summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-01-15 01:13:55 +0000
committermav <mav@FreeBSD.org>2013-01-15 01:13:55 +0000
commit19b676e81d252cce89e1cf1fc15a58a1d314f0e1 (patch)
tree8949de2ef31e64eb3e0a6b39fd52559ffc11d153
parent90ae50fac70708906822631642535e26afa47f11 (diff)
downloadFreeBSD-src-19b676e81d252cce89e1cf1fc15a58a1d314f0e1.zip
FreeBSD-src-19b676e81d252cce89e1cf1fc15a58a1d314f0e1.tar.gz
Alike to r242314 for GRAID make GMIRROR 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. PR: kern/113957 MFC after: 2 weeks
-rw-r--r--sys/geom/mirror/g_mirror.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index 17271dd..d77dee9 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -81,7 +81,8 @@ SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, sync_requests, CTLFLAG_RDTUN,
G_MIRROR_DEBUG(4, "%s: Woken up %p.", __func__, (ident)); \
} while (0)
-static eventhandler_tag g_mirror_pre_sync = NULL;
+static eventhandler_tag g_mirror_post_sync = NULL;
+static int g_mirror_shutdown = 0;
static int g_mirror_destroy_geom(struct gctl_req *req, struct g_class *mp,
struct g_geom *gp);
@@ -815,7 +816,7 @@ g_mirror_idle(struct g_mirror_softc *sc, int acw)
return (0);
if (acw > 0 || (acw == -1 && sc->sc_provider->acw > 0)) {
timeout = g_mirror_idletime - (time_uptime - sc->sc_last_write);
- if (timeout > 0)
+ if (!g_mirror_shutdown && timeout > 0)
return (timeout);
}
sc->sc_idle = 1;
@@ -2821,7 +2822,7 @@ g_mirror_access(struct g_provider *pp, int acr, int acw, int ace)
error = ENXIO;
goto end;
}
- if (dcw == 0 && !sc->sc_idle)
+ 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) {
@@ -3232,7 +3233,7 @@ g_mirror_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
}
static void
-g_mirror_shutdown_pre_sync(void *arg, int howto)
+g_mirror_shutdown_post_sync(void *arg, int howto)
{
struct g_class *mp;
struct g_geom *gp, *gp2;
@@ -3242,6 +3243,7 @@ g_mirror_shutdown_pre_sync(void *arg, int howto)
mp = arg;
DROP_GIANT();
g_topology_lock();
+ g_mirror_shutdown = 1;
LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
if ((sc = gp->softc) == NULL)
continue;
@@ -3250,6 +3252,7 @@ g_mirror_shutdown_pre_sync(void *arg, int howto)
continue;
g_topology_unlock();
sx_xlock(&sc->sc_lock);
+ g_mirror_idle(sc, -1);
g_cancel_event(sc);
error = g_mirror_destroy(sc, G_MIRROR_DESTROY_DELAYED);
if (error != 0)
@@ -3264,9 +3267,9 @@ static void
g_mirror_init(struct g_class *mp)
{
- g_mirror_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync,
- g_mirror_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST);
- if (g_mirror_pre_sync == NULL)
+ g_mirror_post_sync = EVENTHANDLER_REGISTER(shutdown_post_sync,
+ g_mirror_shutdown_post_sync, mp, SHUTDOWN_PRI_FIRST);
+ if (g_mirror_post_sync == NULL)
G_MIRROR_DEBUG(0, "Warning! Cannot register shutdown event.");
}
@@ -3274,8 +3277,8 @@ static void
g_mirror_fini(struct g_class *mp)
{
- if (g_mirror_pre_sync != NULL)
- EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_mirror_pre_sync);
+ if (g_mirror_post_sync != NULL)
+ EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_mirror_post_sync);
}
DECLARE_GEOM_CLASS(g_mirror_class, g_mirror);
OpenPOWER on IntegriCloud