]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Interpret "--metadata=1" with --assemble to imply any version-1, not just 1.0
authorDoug Ledford <dledford@redhat.com>
Sun, 8 Jul 2007 23:59:47 +0000 (09:59 +1000)
committerNeil Brown <neilb@suse.de>
Sun, 8 Jul 2007 23:59:47 +0000 (09:59 +1000)
From: Doug Ledford <dledford@redhat.com>

OK, this one fixes an issue where people were doing manual array
creation and specifying superblock types other than 1.0 (aka, 1.1, 1.2)
and then using mdadm -Ebs to populate their mdadm.conf file.  The
general problem is that if you specify a superblock type in the ARRAY
line (or on the command line), then you must specify the superblock type
*exactly*, including the minor version.  Unfortunately, mdadm -Ebs
prints out all version 1 superblocks, regardless of minor version, as
just plain old 1.  This breaks the mdadm.conf file for anything other
than plain version 1 superblock devices.

So, since I thought it was basically backwards that the mdadm -E output
was lax on specifying the location of the superblock where as the mdadm
-A input was strict, I reversed that.  With this patch, the mdadm -E
output is now exact for any given superblock.  But, in addition, the
mdadm -A input is now lax for any superblock that doesn't specifically
list the minor version, aka version 1 now means version 1, not version
0.90, but any minor version.  So does default/large.

super1.c

index 9901e004244c690fda98307269c816ba5a4fe7b2..0ff11fb12726fc963b44836db6b06e9a5b86f6f6 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -152,9 +152,17 @@ static void examine_super1(void *sbv, char *homehost)
        char *c;
        int l = homehost ? strlen(homehost) : 0;
        int layout;
+       unsigned long long sb_offset;
 
        printf("          Magic : %08x\n", __le32_to_cpu(sb->magic));
-       printf("        Version : %02d\n", 1);
+       printf("        Version : 1");
+       sb_offset = __le64_to_cpu(sb->super_offset);
+       if (sb_offset <= 4)
+               printf(".1\n");
+       else if (sb_offset <= 8)
+               printf(".2\n");
+       else
+               printf(".0\n");
        printf("    Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map));
        printf("     Array UUID : ");
        for (i=0; i<16; i++) {
@@ -337,6 +345,7 @@ static void brief_examine_super1(void *sbv)
 {
        struct mdp_superblock_1 *sb = sbv;
        int i;
+       unsigned long long sb_offset;
        char *nm;
        char *c=map_num(pers, __le32_to_cpu(sb->level));
 
@@ -348,9 +357,15 @@ static void brief_examine_super1(void *sbv)
        else
                nm = "??";
 
-       printf("ARRAY /dev/md/%s level=%s metadata=1 num-devices=%d UUID=",
-              nm,
-              c?c:"-unknown-", __le32_to_cpu(sb->raid_disks));
+       printf("ARRAY /dev/md/%s level=%s ", nm, c?c:"-unknown-");
+       sb_offset = __le64_to_cpu(sb->super_offset);
+       if (sb_offset <= 4)
+               printf("metadata=1.1 ");
+       else if (sb_offset <= 8)
+               printf("metadata=1.2 ");
+       else
+               printf("metadata=1.0 ");
+       printf("num-devices=%d UUID=", __le32_to_cpu(sb->raid_disks));
        for (i=0; i<16; i++) {
                if ((i&3)==0 && i != 0) printf(":");
                printf("%02x", sb->set_uuid[i]);
@@ -975,7 +990,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
        struct misc_dev_info *misc;
 
 
-       if (st->ss == NULL) {
+       if (st->ss == NULL || st->minor_version == -1) {
                int bestvers = -1;
                __u64 bestctime = 0;
                /* guess... choose latest ctime */
@@ -1123,9 +1138,7 @@ static struct supertype *match_metadata_desc1(char *arg)
 
        st->ss = &super1;
        st->max_devs = 384;
-       if (strcmp(arg, "1") == 0 ||
-           strcmp(arg, "1.0") == 0 ||
-           strcmp(arg, "default/large") == 0) {
+       if (strcmp(arg, "1.0") == 0) {
                st->minor_version = 0;
                return st;
        }
@@ -1137,6 +1150,11 @@ static struct supertype *match_metadata_desc1(char *arg)
                st->minor_version = 2;
                return st;
        }
+       if (strcmp(arg, "1") == 0 ||
+           strcmp(arg, "default/large") == 0) {
+               st->minor_version = -1;
+               return st;
+       }
 
        free(st);
        return NULL;
@@ -1154,6 +1172,9 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
        devsize -= choose_bm_space(devsize);
 
        switch(st->minor_version) {
+       case -1: /* no specified.  Now time to set default */
+               st->minor_version = 0;
+               /* FALL THROUGH */
        case 0:
                /* at end */
                return ((devsize - 8*2 ) & ~(4*2-1));