diff options
author | pjd <pjd@FreeBSD.org> | 2006-11-01 22:51:49 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-11-01 22:51:49 +0000 |
commit | b34fb80d8364fbc4f1737da5f2916fe5b39a9325 (patch) | |
tree | 97b3734a2b0b5f3ef52ead534f66a992a2f04c67 /sys/geom/raid3 | |
parent | 3d8e2e0a6f357ed1a3f49941041c5850215bb15d (diff) | |
download | FreeBSD-src-b34fb80d8364fbc4f1737da5f2916fe5b39a9325.zip FreeBSD-src-b34fb80d8364fbc4f1737da5f2916fe5b39a9325.tar.gz |
Now, that we have gjournal in the tree add possibility to configure
gmirror and graid3 in a way that it is not resynchronized after a
power failure or system crash.
It is safe when gjournal is running on top of gmirror/graid3.
Diffstat (limited to 'sys/geom/raid3')
-rw-r--r-- | sys/geom/raid3/g_raid3.c | 10 | ||||
-rw-r--r-- | sys/geom/raid3/g_raid3.h | 14 | ||||
-rw-r--r-- | sys/geom/raid3/g_raid3_ctl.c | 33 |
3 files changed, 49 insertions, 8 deletions
diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index e08e331..776b6bd 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -861,6 +861,8 @@ g_raid3_idle(struct g_raid3_softc *sc, int acw) if (sc->sc_provider == NULL) return (0); + if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) + return (0); if (sc->sc_idle) return (0); if (sc->sc_writes > 0) @@ -892,6 +894,8 @@ g_raid3_unidle(struct g_raid3_softc *sc) g_topology_assert_not(); sx_assert(&sc->sc_lock, SX_XLOCKED); + if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) + return; sc->sc_idle = 0; sc->sc_last_write = time_uptime; for (i = 0; i < sc->sc_ndisks; i++) { @@ -2154,6 +2158,8 @@ g_raid3_update_idle(struct g_raid3_softc *sc, struct g_raid3_disk *disk) { sx_assert(&sc->sc_lock, SX_LOCKED); + if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) + return; if (!sc->sc_idle && (disk->d_flags & G_RAID3_DISK_FLAG_DIRTY) == 0) { G_RAID3_DEBUG(1, "Disk %s (device %s) marked as dirty.", g_raid3_get_diskname(disk), sc->sc_name); @@ -2206,7 +2212,8 @@ g_raid3_sync_start(struct g_raid3_softc *sc) G_RAID3_DEBUG(0, "Device %s: rebuilding provider %s.", sc->sc_name, g_raid3_get_diskname(disk)); - disk->d_flags |= G_RAID3_DISK_FLAG_DIRTY; + if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) == 0) + disk->d_flags |= G_RAID3_DISK_FLAG_DIRTY; KASSERT(disk->d_sync.ds_consumer == NULL, ("Sync consumer already exists (device=%s, disk=%s).", sc->sc_name, g_raid3_get_diskname(disk))); @@ -3481,6 +3488,7 @@ g_raid3_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, sbuf_printf(sb, name); \ } \ } while (0) + ADD_FLAG(G_RAID3_DEVICE_FLAG_NOFAILSYNC, "NOFAILSYNC"); ADD_FLAG(G_RAID3_DEVICE_FLAG_NOAUTOSYNC, "NOAUTOSYNC"); ADD_FLAG(G_RAID3_DEVICE_FLAG_ROUND_ROBIN, "ROUND-ROBIN"); diff --git a/sys/geom/raid3/g_raid3.h b/sys/geom/raid3/g_raid3.h index 1032142..a375999 100644 --- a/sys/geom/raid3/g_raid3.h +++ b/sys/geom/raid3/g_raid3.h @@ -42,8 +42,9 @@ * 2 - Added 'verify reading' algorithm. * 3 - Added md_genid field to metadata. * 4 - Added md_provsize field to metadata. + * 5 - Added 'no failure synchronization' flag. */ -#define G_RAID3_VERSION 4 +#define G_RAID3_VERSION 5 #define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL #define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL @@ -57,9 +58,11 @@ #define G_RAID3_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL #define G_RAID3_DEVICE_FLAG_ROUND_ROBIN 0x0000000000000002ULL #define G_RAID3_DEVICE_FLAG_VERIFY 0x0000000000000004ULL +#define G_RAID3_DEVICE_FLAG_NOFAILSYNC 0x0000000000000008ULL #define G_RAID3_DEVICE_FLAG_MASK (G_RAID3_DEVICE_FLAG_NOAUTOSYNC | \ G_RAID3_DEVICE_FLAG_ROUND_ROBIN | \ - G_RAID3_DEVICE_FLAG_VERIFY) + G_RAID3_DEVICE_FLAG_VERIFY | \ + G_RAID3_DEVICE_FLAG_NOFAILSYNC) #ifdef _KERNEL extern u_int g_raid3_debug; @@ -363,7 +366,7 @@ raid3_metadata_decode_v3(const u_char *data, struct g_raid3_metadata *md) return (0); } static __inline int -raid3_metadata_decode_v4(const u_char *data, struct g_raid3_metadata *md) +raid3_metadata_decode_v4v5(const u_char *data, struct g_raid3_metadata *md) { MD5_CTX ctx; @@ -405,7 +408,8 @@ raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) error = raid3_metadata_decode_v3(data, md); break; case 4: - error = raid3_metadata_decode_v4(data, md); + case 5: + error = raid3_metadata_decode_v4v5(data, md); break; default: error = EINVAL; @@ -442,6 +446,8 @@ raid3_metadata_dump(const struct g_raid3_metadata *md) printf(" ROUND-ROBIN"); if ((md->md_mflags & G_RAID3_DEVICE_FLAG_VERIFY) != 0) printf(" VERIFY"); + if ((md->md_mflags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) + printf(" NOFAILSYNC"); } printf("\n"); printf(" dflags:"); diff --git a/sys/geom/raid3/g_raid3_ctl.c b/sys/geom/raid3/g_raid3_ctl.c index 67d1f44..952ac2b 100644 --- a/sys/geom/raid3/g_raid3_ctl.c +++ b/sys/geom/raid3/g_raid3_ctl.c @@ -98,8 +98,9 @@ g_raid3_ctl_configure(struct gctl_req *req, struct g_class *mp) struct g_raid3_softc *sc; struct g_raid3_disk *disk; const char *name; - int *nargs, do_sync = 0; + int *nargs, do_sync = 0, dirty = 1; int *autosync, *noautosync; + int *failsync, *nofailsync; int *round_robin, *noround_robin; int *verify, *noverify; u_int n; @@ -128,6 +129,21 @@ g_raid3_ctl_configure(struct gctl_req *req, struct g_class *mp) "noautosync"); return; } + failsync = gctl_get_paraml(req, "failsync", sizeof(*failsync)); + if (failsync == NULL) { + gctl_error(req, "No '%s' argument.", "failsync"); + return; + } + nofailsync = gctl_get_paraml(req, "nofailsync", sizeof(*nofailsync)); + if (nofailsync == NULL) { + gctl_error(req, "No '%s' argument.", "nofailsync"); + return; + } + if (*failsync && *nofailsync) { + gctl_error(req, "'%s' and '%s' specified.", "failsync", + "nofailsync"); + return; + } round_robin = gctl_get_paraml(req, "round_robin", sizeof(*round_robin)); if (round_robin == NULL) { gctl_error(req, "No '%s' argument.", "round_robin"); @@ -159,8 +175,8 @@ g_raid3_ctl_configure(struct gctl_req *req, struct g_class *mp) "noverify"); return; } - if (!*autosync && !*noautosync && !*round_robin && !*noround_robin && - !*verify && !*noverify) { + if (!*autosync && !*noautosync && !*failsync && !*nofailsync && + !*round_robin && !*noround_robin && !*verify && !*noverify) { gctl_error(req, "Nothing has changed."); return; } @@ -188,6 +204,15 @@ g_raid3_ctl_configure(struct gctl_req *req, struct g_class *mp) if (*noautosync) sc->sc_flags |= G_RAID3_DEVICE_FLAG_NOAUTOSYNC; } + if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) { + if (*failsync) + sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_NOFAILSYNC; + } else { + if (*nofailsync) { + sc->sc_flags |= G_RAID3_DEVICE_FLAG_NOFAILSYNC; + dirty = 0; + } + } if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_VERIFY) != 0) { if (*noverify) sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_VERIFY; @@ -215,6 +240,8 @@ g_raid3_ctl_configure(struct gctl_req *req, struct g_class *mp) if (disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) disk->d_flags &= ~G_RAID3_DISK_FLAG_FORCE_SYNC; } + if (!dirty) + disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; g_raid3_update_metadata(disk); if (do_sync) { if (disk->d_state == G_RAID3_DISK_STATE_STALE) { |