]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Support --update=devicesize for cases where the underlying device can change size.
authorNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:31:03 +0000 (17:31 +1100)
committerNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:31:03 +0000 (17:31 +1100)
ChangeLog
mdadm.8
mdadm.c
super1.c

index 6ea0c3b5ad6bd8534f259913e069e98192154e7c..1c359f85a284f4f54174ae323429cb2321db3253 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,8 @@ Changes Prior to this release
        missing devices (which is needed else if won't assemble.
        Without this fix it would only assemble if one or zero
        missing devices.
+    -   Support --update=devicesize for cases where the underlying device
+       can change size.
 
 Changes Prior to 2.5.6 release
     -   Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled
diff --git a/mdadm.8 b/mdadm.8
index 2e92ec94de1871e571c8e8205e6938d7d28592fd..f761853c16ec5f6d91aa9f39cef8f7479a21f4cd 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -712,6 +712,7 @@ argument given to this flag can be one of
 .BR homehost ,
 .BR resync ,
 .BR byteorder ,
+.BR devicesize ,
 or
 .BR super-minor .
 
@@ -789,6 +790,22 @@ The
 option will correct the summaries in the superblock. That is the
 counts of total, working, active, failed, and spare devices.
 
+The
+.B devicesize
+will rarely be of use.  It applies to version 1.1 and 1.2 metadata
+only (where the metadata is at the start of the device) and is only
+useful when the component device has changed size (typically become
+larger).  The version 1 metadata records the amount of the device that
+can be used to store data, so if a device in a version 1.1 or 1.2
+array becomes larger, the metadata will still be visible, but the
+extra space will not.  In this case it might be useful to assemble the
+array with
+.BR --update=devicesize .
+This will cause
+.I mdadm
+to determine the maximum usable amount of space on each device and
+update the relevant field in the metadata.
+
 .TP
 .B --auto-update-homehost
 This flag is only meaning with auto-assembly (see discussion below).
diff --git a/mdadm.c b/mdadm.c
index 286df300a6e5bd7dd4d5dd69e8a1ed680d651ad7..41360c4813afa403a234f8e89f1879482dd44fe0 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -582,6 +582,8 @@ int main(int argc, char *argv[])
                                continue;
                        if (strcmp(update, "homehost")==0)
                                continue;
+                       if (strcmp(update, "devicesize")==0)
+                               continue;
                        if (strcmp(update, "byteorder")==0) {
                                if (ss) {
                                        fprintf(stderr, Name ": must not set metadata type with --update=byteorder.\n");
@@ -601,8 +603,8 @@ int main(int argc, char *argv[])
                        else
                                fprintf(stderr, Name ": '--update=%s' is invalid.  ", update);
                        fprintf(stderr, "Valid --update options are:\n"
-                               "     'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
-                               "     'summaries', 'homehost', 'byteorder'.\n");
+               "     'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
+               "     'summaries', 'homehost', 'byteorder', 'devicesize'.\n");
                        exit(2);
 
                case O(ASSEMBLE,NoDegraded): /* --no-degraded */
index 7aa324fc459b06a64c6c0ddf1b87c772e661fbce..368d9bcf3e6fcf055f64cae56098a64e935cdcaf 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -94,6 +94,10 @@ struct mdp_superblock_1 {
        __u16   dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
 };
 
+struct misc_dev_info {
+       __u64 device_size;
+};
+
 /* feature_map bits */
 #define MD_FEATURE_BITMAP_OFFSET       1
 #define        MD_FEATURE_RECOVERY_OFFSET      2 /* recovery_offset is present and
@@ -558,6 +562,17 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update,
                } else
                        strcpy(sb->set_name, info->name);
        }
+       if (strcmp(update, "devicesize") == 0 &&
+           __le64_to_cpu(sb->super_offset) <
+           __le64_to_cpu(sb->data_offset)) {
+               /* set data_size to device size less data_offset */
+               struct misc_dev_info *misc = (struct misc_dev_info*)
+                       (sbv + 1024 + sizeof(struct bitmap_super_s));
+               printf("Size was %llu\n", __le64_to_cpu(sb->data_size));
+               sb->data_size = __cpu_to_le64(
+                       misc->device_size - __le64_to_cpu(sb->data_offset));
+               printf("Size is %llu\n", __le64_to_cpu(sb->data_size));
+       }
        if (strcmp(update, "_reshape_progress")==0)
                sb->reshape_position = __cpu_to_le64(info->reshape_progress);
 
@@ -568,7 +583,8 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update,
 static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
                       unsigned long long size, char *name, char *homehost)
 {
-       struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t));
+       struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t) +
+                                            sizeof(struct misc_dev_info));
        int spares;
        int rfd;
        char defname[10];
@@ -882,8 +898,10 @@ static int compare_super1(void **firstp, void *secondv)
                return 1;
 
        if (!first) {
-               first = malloc(1024+sizeof(bitmap_super_t));
-               memcpy(first, second, 1024+sizeof(bitmap_super_t));
+               first = malloc(1024+sizeof(bitmap_super_t) +
+                              sizeof(struct misc_dev_info));
+               memcpy(first, second, 1024+sizeof(bitmap_super_t) +
+                      sizeof(struct misc_dev_info));
                *firstp = first;
                return 0;
        }
@@ -908,6 +926,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
        struct mdp_superblock_1 *super;
        int uuid[4];
        struct bitmap_super_s *bsb;
+       struct misc_dev_info *misc;
 
 
        if (st->ss == NULL) {
@@ -997,7 +1016,8 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                return 1;
        }
 
-       super = malloc(1024 + sizeof(bitmap_super_t));
+       super = malloc(1024 + sizeof(bitmap_super_t) +
+                      sizeof(struct misc_dev_info));
 
        if (read(fd, super, 1024) != 1024) {
                if (devname)
@@ -1031,6 +1051,11 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
        }
        *sbp = super;
 
+       bsb = (struct bitmap_super_s *)(((char*)super)+1024);
+
+       misc = (struct misc_dev_info*) (bsb+1);
+       misc->device_size = dsize;
+
        /* Now check on the bitmap superblock */
        if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0)
                return 0;
@@ -1044,7 +1069,6 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                goto no_bitmap;
 
        uuid_from_super1(uuid, super);
-       bsb = (struct bitmap_super_s *)(((char*)super)+1024);
        if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC ||
            memcmp(bsb->uuid, uuid, 16) != 0)
                goto no_bitmap;