Support --update=devicesize for cases where the underlying device can change size.

This commit is contained in:
Neil Brown 2006-12-14 17:31:03 +11:00
parent 199171a297
commit bee8ec56f4
4 changed files with 52 additions and 7 deletions

View File

@ -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

17
mdadm.8
View File

@ -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).

View File

@ -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 */

View File

@ -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;