Date: Sat, 28 Dec 2019 23:21:54 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356162 - head/sys/geom/shsec Message-ID: <201912282321.xBSNLs7q015568@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Sat Dec 28 23:21:53 2019 New Revision: 356162 URL: https://svnweb.freebsd.org/changeset/base/356162 Log: 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. MFC after: 2 weeks Sponsored by: iXsystems, Inc. Modified: head/sys/geom/shsec/g_shsec.c Modified: head/sys/geom/shsec/g_shsec.c ============================================================================== --- head/sys/geom/shsec/g_shsec.c Sat Dec 28 22:32:14 2019 (r356161) +++ head/sys/geom/shsec/g_shsec.c Sat Dec 28 23:21:53 2019 (r356162) @@ -165,7 +165,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); } @@ -191,7 +191,7 @@ g_shsec_orphan(struct g_consumer *cp) 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; @@ -222,21 +222,25 @@ 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 */ } + 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?201912282321.xBSNLs7q015568>