svn commit: r356582 - stable/12/sys/geom/shsec
Alexander Motin
mav at FreeBSD.org
Fri Jan 10 00:45:28 UTC 2020
Author: mav
Date: Fri Jan 10 00:45:27 2020
New Revision: 356582
URL: https://svnweb.freebsd.org/changeset/base/356582
Log:
MFC r356162, r356182: Fix GEOM_SHSEC orphanization.
Previous code closed and destroyed consumer even with I/O in progress.
This patch postpones the destruction till the last close, identical to
GEOM_STRIPE, since they seem to have common origin.
Modified:
stable/12/sys/geom/shsec/g_shsec.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/geom/shsec/g_shsec.c
==============================================================================
--- stable/12/sys/geom/shsec/g_shsec.c Fri Jan 10 00:44:07 2020 (r356581)
+++ stable/12/sys/geom/shsec/g_shsec.c Fri Jan 10 00:45:27 2020 (r356582)
@@ -164,7 +164,7 @@ g_shsec_remove_disk(struct g_consumer *cp)
}
if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0)
- g_access(cp, -cp->acr, -cp->acw, -cp->ace);
+ return;
g_detach(cp);
g_destroy_consumer(cp);
}
@@ -183,14 +183,14 @@ g_shsec_orphan(struct g_consumer *cp)
g_shsec_remove_disk(cp);
/* If there are no valid disks anymore, remove device. */
- if (g_shsec_nvalid(sc) == 0)
+ if (LIST_EMPTY(&gp->consumer))
g_shsec_destroy(sc, 1);
}
static int
g_shsec_access(struct g_provider *pp, int dr, int dw, int de)
{
- struct g_consumer *cp1, *cp2;
+ struct g_consumer *cp1, *cp2, *tmp;
struct g_shsec_softc *sc;
struct g_geom *gp;
int error;
@@ -198,21 +198,6 @@ g_shsec_access(struct g_provider *pp, int dr, int dw,
gp = pp->geom;
sc = gp->softc;
- if (sc == NULL) {
- /*
- * It looks like geom is being withered.
- * In that case we allow only negative requests.
- */
- KASSERT(dr <= 0 && dw <= 0 && de <= 0,
- ("Positive access request (device=%s).", pp->name));
- if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 &&
- (pp->ace + de) == 0) {
- G_SHSEC_DEBUG(0, "Device %s definitely destroyed.",
- gp->name);
- }
- return (0);
- }
-
/* On first open, grab an extra "exclusive" bit */
if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0)
de++;
@@ -221,21 +206,30 @@ g_shsec_access(struct g_provider *pp, int dr, int dw,
de--;
error = ENXIO;
- LIST_FOREACH(cp1, &gp->consumer, consumer) {
+ LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) {
error = g_access(cp1, dr, dw, de);
- if (error == 0)
- continue;
- /*
- * If we fail here, backout all previous changes.
- */
- LIST_FOREACH(cp2, &gp->consumer, consumer) {
- if (cp1 == cp2)
- return (error);
- g_access(cp2, -dr, -dw, -de);
+ if (error != 0)
+ goto fail;
+ if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 &&
+ cp1->flags & G_CF_ORPHAN) {
+ g_detach(cp1);
+ g_destroy_consumer(cp1);
}
- /* NOTREACHED */
}
+ /* If there are no valid disks anymore, remove device. */
+ if (LIST_EMPTY(&gp->consumer))
+ g_shsec_destroy(sc, 1);
+
+ return (error);
+
+fail:
+ /* If we fail here, backout all previous changes. */
+ LIST_FOREACH(cp2, &gp->consumer, consumer) {
+ if (cp1 == cp2)
+ break;
+ g_access(cp2, -dr, -dw, -de);
+ }
return (error);
}
More information about the svn-src-stable-12
mailing list