Date: Fri, 10 Jan 2020 00:45:28 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r356582 - stable/12/sys/geom/shsec Message-ID: <202001100045.00A0jS3g017025@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001100045.00A0jS3g017025>