From bee8ec56f4d96a3ac7e6f6f256be6331dfafb076 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 14 Dec 2006 17:31:03 +1100 Subject: [PATCH] Support --update=devicesize for cases where the underlying device can change size. --- ChangeLog | 2 ++ mdadm.8 | 17 +++++++++++++++++ mdadm.c | 6 ++++-- super1.c | 34 +++++++++++++++++++++++++++++----- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6ea0c3b5..1c359f85 100644 --- 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 2e92ec94..f761853c 100644 --- 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 286df300..41360c48 100644 --- 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 */ diff --git a/super1.c b/super1.c index 7aa324fc..368d9bcf 100644 --- 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; -- 2.39.2