]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: Fix linear-growth when devices are not all the same size.
authorNeilBrown <neilb@suse.de>
Wed, 15 Oct 2008 03:34:18 +0000 (14:34 +1100)
committerNeilBrown <neilb@suse.de>
Wed, 15 Oct 2008 03:34:18 +0000 (14:34 +1100)
If we add a device to a linear array which is a difference size
to the other devices in the array then, for v1.x metadata, we need to
make sure the size is correctly reflected in the superblock.

super1.c

index bec0c5e4b9304cd6a36dfd88b81eea1dc9543123..62a3ab9ea435dd1ebed58f772f07f6b98b1d3b70 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -599,7 +599,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
        }
        if (strcmp(update, "linear-grow-new") == 0) {
                int i;
        }
        if (strcmp(update, "linear-grow-new") == 0) {
                int i;
-               int rfd;
+               int rfd, fd;
                int max = __le32_to_cpu(sb->max_dev);
 
                for (i=0 ; i < max ; i++)
                int max = __le32_to_cpu(sb->max_dev);
 
                for (i=0 ; i < max ; i++)
@@ -620,6 +620,25 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 
                sb->dev_roles[i] =
                        __cpu_to_le16(info->disk.raid_disk);
 
                sb->dev_roles[i] =
                        __cpu_to_le16(info->disk.raid_disk);
+
+               fd = open(devname, O_RDONLY);
+               if (fd >= 0) {
+                       unsigned long long ds;
+                       get_dev_size(fd, devname, &ds);
+                       close(fd);
+                       ds >>= 9;
+                       if (__le64_to_cpu(sb->super_offset) <
+                           __le64_to_cpu(sb->data_offset)) {
+                               sb->data_size = __cpu_to_le64(
+                                       ds - __le64_to_cpu(sb->data_offset));
+                       } else {
+                               ds -= 8*2;
+                               ds &= ~(unsigned long long)(4*2-1);
+                               sb->super_offset = __cpu_to_le64(ds);
+                               sb->data_size = __cpu_to_le64(
+                                       ds - __le64_to_cpu(sb->data_offset));
+                       }
+               }
        }
        if (strcmp(update, "linear-grow-update") == 0) {
                sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
        }
        if (strcmp(update, "linear-grow-update") == 0) {
                sb->raid_disks = __cpu_to_le32(info->array.raid_disks);