summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-11-01 22:51:49 +0000
committerpjd <pjd@FreeBSD.org>2006-11-01 22:51:49 +0000
commitb34fb80d8364fbc4f1737da5f2916fe5b39a9325 (patch)
tree97b3734a2b0b5f3ef52ead534f66a992a2f04c67 /sys/geom
parent3d8e2e0a6f357ed1a3f49941041c5850215bb15d (diff)
downloadFreeBSD-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')
-rw-r--r--sys/geom/mirror/g_mirror.c10
-rw-r--r--sys/geom/mirror/g_mirror.h14
-rw-r--r--sys/geom/mirror/g_mirror_ctl.c32
-rw-r--r--sys/geom/raid3/g_raid3.c10
-rw-r--r--sys/geom/raid3/g_raid3.h14
-rw-r--r--sys/geom/raid3/g_raid3_ctl.c33
6 files changed, 98 insertions, 15 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index f03da3b..419611e 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -802,6 +802,8 @@ g_mirror_idle(struct g_mirror_softc *sc, int acw)
if (sc->sc_provider == NULL)
return (0);
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) != 0)
+ return (0);
if (sc->sc_idle)
return (0);
if (sc->sc_writes > 0)
@@ -831,6 +833,8 @@ g_mirror_unidle(struct g_mirror_softc *sc)
g_topology_assert_not();
sx_assert(&sc->sc_lock, SX_XLOCKED);
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) != 0)
+ return;
sc->sc_idle = 0;
sc->sc_last_write = time_uptime;
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
@@ -1884,6 +1888,8 @@ g_mirror_update_idle(struct g_mirror_softc *sc, struct g_mirror_disk *disk)
sx_assert(&sc->sc_lock, SX_LOCKED);
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) != 0)
+ return;
if (!sc->sc_idle && (disk->d_flags & G_MIRROR_DISK_FLAG_DIRTY) == 0) {
G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as dirty.",
g_mirror_get_diskname(disk), sc->sc_name);
@@ -1928,7 +1934,8 @@ g_mirror_sync_start(struct g_mirror_disk *disk)
G_MIRROR_DEBUG(0, "Device %s: rebuilding provider %s.", sc->sc_name,
g_mirror_get_diskname(disk));
- disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) == 0)
+ disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
KASSERT(disk->d_sync.ds_consumer == NULL,
("Sync consumer already exists (device=%s, disk=%s).",
sc->sc_name, g_mirror_get_diskname(disk)));
@@ -3180,6 +3187,7 @@ g_mirror_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
sbuf_printf(sb, name); \
} \
} while (0)
+ ADD_FLAG(G_MIRROR_DEVICE_FLAG_NOFAILSYNC, "NOFAILSYNC");
ADD_FLAG(G_MIRROR_DEVICE_FLAG_NOAUTOSYNC, "NOAUTOSYNC");
#undef ADD_FLAG
}
diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h
index a6ddc51..eb67b6e0 100644
--- a/sys/geom/mirror/g_mirror.h
+++ b/sys/geom/mirror/g_mirror.h
@@ -41,8 +41,9 @@
* 1 - Added 'prefer' balance algorithm.
* 2 - Added md_genid field to metadata.
* 3 - Added md_provsize field to metadata.
+ * 4 - Added 'no failure synchronization' flag.
*/
-#define G_MIRROR_VERSION 3
+#define G_MIRROR_VERSION 4
#define G_MIRROR_BALANCE_NONE 0
#define G_MIRROR_BALANCE_ROUND_ROBIN 1
@@ -64,7 +65,9 @@
G_MIRROR_DISK_FLAG_INACTIVE)
#define G_MIRROR_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL
-#define G_MIRROR_DEVICE_FLAG_MASK (G_MIRROR_DEVICE_FLAG_NOAUTOSYNC)
+#define G_MIRROR_DEVICE_FLAG_NOFAILSYNC 0x0000000000000002ULL
+#define G_MIRROR_DEVICE_FLAG_MASK (G_MIRROR_DEVICE_FLAG_NOAUTOSYNC | \
+ G_MIRROR_DEVICE_FLAG_NOFAILSYNC)
#ifdef _KERNEL
extern u_int g_mirror_debug;
@@ -341,7 +344,7 @@ mirror_metadata_decode_v2(const u_char *data, struct g_mirror_metadata *md)
return (0);
}
static __inline int
-mirror_metadata_decode_v3(const u_char *data, struct g_mirror_metadata *md)
+mirror_metadata_decode_v3v4(const u_char *data, struct g_mirror_metadata *md)
{
MD5_CTX ctx;
@@ -385,7 +388,8 @@ mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md)
error = mirror_metadata_decode_v2(data, md);
break;
case 3:
- error = mirror_metadata_decode_v3(data, md);
+ case 4:
+ error = mirror_metadata_decode_v3v4(data, md);
break;
default:
error = EINVAL;
@@ -456,6 +460,8 @@ mirror_metadata_dump(const struct g_mirror_metadata *md)
if (md->md_mflags == 0)
printf(" NONE");
else {
+ if ((md->md_mflags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) != 0)
+ printf(" NOFAILSYNC");
if ((md->md_mflags & G_MIRROR_DEVICE_FLAG_NOAUTOSYNC) != 0)
printf(" NOAUTOSYNC");
}
diff --git a/sys/geom/mirror/g_mirror_ctl.c b/sys/geom/mirror/g_mirror_ctl.c
index 9578782..27e58ce 100644
--- a/sys/geom/mirror/g_mirror_ctl.c
+++ b/sys/geom/mirror/g_mirror_ctl.c
@@ -97,7 +97,8 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
intmax_t *slicep;
uint32_t slice;
uint8_t balance;
- int *nargs, *autosync, *noautosync, *hardcode, *dynamic, do_sync = 0;
+ int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic;
+ int *nargs, do_sync = 0, dirty = 1;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -128,6 +129,16 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "No '%s' argument.", "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;
+ }
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
if (hardcode == NULL) {
gctl_error(req, "No '%s' argument.", "hardcode");
@@ -143,6 +154,11 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
"noautosync");
return;
}
+ if (*failsync && *nofailsync) {
+ gctl_error(req, "'%s' and '%s' specified.", "failsync",
+ "nofailsync");
+ return;
+ }
if (*hardcode && *dynamic) {
gctl_error(req, "'%s' and '%s' specified.", "hardcode",
"dynamic");
@@ -180,7 +196,8 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
return;
}
if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
- !*noautosync && !*hardcode && !*dynamic) {
+ !*noautosync && !*failsync && !*nofailsync && !*hardcode &&
+ !*dynamic) {
sx_xunlock(&sc->sc_lock);
gctl_error(req, "Nothing has changed.");
return;
@@ -196,6 +213,15 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
if (*noautosync)
sc->sc_flags |= G_MIRROR_DEVICE_FLAG_NOAUTOSYNC;
}
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOFAILSYNC) != 0) {
+ if (*failsync)
+ sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_NOFAILSYNC;
+ } else {
+ if (*nofailsync) {
+ sc->sc_flags |= G_MIRROR_DEVICE_FLAG_NOFAILSYNC;
+ dirty = 0;
+ }
+ }
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (do_sync) {
if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING)
@@ -205,6 +231,8 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
else if (*dynamic)
disk->d_flags &= ~G_MIRROR_DISK_FLAG_HARDCODED;
+ if (!dirty)
+ disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
g_mirror_update_metadata(disk);
if (do_sync) {
if (disk->d_state == G_MIRROR_DISK_STATE_STALE) {
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) {
OpenPOWER on IntegriCloud