Date: Thu, 20 Oct 2016 08:48:59 +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-11@freebsd.org Subject: svn commit: r307665 - stable/11/sys/geom/mirror Message-ID: <201610200848.u9K8mxbx008081@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Thu Oct 20 08:48:58 2016 New Revision: 307665 URL: https://svnweb.freebsd.org/changeset/base/307665 Log: MFC r306762: Fix possible geom destruction before final provider close. Introduce internal counter to track opens. Using provider's counters is not very successfull after calling g_wither_provider(). Modified: stable/11/sys/geom/mirror/g_mirror.c stable/11/sys/geom/mirror/g_mirror.h stable/11/sys/geom/mirror/g_mirror_ctl.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/geom/mirror/g_mirror.c ============================================================================== --- stable/11/sys/geom/mirror/g_mirror.c Thu Oct 20 02:03:19 2016 (r307664) +++ stable/11/sys/geom/mirror/g_mirror.c Thu Oct 20 08:48:58 2016 (r307665) @@ -2137,10 +2137,9 @@ g_mirror_destroy_provider(struct g_mirro } } mtx_unlock(&sc->sc_queue_mtx); - G_MIRROR_DEBUG(0, "Device %s: provider %s destroyed.", sc->sc_name, - sc->sc_provider->name); g_wither_provider(sc->sc_provider, ENXIO); sc->sc_provider = NULL; + G_MIRROR_DEBUG(0, "Device %s: provider destroyed.", sc->sc_name); g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) @@ -2866,7 +2865,7 @@ static int g_mirror_access(struct g_provider *pp, int acr, int acw, int ace) { struct g_mirror_softc *sc; - int dcr, dcw, dce, error = 0; + int error = 0; g_topology_assert(); G_MIRROR_DEBUG(2, "Access request for %s: r%dw%de%d.", pp->name, acr, @@ -2877,30 +2876,21 @@ g_mirror_access(struct g_provider *pp, i return (0); KASSERT(sc != NULL, ("NULL softc (provider=%s).", pp->name)); - dcr = pp->acr + acr; - dcw = pp->acw + acw; - dce = pp->ace + ace; - g_topology_unlock(); sx_xlock(&sc->sc_lock); if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0 || + (sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROYING) != 0 || LIST_EMPTY(&sc->sc_disks)) { if (acr > 0 || acw > 0 || ace > 0) error = ENXIO; goto end; } - if (dcw == 0) - g_mirror_idle(sc, dcw); - if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROYING) != 0) { - if (acr > 0 || acw > 0 || ace > 0) { - error = ENXIO; - goto end; - } - if (dcr == 0 && dcw == 0 && dce == 0) { - g_post_event(g_mirror_destroy_delayed, sc, M_WAITOK, - sc, NULL); - } - } + sc->sc_provider_open += acr + acw + ace; + if (pp->acw + acw == 0) + g_mirror_idle(sc, 0); + if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROYING) != 0 && + sc->sc_provider_open == 0) + g_post_event(g_mirror_destroy_delayed, sc, M_WAITOK, sc, NULL); end: sx_xunlock(&sc->sc_lock); g_topology_lock(); @@ -2957,6 +2947,7 @@ g_mirror_create(struct g_class *mp, cons gp->softc = sc; sc->sc_geom = gp; sc->sc_provider = NULL; + sc->sc_provider_open = 0; /* * Synchronization geom. */ @@ -2997,26 +2988,23 @@ int g_mirror_destroy(struct g_mirror_softc *sc, int how) { struct g_mirror_disk *disk; - struct g_provider *pp; g_topology_assert_not(); if (sc == NULL) return (ENXIO); sx_assert(&sc->sc_lock, SX_XLOCKED); - pp = sc->sc_provider; - if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0 || - SCHEDULER_STOPPED())) { + if (sc->sc_provider_open != 0 || SCHEDULER_STOPPED()) { switch (how) { case G_MIRROR_DESTROY_SOFT: G_MIRROR_DEBUG(1, - "Device %s is still open (r%dw%de%d).", pp->name, - pp->acr, pp->acw, pp->ace); + "Device %s is still open (%d).", sc->sc_name, + sc->sc_provider_open); return (EBUSY); case G_MIRROR_DESTROY_DELAYED: G_MIRROR_DEBUG(1, "Device %s will be destroyed on last close.", - pp->name); + sc->sc_name); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) { @@ -3027,7 +3015,7 @@ g_mirror_destroy(struct g_mirror_softc * return (EBUSY); case G_MIRROR_DESTROY_HARD: G_MIRROR_DEBUG(1, "Device %s is still open, so it " - "can't be definitely removed.", pp->name); + "can't be definitely removed.", sc->sc_name); } } Modified: stable/11/sys/geom/mirror/g_mirror.h ============================================================================== --- stable/11/sys/geom/mirror/g_mirror.h Thu Oct 20 02:03:19 2016 (r307664) +++ stable/11/sys/geom/mirror/g_mirror.h Thu Oct 20 08:48:58 2016 (r307665) @@ -179,6 +179,7 @@ struct g_mirror_softc { struct g_geom *sc_geom; struct g_provider *sc_provider; + int sc_provider_open; uint32_t sc_id; /* Mirror unique ID. */ Modified: stable/11/sys/geom/mirror/g_mirror_ctl.c ============================================================================== --- stable/11/sys/geom/mirror/g_mirror_ctl.c Thu Oct 20 02:03:19 2016 (r307664) +++ stable/11/sys/geom/mirror/g_mirror_ctl.c Thu Oct 20 08:48:58 2016 (r307665) @@ -658,8 +658,7 @@ g_mirror_ctl_resize(struct gctl_req *req return; } /* Deny shrinking of an opened provider */ - if ((g_debugflags & 16) == 0 && (sc->sc_provider->acr > 0 || - sc->sc_provider->acw > 0 || sc->sc_provider->ace > 0)) { + if ((g_debugflags & 16) == 0 && sc->sc_provider_open > 0) { if (sc->sc_mediasize > mediasize) { gctl_error(req, "Device %s is busy.", sc->sc_provider->name);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610200848.u9K8mxbx008081>