Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Nov 2012 05:33:14 +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-9@freebsd.org
Subject:   svn commit: r243056 - stable/9/sys/geom/raid
Message-ID:  <201211150533.qAF5XEFS026164@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Nov 15 05:33:14 2012
New Revision: 243056
URL: http://svnweb.freebsd.org/changeset/base/243056

Log:
  MFC r242314:
  Make GEOM RAID more aggressive in marking volumes as clean on shutdown
  and move that action from shutdown_pre_sync to shutdown_post_sync stage
  to avoid extra flapping.
  
  ZFS tends to not close devices on shutdown, that doesn't allow GEOM RAID
  to shutdown gracefully.  To handle that, mark volume as clean just when
  shutdown time comes and there are no active writes.

Modified:
  stable/9/sys/geom/raid/g_raid.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/geom/raid/g_raid.c
==============================================================================
--- stable/9/sys/geom/raid/g_raid.c	Thu Nov 15 04:51:37 2012	(r243055)
+++ stable/9/sys/geom/raid/g_raid.c	Thu Nov 15 05:33:14 2012	(r243056)
@@ -108,8 +108,9 @@ LIST_HEAD(, g_raid_tr_class) g_raid_tr_c
 LIST_HEAD(, g_raid_volume) g_raid_volumes =
     LIST_HEAD_INITIALIZER(g_raid_volumes);
 
-static eventhandler_tag g_raid_pre_sync = NULL;
+static eventhandler_tag g_raid_post_sync = NULL;
 static int g_raid_started = 0;
+static int g_raid_shutdown = 0;
 
 static int g_raid_destroy_geom(struct gctl_req *req, struct g_class *mp,
     struct g_geom *gp);
@@ -881,7 +882,7 @@ g_raid_orphan(struct g_consumer *cp)
 	    G_RAID_EVENT_DISK);
 }
 
-static int
+static void
 g_raid_clean(struct g_raid_volume *vol, int acw)
 {
 	struct g_raid_softc *sc;
@@ -892,22 +893,21 @@ g_raid_clean(struct g_raid_volume *vol, 
 	sx_assert(&sc->sc_lock, SX_XLOCKED);
 
 //	if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOFAILSYNC) != 0)
-//		return (0);
+//		return;
 	if (!vol->v_dirty)
-		return (0);
+		return;
 	if (vol->v_writes > 0)
-		return (0);
+		return;
 	if (acw > 0 || (acw == -1 &&
 	    vol->v_provider != NULL && vol->v_provider->acw > 0)) {
 		timeout = g_raid_clean_time - (time_uptime - vol->v_last_write);
-		if (timeout > 0)
-			return (timeout);
+		if (!g_raid_shutdown && timeout > 0)
+			return;
 	}
 	vol->v_dirty = 0;
 	G_RAID_DEBUG1(1, sc, "Volume %s marked as clean.",
 	    vol->v_name);
 	g_raid_write_metadata(sc, vol, NULL, NULL);
-	return (0);
 }
 
 static void
@@ -1520,8 +1520,7 @@ process:
 				g_raid_disk_done_request(bp);
 		} else if (rv == EWOULDBLOCK) {
 			TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
-				if (vol->v_writes == 0 && vol->v_dirty)
-					g_raid_clean(vol, -1);
+				g_raid_clean(vol, -1);
 				if (bioq_first(&vol->v_inflight) == NULL &&
 				    vol->v_tr) {
 					t.tv_sec = g_raid_idle_threshold / 1000000;
@@ -1783,7 +1782,7 @@ g_raid_access(struct g_provider *pp, int
 		error = ENXIO;
 		goto out;
 	}
-	if (dcw == 0 && vol->v_dirty)
+	if (dcw == 0)
 		g_raid_clean(vol, dcw);
 	vol->v_provider_open += acr + acw + ace;
 	/* Handle delayed node destruction. */
@@ -2379,21 +2378,25 @@ g_raid_dumpconf(struct sbuf *sb, const c
 }
 
 static void
-g_raid_shutdown_pre_sync(void *arg, int howto)
+g_raid_shutdown_post_sync(void *arg, int howto)
 {
 	struct g_class *mp;
 	struct g_geom *gp, *gp2;
 	struct g_raid_softc *sc;
+	struct g_raid_volume *vol;
 	int error;
 
 	mp = arg;
 	DROP_GIANT();
 	g_topology_lock();
+	g_raid_shutdown = 1;
 	LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
 		if ((sc = gp->softc) == NULL)
 			continue;
 		g_topology_unlock();
 		sx_xlock(&sc->sc_lock);
+		TAILQ_FOREACH(vol, &sc->sc_volumes, v_next)
+			g_raid_clean(vol, -1);
 		g_cancel_event(sc);
 		error = g_raid_destroy(sc, G_RAID_DESTROY_DELAYED);
 		if (error != 0)
@@ -2408,9 +2411,9 @@ static void
 g_raid_init(struct g_class *mp)
 {
 
-	g_raid_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync,
-	    g_raid_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST);
-	if (g_raid_pre_sync == NULL)
+	g_raid_post_sync = EVENTHANDLER_REGISTER(shutdown_post_sync,
+	    g_raid_shutdown_post_sync, mp, SHUTDOWN_PRI_FIRST);
+	if (g_raid_post_sync == NULL)
 		G_RAID_DEBUG(0, "Warning! Cannot register shutdown event.");
 	g_raid_started = 1;
 }
@@ -2419,8 +2422,8 @@ static void
 g_raid_fini(struct g_class *mp)
 {
 
-	if (g_raid_pre_sync != NULL)
-		EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_raid_pre_sync);
+	if (g_raid_post_sync != NULL)
+		EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_raid_post_sync);
 	g_raid_started = 0;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211150533.qAF5XEFS026164>