.BR homehost ,
.BR resync ,
.BR byteorder ,
+.BR devicesize ,
or
.BR super-minor .
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).
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");
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 */
__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
} 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);
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];
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;
}
struct mdp_superblock_1 *super;
int uuid[4];
struct bitmap_super_s *bsb;
+ struct misc_dev_info *misc;
if (st->ss == NULL) {
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)
}
*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;
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;