Date: Mon, 2 Sep 2013 10:44: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: r255144 - head/sys/geom/eli Message-ID: <201309021044.r82AisqQ070834@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Mon Sep 2 10:44:54 2013 New Revision: 255144 URL: http://svnweb.freebsd.org/changeset/base/255144 Log: Make ELI destruction (including orphanization) less aggressive, making it always wait for provider close. Old algorithm was reported to cause NULL dereference panic on attempt to close provider after softc destruction. If not global workaroung in GEOM, that could even cause destruction with requests still in flight. Modified: head/sys/geom/eli/g_eli.c Modified: head/sys/geom/eli/g_eli.c ============================================================================== --- head/sys/geom/eli/g_eli.c Mon Sep 2 10:14:25 2013 (r255143) +++ head/sys/geom/eli/g_eli.c Mon Sep 2 10:44:54 2013 (r255144) @@ -621,21 +621,19 @@ end: * to close it when this situation occur. */ static void -g_eli_last_close(struct g_eli_softc *sc) +g_eli_last_close(void *arg, int flags __unused) { struct g_geom *gp; - struct g_provider *pp; - char ppname[64]; + char gpname[64]; int error; g_topology_assert(); - gp = sc->sc_geom; - pp = LIST_FIRST(&gp->provider); - strlcpy(ppname, pp->name, sizeof(ppname)); - error = g_eli_destroy(sc, TRUE); + gp = arg; + strlcpy(gpname, gp->name, sizeof(gpname)); + error = g_eli_destroy(gp->softc, TRUE); KASSERT(error == 0, ("Cannot detach %s on last close (error=%d).", - ppname, error)); - G_ELI_DEBUG(0, "Detached %s on last close.", ppname); + gpname, error)); + G_ELI_DEBUG(0, "Detached %s on last close.", gpname); } int @@ -665,7 +663,7 @@ g_eli_access(struct g_provider *pp, int */ if ((sc->sc_flags & G_ELI_FLAG_RW_DETACH) || (sc->sc_flags & G_ELI_FLAG_WOPEN)) { - g_eli_last_close(sc); + g_post_event(g_eli_last_close, gp, M_WAITOK, NULL); } return (0); } @@ -916,6 +914,10 @@ g_eli_destroy(struct g_eli_softc *sc, bo if (force) { G_ELI_DEBUG(1, "Device %s is still open, so it " "cannot be definitely removed.", pp->name); + sc->sc_flags |= G_ELI_FLAG_RW_DETACH; + gp->access = g_eli_access; + g_wither_provider(pp, ENXIO); + return (EBUSY); } else { G_ELI_DEBUG(1, "Device %s is still open (r%dw%de%d).", pp->name,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309021044.r82AisqQ070834>