diff options
author | pjd <pjd@FreeBSD.org> | 2004-11-05 13:01:25 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2004-11-05 13:01:25 +0000 |
commit | f229109eb7836119f80fed05e744af671bae2425 (patch) | |
tree | bdef802a4e5e192c3b0cd40156d0308f0d32d46f /sys/geom/raid3 | |
parent | 270f218c1d5f595b2cc0352c301eb1b38fb8cf40 (diff) | |
download | FreeBSD-src-f229109eb7836119f80fed05e744af671bae2425.zip FreeBSD-src-f229109eb7836119f80fed05e744af671bae2425.tar.gz |
Mark raid3 devices as clean on shutdown (after all file systems are
unmounted).
Suggested by: scottl
Diffstat (limited to 'sys/geom/raid3')
-rw-r--r-- | sys/geom/raid3/g_raid3.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index abcb56d..860e3f1 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bio.h> #include <sys/sysctl.h> #include <sys/malloc.h> +#include <sys/eventhandler.h> #include <vm/uma.h> #include <machine/atomic.h> #include <geom/geom.h> @@ -108,17 +109,22 @@ SYSCTL_UINT(_kern_geom_raid3_stat, OID_AUTO, 4k_failed, CTLFLAG_RD, G_RAID3_DEBUG(4, "%s: Woken up %p.", __func__, (ident)); \ } while (0) +static eventhandler_tag g_raid3_ehtag = NULL; static int g_raid3_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp); static g_taste_t g_raid3_taste; +static void g_raid3_init(struct g_class *mp); +static void g_raid3_fini(struct g_class *mp); struct g_class g_raid3_class = { .name = G_RAID3_CLASS_NAME, .version = G_VERSION, .ctlreq = g_raid3_config, .taste = g_raid3_taste, - .destroy_geom = g_raid3_destroy_geom + .destroy_geom = g_raid3_destroy_geom, + .init = g_raid3_init, + .fini = g_raid3_fini }; @@ -512,6 +518,7 @@ static void g_raid3_destroy_device(struct g_raid3_softc *sc) { struct g_raid3_event *ep; + struct g_raid3_disk *disk; struct g_geom *gp; struct g_consumer *cp; u_int n; @@ -521,8 +528,12 @@ g_raid3_destroy_device(struct g_raid3_softc *sc) gp = sc->sc_geom; if (sc->sc_provider != NULL) g_raid3_destroy_provider(sc); - for (n = 0; n < sc->sc_ndisks; n++) - g_raid3_destroy_disk(&sc->sc_disks[n]); + for (n = 0; n < sc->sc_ndisks; n++) { + disk = &sc->sc_disks[n]; + disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; + g_raid3_update_metadata(disk); + g_raid3_destroy_disk(disk); + } while ((ep = g_raid3_event_get(sc)) != NULL) { if ((ep->e_flags & G_RAID3_EVENT_DONTWAIT) != 0) g_raid3_event_free(ep); @@ -2913,4 +2924,42 @@ g_raid3_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, } } +static void +g_raid3_shutdown(void *arg, int howto) +{ + struct g_class *mp; + struct g_geom *gp, *gp2; + + mp = arg; + g_topology_lock(); + LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { + if (gp->softc == NULL) + continue; + g_raid3_destroy(gp->softc, 1); + } + g_topology_unlock(); +#if 0 + tsleep(&gp, PRIBIO, "r3:shutdown", hz * 20); +#endif +} + +static void +g_raid3_init(struct g_class *mp) +{ + + g_raid3_ehtag = EVENTHANDLER_REGISTER(shutdown_post_sync, + g_raid3_shutdown, mp, SHUTDOWN_PRI_FIRST); + if (g_raid3_ehtag == NULL) + G_RAID3_DEBUG(0, "Warning! Cannot register shutdown event."); +} + +static void +g_raid3_fini(struct g_class *mp) +{ + + if (g_raid3_ehtag == NULL) + return; + EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_raid3_ehtag); +} + DECLARE_GEOM_CLASS(g_raid3_class, g_raid3); |