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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to