]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Put a 'canary' block in front of the backup
authorNeil Brown <neilb@suse.de>
Mon, 27 Mar 2006 04:14:43 +0000 (04:14 +0000)
committerNeil Brown <neilb@suse.de>
Mon, 27 Mar 2006 04:14:43 +0000 (04:14 +0000)
.. so corruptio can be detected.

Signed-off-by: Neil Brown <neilb@suse.de>
ChangeLog
Grow.c

index c7722b0ff6584bba0fb31916e76096584b632ce7..ade4debb9b111ce89e7179dd0a3efac78be9aa75 100644 (file)
--- 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 736afa57a25f57895ffa62a2078f8891c9822ab6..44329228ad5ef6a8d35403b64fdf6c2aea1e81bd 100644 (file)
--- 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);