Author: mav
Date: Tue Jan 15 01:27:04 2013
New Revision: 245444
URL: http://svnweb.freebsd.org/changeset/base/245444

Log:
  Alike to r242314 for GRAID make GRAID3 more aggressive in marking volumes
  as clean on shutdown and move that action from shutdown_pre_sync stage to
  shutdown_post_sync 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.
  
  MFC after:    2 weeks

Modified:
  head/sys/geom/raid3/g_raid3.c

Modified: head/sys/geom/raid3/g_raid3.c
==============================================================================
--- head/sys/geom/raid3/g_raid3.c       Tue Jan 15 01:13:55 2013        
(r245443)
+++ head/sys/geom/raid3/g_raid3.c       Tue Jan 15 01:27:04 2013        
(r245444)
@@ -104,7 +104,8 @@ SYSCTL_UINT(_kern_geom_raid3_stat, OID_A
        G_RAID3_DEBUG(4, "%s: Woken up %p.", __func__, (ident));        \
 } while (0)
 
-static eventhandler_tag g_raid3_pre_sync = NULL;
+static eventhandler_tag g_raid3_post_sync = NULL;
+static int g_raid3_shutdown = 0;
 
 static int g_raid3_destroy_geom(struct gctl_req *req, struct g_class *mp,
     struct g_geom *gp);
@@ -876,7 +877,7 @@ g_raid3_idle(struct g_raid3_softc *sc, i
                return (0);
        if (acw > 0 || (acw == -1 && sc->sc_provider->acw > 0)) {
                timeout = g_raid3_idletime - (time_uptime - sc->sc_last_write);
-               if (timeout > 0)
+               if (!g_raid3_shutdown && timeout > 0)
                        return (timeout);
        }
        sc->sc_idle = 1;
@@ -3098,7 +3099,7 @@ g_raid3_access(struct g_provider *pp, in
                        error = ENXIO;
                goto end;
        }
-       if (dcw == 0 && !sc->sc_idle)
+       if (dcw == 0)
                g_raid3_idle(sc, dcw);
        if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_DESTROYING) != 0) {
                if (acr > 0 || acw > 0 || ace > 0) {
@@ -3544,7 +3545,7 @@ g_raid3_dumpconf(struct sbuf *sb, const 
 }
 
 static void
-g_raid3_shutdown_pre_sync(void *arg, int howto)
+g_raid3_shutdown_post_sync(void *arg, int howto)
 {
        struct g_class *mp;
        struct g_geom *gp, *gp2;
@@ -3554,6 +3555,7 @@ g_raid3_shutdown_pre_sync(void *arg, int
        mp = arg;
        DROP_GIANT();
        g_topology_lock();
+       g_raid3_shutdown = 1;
        LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
                if ((sc = gp->softc) == NULL)
                        continue;
@@ -3562,6 +3564,7 @@ g_raid3_shutdown_pre_sync(void *arg, int
                        continue;
                g_topology_unlock();
                sx_xlock(&sc->sc_lock);
+               g_raid3_idle(sc, -1);
                g_cancel_event(sc);
                error = g_raid3_destroy(sc, G_RAID3_DESTROY_DELAYED);
                if (error != 0)
@@ -3576,9 +3579,9 @@ static void
 g_raid3_init(struct g_class *mp)
 {
 
-       g_raid3_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync,
-           g_raid3_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST);
-       if (g_raid3_pre_sync == NULL)
+       g_raid3_post_sync = EVENTHANDLER_REGISTER(shutdown_post_sync,
+           g_raid3_shutdown_post_sync, mp, SHUTDOWN_PRI_FIRST);
+       if (g_raid3_post_sync == NULL)
                G_RAID3_DEBUG(0, "Warning! Cannot register shutdown event.");
 }
 
@@ -3586,8 +3589,8 @@ static void
 g_raid3_fini(struct g_class *mp)
 {
 
-       if (g_raid3_pre_sync != NULL)
-               EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_raid3_pre_sync);
+       if (g_raid3_post_sync != NULL)
+               EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_raid3_post_sync);
 }
 
 DECLARE_GEOM_CLASS(g_raid3_class, g_raid3);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to