From owner-svn-src-all@freebsd.org Tue Oct 31 10:10:14 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 889BBE54271; Tue, 31 Oct 2017 10:10:14 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 63FC86CB65; Tue, 31 Oct 2017 10:10:14 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v9VAADxJ097939; Tue, 31 Oct 2017 10:10:13 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v9VAADcw097938; Tue, 31 Oct 2017 10:10:13 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201710311010.v9VAADcw097938@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Tue, 31 Oct 2017 10:10:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r325227 - head/sys/geom X-SVN-Group: head X-SVN-Commit-Author: avg X-SVN-Commit-Paths: head/sys/geom X-SVN-Commit-Revision: 325227 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Oct 2017 10:10:14 -0000 Author: avg Date: Tue Oct 31 10:10:13 2017 New Revision: 325227 URL: https://svnweb.freebsd.org/changeset/base/325227 Log: geom_slice: do not destroy softc until providers are gone At present, g_slice_orphan and g_slice_spoiled destroy the softc (struct g_slicer) even before calling g_wither_geom, so there can be active and incoming io requests at that time and g_slice_start can access the softc. This commit changes the code to destroy the softc only after all providers are closed. While there, a couple of small cleanups. Reported by: Ben RUBSON Tested by: Ben RUBSON Reviewed by: mav, smh (earlier version) MFC after: 2 weeks Sponsored by: Panzura Differential Revision: https://reviews.freebsd.org/D12809 Modified: head/sys/geom/geom_slice.c Modified: head/sys/geom/geom_slice.c ============================================================================== --- head/sys/geom/geom_slice.c Tue Oct 31 09:58:51 2017 (r325226) +++ head/sys/geom/geom_slice.c Tue Oct 31 10:10:13 2017 (r325227) @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -127,6 +126,15 @@ g_slice_access(struct g_provider *pp, int dr, int dw, if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1) de--; error = g_access(cp, dr, dw, de); + + /* + * Free the softc if all providers have been closed and this geom + * is being removed. + */ + if (error == 0 && (gp->flags & G_GEOM_WITHER) != 0 && + (cp->acr + cp->acw + cp->ace) == 0) + g_slice_free(gsp); + return (error); } @@ -470,21 +478,32 @@ g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t o } void -g_slice_spoiled(struct g_consumer *cp) +g_slice_orphan(struct g_consumer *cp) { struct g_geom *gp; - struct g_slicer *gsp; g_topology_assert(); gp = cp->geom; - g_trace(G_T_TOPOLOGY, "g_slice_spoiled(%p/%s)", cp, gp->name); - cp->flags |= G_CF_ORPHAN; - gsp = gp->softc; - gp->softc = NULL; - g_slice_free(gsp); + g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, gp->name); g_wither_geom(gp, ENXIO); + + /* + * We can safely free the softc now if there are no accesses, + * otherwise g_slice_access() will do that after the last close. + */ + if ((cp->acr + cp->acw + cp->ace) == 0) + g_slice_free(gp->softc); } +void +g_slice_spoiled(struct g_consumer *cp) +{ + + g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->geom->name); + cp->flags |= G_CF_ORPHAN; + g_slice_orphan(cp); +} + int g_slice_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) { @@ -507,10 +526,10 @@ g_slice_new(struct g_class *mp, u_int slices, struct g gp = g_new_geomf(mp, "%s", pp->name); gsp = g_slice_alloc(slices, extra); gsp->start = start; - gp->access = g_slice_access; - gp->orphan = g_slice_orphan; gp->softc = gsp; gp->start = g_slice_start; + gp->access = g_slice_access; + gp->orphan = g_slice_orphan; gp->spoiled = g_slice_spoiled; if (gp->dumpconf == NULL) gp->dumpconf = g_slice_dumpconf; @@ -529,19 +548,4 @@ g_slice_new(struct g_class *mp, u_int slices, struct g *vp = gsp->softc; *cpp = cp; return (gp); -} - -void -g_slice_orphan(struct g_consumer *cp) -{ - struct g_slicer *gsp; - - g_trace(G_T_TOPOLOGY, "g_slice_orphan(%p/%s)", cp, cp->provider->name); - g_topology_assert(); - - /* XXX: Not good enough we leak the softc and its suballocations */ - gsp = cp->geom->softc; - cp->geom->softc = NULL; - g_slice_free(gsp); - g_wither_geom(cp->geom, ENXIO); }