aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/raid3/g_raid3.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2013-01-15 01:27:04 +0000
committerAlexander Motin <mav@FreeBSD.org>2013-01-15 01:27:04 +0000
commitf62c1a47d6fbb12ee019fc7c3f0b5b89fb6a0edb (patch)
tree79501d0e9e3a50869c84b12a90df7cc91ca73cfd /sys/geom/raid3/g_raid3.c
parentcbab6161747f0f8a96fdf6ba7569783e6487ecba (diff)
downloadsrc-f62c1a47d6fbb12ee019fc7c3f0b5b89fb6a0edb.tar.gz
src-f62c1a47d6fbb12ee019fc7c3f0b5b89fb6a0edb.zip
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
Notes
Notes: svn path=/head/; revision=245444
Diffstat (limited to 'sys/geom/raid3/g_raid3.c')
-rw-r--r--sys/geom/raid3/g_raid3.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c
index 711e9e14ebca..927cb3173e71 100644
--- a/sys/geom/raid3/g_raid3.c
+++ b/sys/geom/raid3/g_raid3.c
@@ -104,7 +104,8 @@ SYSCTL_UINT(_kern_geom_raid3_stat, OID_AUTO, parity_mismatch, CTLFLAG_RD,
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, int acw)
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, int acr, int acw, int ace)
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 char *indent, struct g_geom *gp,
}
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 howto)
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 howto)
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);