From owner-svn-src-all@freebsd.org Fri Jan 10 00:42:40 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 536E11FDEFF; Fri, 10 Jan 2020 00:42:40 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47v42S0Scfz3wqZ; Fri, 10 Jan 2020 00:42:40 +0000 (UTC) (envelope-from mav@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0B2279CC8; Fri, 10 Jan 2020 00:42:40 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 00A0gdY4016628; Fri, 10 Jan 2020 00:42:39 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 00A0gd7K016627; Fri, 10 Jan 2020 00:42:39 GMT (envelope-from mav@FreeBSD.org) Message-Id: <202001100042.00A0gd7K016627@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 10 Jan 2020 00:42:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r356578 - stable/12/sys/geom/uzip X-SVN-Group: stable-12 X-SVN-Commit-Author: mav X-SVN-Commit-Paths: stable/12/sys/geom/uzip X-SVN-Commit-Revision: 356578 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.29 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: Fri, 10 Jan 2020 00:42:40 -0000 Author: mav Date: Fri Jan 10 00:42:39 2020 New Revision: 356578 URL: https://svnweb.freebsd.org/changeset/base/356578 Log: MFC r356138: Fix GEOM_UZIP orphanization. Previous code destroyed softc even with provider still open, that resulted in panic under load. This change postpones the free till the final close, when we know for sure there will be no more I/O requests. Modified: stable/12/sys/geom/uzip/g_uzip.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/geom/uzip/g_uzip.c ============================================================================== --- stable/12/sys/geom/uzip/g_uzip.c Fri Jan 10 00:42:05 2020 (r356577) +++ stable/12/sys/geom/uzip/g_uzip.c Fri Jan 10 00:42:39 2020 (r356578) @@ -139,13 +139,12 @@ static void g_uzip_read_done(struct bio *bp); static void g_uzip_do(struct g_uzip_softc *, struct bio *bp); static void -g_uzip_softc_free(struct g_uzip_softc *sc, struct g_geom *gp) +g_uzip_softc_free(struct g_geom *gp) { + struct g_uzip_softc *sc = gp->softc; - if (gp != NULL) { - DPRINTF(GUZ_DBG_INFO, ("%s: %d requests, %d cached\n", - gp->name, sc->req_total, sc->req_cached)); - } + DPRINTF(GUZ_DBG_INFO, ("%s: %d requests, %d cached\n", + gp->name, sc->req_total, sc->req_cached)); mtx_lock(&sc->queue_mtx); sc->wrkthr_flags |= GUZ_SHUTDOWN; @@ -162,6 +161,7 @@ g_uzip_softc_free(struct g_uzip_softc *sc, struct g_ge mtx_destroy(&sc->last_mtx); free(sc->last_buf, M_GEOM_UZIP); free(sc, M_GEOM_UZIP); + gp->softc = NULL; } static int @@ -503,20 +503,35 @@ g_uzip_orphan(struct g_consumer *cp) { struct g_geom *gp; - g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->provider->name); g_topology_assert(); - + G_VALID_CONSUMER(cp); gp = cp->geom; - g_uzip_softc_free(gp->softc, gp); - gp->softc = NULL; + 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_uzip_access() will do that after the last close. + */ + if ((cp->acr + cp->acw + cp->ace) == 0) + g_uzip_softc_free(gp); } +static void +g_uzip_spoiled(struct g_consumer *cp) +{ + + g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->geom->name); + cp->flags |= G_CF_ORPHAN; + g_uzip_orphan(cp); +} + static int g_uzip_access(struct g_provider *pp, int dr, int dw, int de) { struct g_geom *gp; struct g_consumer *cp; + int error; gp = pp->geom; cp = LIST_FIRST(&gp->consumer); @@ -525,22 +540,17 @@ g_uzip_access(struct g_provider *pp, int dr, int dw, i if (cp->acw + dw > 0) return (EROFS); - return (g_access(cp, dr, dw, de)); -} + error = g_access(cp, dr, dw, de); -static void -g_uzip_spoiled(struct g_consumer *cp) -{ - struct g_geom *gp; + /* + * 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_uzip_softc_free(gp); - G_VALID_CONSUMER(cp); - gp = cp->geom; - g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, gp->name); - g_topology_assert(); - - g_uzip_softc_free(gp->softc, gp); - gp->softc = NULL; - g_wither_geom(gp, ENXIO); + return (error); } static int @@ -901,10 +911,8 @@ g_uzip_destroy_geom(struct gctl_req *req, struct g_cla if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0) return (EBUSY); - g_uzip_softc_free(gp->softc, gp); - gp->softc = NULL; g_wither_geom(gp, ENXIO); - + g_uzip_softc_free(gp); return (0); }