From a17a3de364806681fc7c1395364d11061a638ff3 Mon Sep 17 00:00:00 2001 From: Doug Ledford Date: Mon, 9 Jul 2007 09:59:47 +1000 Subject: [PATCH] Interpret "--metadata=1" with --assemble to imply any version-1, not just 1.0 From: Doug Ledford 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 | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/super1.c b/super1.c index 9901e004..0ff11fb1 100644 --- 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)); -- 2.39.2