summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-03-27 04:14:43 +0000
committerNeil Brown <neilb@suse.de>2006-03-27 04:14:43 +0000
commit2efedc7bd23b4796fcf535cb28f796b235aff9ca (patch)
tree0646906edd86acc385a32d3a02d6593b3021482c
parentca9ce4ec3e67cc6296a9e255a9612e2b7b78b612 (diff)
downloadmdadm-2efedc7bd23b4796fcf535cb28f796b235aff9ca.tar.gz
mdadm-2efedc7bd23b4796fcf535cb28f796b235aff9ca.tar.xz
mdadm-2efedc7bd23b4796fcf535cb28f796b235aff9ca.zip
Put a 'canary' block in front of the backup
.. so corruptio can be detected. Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r--ChangeLog7
-rw-r--r--Grow.c37
2 files changed, 36 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index c7722b0..ade4deb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Changes Prior to 2.4 release
+ - Rewrite 'reshape' support including performing a backup
+ of the critical region for a raid5 growth, and restoring that
+ backup after a crash.
+ - Put a 'canary' at each end of the backup so a corruption
+ can be more easily detected.
+
Changes Prior to 2.3.1 release
- Fixed -O2 compile so I could make and RPM.
- Type cast number to be printed %llu so it compiles on 64bit
diff --git a/Grow.c b/Grow.c
index 736afa5..4432922 100644
--- a/Grow.c
+++ b/Grow.c
@@ -689,13 +689,32 @@ int Grow_reshape(char *devname, int fd, int quiet,
spares = sra->spares;
- /* Decide offset for the backup and llseek the spares */
+
+ memcpy(bsb.magic, "md_backup_data-1", 16);
+ st->ss->uuid_from_super((int*)&bsb.set_uuid, super);
+ bsb.mtime = __cpu_to_le64(time(0));
+ bsb.arraystart = 0;
+ bsb.length = __cpu_to_le64(last_block);
+
+ /* Decide offset for the backup, llseek the spares, and write
+ * a leading superblock 4K earlier.
+ */
for (i=array.raid_disks; i<d; i++) {
+ char buf[4096];
offsets[i] += sra->component_size - last_block - 8;
- if (lseek64(fdlist[i], offsets[i]<<9, 0) != offsets[i]<<9) {
+ if (lseek64(fdlist[i], (offsets[i]<<9) - 4096, 0)
+ != (offsets[i]<<9) - 4096) {
fprintf(stderr, Name ": could not seek...\n");
goto abort;
}
+ memset(buf, 0, sizeof(buf));
+ bsb.devstart = __cpu_to_le64(offsets[i]);
+ bsb.sb_csum = bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum)-((char*)&bsb));
+ memcpy(buf, &bsb, sizeof(bsb));
+ if (write(fdlist[i], buf, 4096) != 4096) {
+ fprintf(stderr, Name ": could not write leading superblock\n");
+ goto abort;
+ }
}
array.level = nlevel;
array.raid_disks = ndisks;
@@ -728,12 +747,7 @@ int Grow_reshape(char *devname, int fd, int quiet,
devname);
goto abort_resume;
}
- /* FIXME write superblocks */
- memcpy(bsb.magic, "md_backup_data-1", 16);
- st->ss->uuid_from_super((int*)&bsb.set_uuid, super);
- bsb.mtime = __cpu_to_le64(time(0));
- bsb.arraystart = 0;
- bsb.length = __cpu_to_le64(last_block);
+
for (i=odisks; i<d ; i++) {
bsb.devstart = __cpu_to_le64(offsets[i]);
bsb.sb_csum = bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum)-((char*)&bsb));
@@ -823,6 +837,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
struct mdinfo dinfo;
struct mddev_ident_s id;
struct mdp_backup_super bsb;
+ char buf[4096];
/* This was a spare and may have some saved data on it.
* Load the superblock, find and load the
@@ -863,6 +878,12 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
if (lseek64(fdlist[i], __le64_to_cpu(bsb.devstart)*512, 0)< 0)
continue; /* Cannot seek */
+ /* There should be a duplicate backup superblock 4k before here */
+ if (lseek64(fdlist[i], -4096, 1) < 0 ||
+ read(fdlist[i], buf, 4096) != 4096 ||
+ memcmp(buf, &bsb, sizeof(buf)) != 0)
+ continue; /* Cannot find leading superblock */
+
/* Now need the data offsets for all devices. */
offsets = malloc(sizeof(*offsets)*info->array.raid_disks);