]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
DDF: factor out writing super block to single disk
authormwilck@arcor.de <mwilck@arcor.de>
Thu, 18 Jul 2013 18:49:01 +0000 (20:49 +0200)
committerNeilBrown <neilb@suse.de>
Mon, 22 Jul 2013 06:56:32 +0000 (16:56 +1000)
Factor out single disk from __write_init_super_ddf to a new function
_write_super_to_disk. Use this function in store_super_ddf.

Signed-off-by: NeilBrown <neilb@suse.de>
super-ddf.c

index efdba6d07578b78b942022475a8785b799eeb2d7..8c6fa6d71bfae0f0a39c05bb58814689680b38de 100644 (file)
@@ -2864,70 +2864,72 @@ out:
        return ret;
 }
 
+static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d)
+{
+       unsigned long long size;
+       int fd = d->fd;
+       if (fd < 0)
+               return 0;
+
+       /* We need to fill in the primary, (secondary) and workspace
+        * lba's in the headers, set their checksums,
+        * Also checksum phys, virt....
+        *
+        * Then write everything out, finally the anchor is written.
+        */
+       get_dev_size(fd, NULL, &size);
+       size /= 512;
+       if (d->workspace_lba != 0)
+               ddf->anchor.workspace_lba = d->workspace_lba;
+       else
+               ddf->anchor.workspace_lba =
+                       __cpu_to_be64(size - 32*1024*2);
+       if (d->primary_lba != 0)
+               ddf->anchor.primary_lba = d->primary_lba;
+       else
+               ddf->anchor.primary_lba =
+                       __cpu_to_be64(size - 16*1024*2);
+       if (d->secondary_lba != 0)
+               ddf->anchor.secondary_lba = d->secondary_lba;
+       else
+               ddf->anchor.secondary_lba =
+                       __cpu_to_be64(size - 32*1024*2);
+       ddf->anchor.seq = ddf->active->seq;
+       memcpy(&ddf->primary, &ddf->anchor, 512);
+       memcpy(&ddf->secondary, &ddf->anchor, 512);
+
+       ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
+       ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
+       ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
+
+       if (!__write_ddf_structure(d, ddf, DDF_HEADER_PRIMARY))
+               return 0;
+
+       if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY))
+               return 0;
+
+       lseek64(fd, (size-1)*512, SEEK_SET);
+       if (write(fd, &ddf->anchor, 512) < 0)
+               return 0;
+
+       return 1;
+}
+
 static int __write_init_super_ddf(struct supertype *st)
 {
        struct ddf_super *ddf = st->sb;
        struct dl *d;
        int attempts = 0;
        int successes = 0;
-       unsigned long long size;
-       __u32 seq;
 
        pr_state(ddf, __func__);
 
-       seq = ddf->active->seq;
-
        /* try to write updated metadata,
         * if we catch a failure move on to the next disk
         */
        for (d = ddf->dlist; d; d=d->next) {
-               int fd = d->fd;
-
-               if (fd < 0)
-                       continue;
-
                attempts++;
-               /* We need to fill in the primary, (secondary) and workspace
-                * lba's in the headers, set their checksums,
-                * Also checksum phys, virt....
-                *
-                * Then write everything out, finally the anchor is written.
-                */
-               get_dev_size(fd, NULL, &size);
-               size /= 512;
-               if (d->workspace_lba != 0)
-                       ddf->anchor.workspace_lba = d->workspace_lba;
-               else
-                       ddf->anchor.workspace_lba =
-                               __cpu_to_be64(size - 32*1024*2);
-               if (d->primary_lba != 0)
-                       ddf->anchor.primary_lba = d->primary_lba;
-               else
-                       ddf->anchor.primary_lba =
-                               __cpu_to_be64(size - 16*1024*2);
-               if (d->secondary_lba != 0)
-                       ddf->anchor.secondary_lba = d->secondary_lba;
-               else
-                       ddf->anchor.secondary_lba =
-                               __cpu_to_be64(size - 32*1024*2);
-               ddf->anchor.seq = seq;
-               memcpy(&ddf->primary, &ddf->anchor, 512);
-               memcpy(&ddf->secondary, &ddf->anchor, 512);
-
-               ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
-               ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
-               ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
-
-               if (!__write_ddf_structure(d, ddf, DDF_HEADER_PRIMARY))
-                       continue;
-
-               if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY))
-                       continue;
-
-               lseek64(fd, (size-1)*512, SEEK_SET);
-               if (write(fd, &ddf->anchor, 512) < 0)
-                       continue;
-               successes++;
+               successes += _write_super_to_disk(ddf, d);
        }
 
        return attempts != successes;
@@ -3729,17 +3731,9 @@ static int store_super_ddf(struct supertype *st, int fd)
                               (int)minor(sta.st_rdev));
                        return 1;
                }
-               /*
-                  For DDF, writing to just one disk makes no sense.
-                  We would run the risk of writing inconsistent meta data
-                  to the devices. So just call __write_init_super_ddf and
-                  write to all devices, including this one.
-                  Use the fd passed to this function, just in case dl->fd
-                  is invalid.
-                */
                ofd = dl->fd;
                dl->fd = fd;
-               ret =  __write_init_super_ddf(st);
+               ret = (_write_super_to_disk(ddf, dl) != 1);
                dl->fd = ofd;
                return ret;
        }