From owner-svn-src-stable@FreeBSD.ORG Thu Apr 18 10:49:53 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 520A88ED; Thu, 18 Apr 2013 10:49:53 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 44338F38; Thu, 18 Apr 2013 10:49:53 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3IAnrTj014295; Thu, 18 Apr 2013 10:49:53 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3IAnqxg014292; Thu, 18 Apr 2013 10:49:52 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201304181049.r3IAnqxg014292@svn.freebsd.org> From: Alexander Motin Date: Thu, 18 Apr 2013 10:49:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r249619 - stable/9/sys/geom X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Apr 2013 10:49:53 -0000 Author: mav Date: Thu Apr 18 10:49:52 2013 New Revision: 249619 URL: http://svnweb.freebsd.org/changeset/base/249619 Log: MFC r248674: Make g_wither_washer() to not loop by itself, but only when there was some more topology change done that may require its attention. Add few missing g_do_wither() calls in respective places to signal it. This fixes potential infinite loop here when some provider is withered, but still opened or connected for some reason and so can not be destroyed. For example, see r227009 and r227510. Modified: stable/9/sys/geom/geom_event.c stable/9/sys/geom/geom_int.h stable/9/sys/geom/geom_subr.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/geom/geom_event.c ============================================================================== --- stable/9/sys/geom/geom_event.c Thu Apr 18 10:42:48 2013 (r249618) +++ stable/9/sys/geom/geom_event.c Thu Apr 18 10:49:52 2013 (r249619) @@ -273,21 +273,16 @@ one_event(void) void g_run_events() { - int i; for (;;) { g_topology_lock(); while (one_event()) ; mtx_assert(&g_eventlock, MA_OWNED); - i = g_wither_work; - if (i) { + if (g_wither_work) { + g_wither_work = 0; mtx_unlock(&g_eventlock); - while (i) { - i = g_wither_washer(); - g_wither_work = i & 1; - i &= 2; - } + g_wither_washer(); g_topology_unlock(); } else { g_topology_unlock(); Modified: stable/9/sys/geom/geom_int.h ============================================================================== --- stable/9/sys/geom/geom_int.h Thu Apr 18 10:42:48 2013 (r249618) +++ stable/9/sys/geom/geom_int.h Thu Apr 18 10:49:52 2013 (r249619) @@ -65,7 +65,7 @@ void g_do_wither(void); /* geom_subr.c */ extern struct class_list_head g_classes; extern char *g_wait_event, *g_wait_sim, *g_wait_up, *g_wait_down; -int g_wither_washer(void); +void g_wither_washer(void); /* geom_io.c */ void g_io_init(void); Modified: stable/9/sys/geom/geom_subr.c ============================================================================== --- stable/9/sys/geom/geom_subr.c Thu Apr 18 10:42:48 2013 (r249618) +++ stable/9/sys/geom/geom_subr.c Thu Apr 18 10:49:52 2013 (r249619) @@ -434,20 +434,16 @@ g_wither_geom_close(struct g_geom *gp, i /* * This function is called (repeatedly) until we cant wash away more - * withered bits at present. Return value contains two bits. Bit 0 - * set means "withering stuff we can't wash now", bit 1 means "call - * me again, there may be stuff I didn't get the first time around. + * withered bits at present. */ -int +void g_wither_washer() { struct g_class *mp; struct g_geom *gp, *gp2; struct g_provider *pp, *pp2; struct g_consumer *cp, *cp2; - int result; - result = 0; g_topology_assert(); LIST_FOREACH(mp, &g_classes, class) { LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { @@ -456,35 +452,25 @@ g_wither_washer() continue; if (LIST_EMPTY(&pp->consumers)) g_destroy_provider(pp); - else - result |= 1; } if (!(gp->flags & G_GEOM_WITHER)) continue; LIST_FOREACH_SAFE(pp, &gp->provider, provider, pp2) { if (LIST_EMPTY(&pp->consumers)) g_destroy_provider(pp); - else - result |= 1; } LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp2) { - if (cp->acr || cp->acw || cp->ace) { - result |= 1; + if (cp->acr || cp->acw || cp->ace) continue; - } if (cp->provider != NULL) g_detach(cp); g_destroy_consumer(cp); - result |= 2; } if (LIST_EMPTY(&gp->provider) && LIST_EMPTY(&gp->consumer)) g_destroy_geom(gp); - else - result |= 1; } } - return (result); } struct g_consumer * @@ -772,9 +758,9 @@ g_detach(struct g_consumer *cp) pp = cp->provider; LIST_REMOVE(cp, consumers); cp->provider = NULL; - if (pp->geom->flags & G_GEOM_WITHER) - g_do_wither(); - else if (pp->flags & G_PF_WITHER) + if ((cp->geom->flags & G_GEOM_WITHER) || + (pp->geom->flags & G_GEOM_WITHER) || + (pp->flags & G_PF_WITHER)) g_do_wither(); redo_rank(cp->geom); } @@ -873,6 +859,9 @@ g_access(struct g_consumer *cp, int dcr, if (pp->acr != 0 || pp->acw != 0 || pp->ace != 0) KASSERT(pp->sectorsize > 0, ("Provider %s lacks sectorsize", pp->name)); + if ((cp->geom->flags & G_GEOM_WITHER) && + cp->acr == 0 && cp->acw == 0 && cp->ace == 0) + g_do_wither(); } return (error); }