summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/geom/raid/g_raid.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c
index d03c2e8..e720c07 100644
--- a/sys/geom/raid/g_raid.c
+++ b/sys/geom/raid/g_raid.c
@@ -108,8 +108,9 @@ LIST_HEAD(, g_raid_tr_class) g_raid_tr_classes =
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, int acw)
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 acr, int acw, int ace)
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 char *indent, struct g_geom *gp,
}
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;
}
OpenPOWER on IntegriCloud