diff options
Diffstat (limited to 'super1.c')
-rw-r--r-- | super1.c | 90 |
1 files changed, 55 insertions, 35 deletions
@@ -558,12 +558,13 @@ static void uuid_from_super1(struct supertype *st, int uuid[4]) cuuid[i] = super->set_uuid[i]; } -static void getinfo_super1(struct supertype *st, struct mdinfo *info) +static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) { struct mdp_superblock_1 *sb = st->sb; int working = 0; unsigned int i; - int role; + unsigned int role; + unsigned int map_disks = info->array.raid_disks; info->array.major_version = 1; info->array.minor_version = st->minor_version; @@ -629,15 +630,33 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info) } else info->reshape_active = 0; + if (map) + for (i=0; i<map_disks; i++) + map[i] = 0; for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { role = __le16_to_cpu(sb->dev_roles[i]); - if (/*role == 0xFFFF || */role < info->array.raid_disks) + if (/*role == 0xFFFF || */role < (unsigned) info->array.raid_disks) { working++; + if (map && role < map_disks) + map[role] = 1; + } } info->array.working_disks = working; } +static struct mdinfo *container_content1(struct supertype *st, char *subarray) +{ + struct mdinfo *info; + + if (subarray) + return NULL; + + info = malloc(sizeof(*info)); + getinfo_super1(st, info, NULL); + return info; +} + static int update_super1(struct supertype *st, struct mdinfo *info, char *update, char *devname, int verbose, @@ -657,8 +676,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, if (sb->events != __cpu_to_le64(info->events)) rv = 1; sb->events = __cpu_to_le64(info->events); - } - if (strcmp(update, "force-array")==0) { + } else if (strcmp(update, "force-array")==0) { /* Degraded array and 'force' requests to * maybe need to mark it 'clean'. */ @@ -669,8 +687,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, rv = 1; sb->resync_offset = MaxSector; } - } - if (strcmp(update, "assemble")==0) { + } else if (strcmp(update, "assemble")==0) { int d = info->disk.number; int want; if (info->disk.state == 6) @@ -695,8 +712,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, sb->reshape_position = __cpu_to_le64(info->reshape_progress); rv = 1; } - } - if (strcmp(update, "linear-grow-new") == 0) { + } else if (strcmp(update, "linear-grow-new") == 0) { unsigned int i; int rfd, fd; unsigned int max = __le32_to_cpu(sb->max_dev); @@ -738,17 +754,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, ds - __le64_to_cpu(sb->data_offset)); } } - } - if (strcmp(update, "linear-grow-update") == 0) { + } else if (strcmp(update, "linear-grow-update") == 0) { sb->raid_disks = __cpu_to_le32(info->array.raid_disks); sb->dev_roles[info->disk.number] = __cpu_to_le16(info->disk.raid_disk); - } - if (strcmp(update, "resync") == 0) { + } else if (strcmp(update, "resync") == 0) { /* make sure resync happens */ sb->resync_offset = 0ULL; - } - if (strcmp(update, "uuid") == 0) { + } else if (strcmp(update, "uuid") == 0) { copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) { @@ -758,8 +771,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, } } else if (strcmp(update, "no-bitmap") == 0) { sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); - } - if (strcmp(update, "homehost") == 0 && + } else if (strcmp(update, "homehost") == 0 && homehost) { char *c; update = "name"; @@ -769,8 +781,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, else strncpy(info->name, sb->set_name, 32); info->name[32] = 0; - } - if (strcmp(update, "name") == 0) { + } else if (strcmp(update, "name") == 0) { if (info->name[0] == 0) sprintf(info->name, "%d", info->array.md_minor); memset(sb->set_name, 0, sizeof(sb->set_name)); @@ -782,8 +793,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, strcat(sb->set_name, info->name); } else strcpy(sb->set_name, info->name); - } - if (strcmp(update, "devicesize") == 0 && + } else 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 */ @@ -795,9 +805,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info, misc->device_size - __le64_to_cpu(sb->data_offset)); printf("Size is %llu\n", (unsigned long long) __le64_to_cpu(sb->data_size)); - } - if (strcmp(update, "_reshape_progress")==0) + } else if (strcmp(update, "_reshape_progress")==0) sb->reshape_position = __cpu_to_le64(info->reshape_progress); + else + rv = -1; sb->sb_csum = calc_sb_1_csum(sb); return rv; @@ -1022,11 +1033,13 @@ static unsigned long choose_bm_space(unsigned long devsize) return 4*2; } +static void free_super1(struct supertype *st); + #ifndef MDASSEMBLE static int write_init_super1(struct supertype *st) { struct mdp_superblock_1 *sb = st->sb; - struct supertype refst; + struct supertype *refst; int rfd; int rv = 0; unsigned long long bm_space; @@ -1058,10 +1071,9 @@ static int write_init_super1(struct supertype *st) sb->events = 0; - refst =*st; - refst.sb = NULL; - if (load_super1(&refst, di->fd, NULL)==0) { - struct mdp_superblock_1 *refsb = refst.sb; + refst = dup_super(st); + if (load_super1(refst, di->fd, NULL)==0) { + struct mdp_superblock_1 *refsb = refst->sb; memcpy(sb->device_uuid, refsb->device_uuid, 16); if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) { @@ -1074,8 +1086,9 @@ static int write_init_super1(struct supertype *st) if (get_linux_version() >= 2006018) sb->dev_number = refsb->dev_number; } - free(refsb); + free_super1(refst); } + free(refst); if (!get_dev_size(di->fd, NULL, &dsize)) return 1; @@ -1210,8 +1223,6 @@ static int compare_super1(struct supertype *st, struct supertype *tst) return 0; } -static void free_super1(struct supertype *st); - static int load_super1(struct supertype *st, int fd, char *devname) { unsigned long long dsize; @@ -1223,9 +1234,6 @@ static int load_super1(struct supertype *st, int fd, char *devname) free_super1(st); - if (st->subarray[0]) - return 1; - if (st->ss == NULL || st->minor_version == -1) { int bestvers = -1; struct supertype tst; @@ -1380,6 +1388,7 @@ static struct supertype *match_metadata_desc1(char *arg) if (!st) return st; memset(st, 0, sizeof(*st)); + st->container_dev = NoMdDev; st->ss = &super1; st->max_devs = 384; st->sb = NULL; @@ -1646,13 +1655,20 @@ static void free_super1(struct supertype *st) { if (st->sb) free(st->sb); + while (st->info) { + struct devinfo *di = st->info; + st->info = di->next; + if (di->fd >= 0) + close(di->fd); + free(di); + } st->sb = NULL; } #ifndef MDASSEMBLE static int validate_geometry1(struct supertype *st, int level, int layout, int raiddisks, - int chunk, unsigned long long size, + int *chunk, unsigned long long size, char *subdev, unsigned long long *freesize, int verbose) { @@ -1664,6 +1680,9 @@ static int validate_geometry1(struct supertype *st, int level, fprintf(stderr, Name ": 1.x metadata does not support containers\n"); return 0; } + if (chunk && *chunk == UnSet) + *chunk = DEFAULT_CHUNK; + if (!subdev) return 1; @@ -1701,6 +1720,7 @@ struct superswitch super1 = { .match_home = match_home1, .uuid_from_super = uuid_from_super1, .getinfo_super = getinfo_super1, + .container_content = container_content1, .update_super = update_super1, .init_super = init_super1, .store_super = store_super1, |