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++) {
printf(" Raid Level : %s\n", c?c:"-unknown-");
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
printf("\n");
- printf(" Used Dev Size : %llu%s\n",
- (unsigned long long)sb->data_size,
- human_size(sb->data_size<<9));
+ printf(" Avail Dev Size : %llu%s\n",
+ (unsigned long long)__le64_to_cpu(sb->data_size),
+ human_size(__le64_to_cpu(sb->data_size)<<9));
if (__le32_to_cpu(sb->level) >= 0) {
int ddsks=0;
switch(__le32_to_cpu(sb->level)) {
ddsks*(unsigned long long)__le64_to_cpu(sb->size),
human_size(ddsks*__le64_to_cpu(sb->size)<<9));
if (sb->size != sb->data_size)
- printf(" Used Size : %llu%s\n",
+ printf(" Used Dev Size : %llu%s\n",
(unsigned long long)__le64_to_cpu(sb->size),
human_size(__le64_to_cpu(sb->size)<<9));
}
printf("\n");
if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
printf("Internal Bitmap : %ld sectors from superblock\n",
- (long)__le32_to_cpu(sb->bitmap_offset));
+ (long)(int32_t)__le32_to_cpu(sb->bitmap_offset));
}
if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) {
printf(" Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2,
{
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));
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]);
}
}
+static void export_super1(void *sbv)
+{
+ struct mdp_superblock_1 *sb = sbv;
+ int i;
+ int len = 32;
+
+ for (i=0; i<32; i++)
+ if (sb->set_name[i] == '\n' ||
+ sb->set_name[i] == '\0') {
+ len = i;
+ break;
+ }
+ if (len)
+ printf("MD_NAME=%.*s\n", len, sb->set_name);
+ printf("MD_UUID=");
+ for (i=0; i<16; i++) {
+ if ((i&3)==0 && i != 0) printf(":");
+ printf("%02x", sb->set_uuid[i]);
+ }
+ printf("\n");
+}
+
#endif
static int match_home1(void *sbv, char *homehost)
rv = 1;
}
}
- if (strcmp(update, "grow") == 0) {
+ if (strcmp(update, "linear-grow-new") == 0) {
+ int i;
+ int rfd;
+ int max = __le32_to_cpu(sb->max_dev);
+
+ for (i=0 ; i < max ; i++)
+ if (__le16_to_cpu(sb->dev_roles[i]) >= 0xfffe)
+ break;
+ sb->dev_number = __cpu_to_le32(i);
+ info->disk.number = i;
+ if (max >= __le32_to_cpu(sb->max_dev))
+ sb->max_dev = __cpu_to_le32(max+1);
+
+ if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
+ read(rfd, sb->device_uuid, 16) != 16) {
+ *(__u32*)(sb->device_uuid) = random();
+ *(__u32*)(sb->device_uuid+4) = random();
+ *(__u32*)(sb->device_uuid+8) = random();
+ *(__u32*)(sb->device_uuid+12) = random();
+ }
+
+ sb->dev_roles[i] =
+ __cpu_to_le16(info->disk.raid_disk);
+ }
+ if (strcmp(update, "linear-grow-update") == 0) {
sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
- /* As we are just adding a spare, there is no need to
- * make any change to the dev_roles array
- */
+ sb->dev_roles[info->disk.number] =
+ __cpu_to_le16(info->disk.raid_disk);
}
if (strcmp(update, "resync") == 0) {
/* make sure resync happens */
/* 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));
+ printf("Size was %llu\n", (unsigned long long)
+ __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));
+ printf("Size is %llu\n", (unsigned long long)
+ __le64_to_cpu(sb->data_size));
}
if (strcmp(update, "_reshape_progress")==0)
sb->reshape_position = __cpu_to_le64(info->reshape_progress);
static int load_super1(struct supertype *st, int fd, void **sbp, char *devname);
+static unsigned long choose_bm_space(unsigned long devsize)
+{
+ /* if the device is bigger than 8Gig, save 64k for bitmap usage,
+ * if bigger than 200Gig, save 128k
+ */
+ if (devsize < 64*2) return 0;
+ if (devsize - 64*2 >= 200*1024*1024*2)
+ return 128*2;
+ if (devsize - 4*2 > 8*1024*1024*2)
+ return 64*2;
+ return 4*2;
+}
+
static int write_init_super1(struct supertype *st, void *sbv,
mdu_disk_info_t *dinfo, char *devname)
{
int rv;
int bm_space;
- unsigned long space;
unsigned long long dsize, array_size;
long long sb_offset;
*/
array_size = __le64_to_cpu(sb->size);
/* work out how much space we left of a bitmap */
- if (array_size >= 200*1024*1024*2)
- bm_space = 128*2;
- else if (array_size > 8*1024*1024*2)
- bm_space = 64*2;
- else
- bm_space = 0;
+ bm_space = choose_bm_space(array_size);
switch(st->minor_version) {
case 0:
break;
case 1:
sb->super_offset = __cpu_to_le64(0);
+ if (4*2 + bm_space + __le64_to_cpu(sb->size) > dsize)
+ bm_space = dsize - __le64_to_cpu(sb->size) - 4*2;
sb->data_offset = __cpu_to_le64(bm_space + 4*2);
sb->data_size = __cpu_to_le64(dsize - bm_space - 4*2);
break;
case 2:
sb_offset = 4*2;
- if (dsize - 4*2 - 64*2 >= array_size && array_size > 8*1024*1024*2)
- space = 64*2;
- else
- space = 4*2;
sb->super_offset = __cpu_to_le64(4*2);
+ if (4*2 + 4*2 + bm_space + __le64_to_cpu(sb->size) > dsize)
+ bm_space = dsize - __le64_to_cpu(sb->size) - 4*2 - 4*2;
sb->data_offset = __cpu_to_le64(4*2 + 4*2 + bm_space);
sb->data_size = __cpu_to_le64(dsize - 4*2 - 4*2 - bm_space );
break;
struct misc_dev_info *misc;
- if (st->ss == NULL) {
+ if (st->ss == NULL || st->minor_version == -1) {
int bestvers = -1;
+ struct supertype tst;
__u64 bestctime = 0;
/* guess... choose latest ctime */
- st->ss = &super1;
- for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) {
- switch(load_super1(st, fd, sbp, devname)) {
+ tst.ss = &super1;
+ for (tst.minor_version = 0; tst.minor_version <= 2 ; tst.minor_version++) {
+ switch(load_super1(&tst, fd, sbp, devname)) {
case 0: super = *sbp;
if (bestvers == -1 ||
bestctime < __le64_to_cpu(super->ctime)) {
- bestvers = st->minor_version;
+ bestvers = tst.minor_version;
bestctime = __le64_to_cpu(super->ctime);
}
free(super);
*sbp = NULL;
break;
- case 1: st->ss = NULL; return 1; /*bad device */
+ case 1: return 1; /*bad device */
case 2: break; /* bad, try next */
}
}
if (bestvers != -1) {
int rv;
- st->minor_version = bestvers;
- st->ss = &super1;
- st->max_devs = 384;
- rv = load_super1(st, fd, sbp, devname);
- if (rv) st->ss = NULL;
+ tst.minor_version = bestvers;
+ tst.ss = &super1;
+ tst.max_devs = 384;
+ rv = load_super1(&tst, fd, sbp, devname);
+ if (rv == 0)
+ *st = tst;
return rv;
}
- st->ss = NULL;
return 2;
}
if (!get_dev_size(fd, devname, &dsize))
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;
}
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;
if (devsize < 24)
return 0;
- /* if the device is bigger than 8Gig, save 64k for bitmap usage,
- * if bigger than 200Gig, save 128k
- */
- if (devsize-64*2 >= 200*1024*1024*2)
- devsize -= 128*2;
- else if (devsize >= 8*1024*1024*2)
- devsize -= 64*2;
+ 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));
* been left.
*/
offset = 0;
- if (__le64_to_cpu(sb->size) >= 200*1024*1024*2)
- room = 128*2;
- else if (__le64_to_cpu(sb->size) > 8*1024*1024*2)
- room = 64*2;
- else {
+ room = choose_bm_space(__le64_to_cpu(sb->size));
+ if (room == 4*2) {
+ /* make it 3K after the superblock */
room = 3*2;
offset = 2;
}
case 2: /* between superblock and data */
if (may_change) {
offset = 4*2;
- if (__le64_to_cpu(sb->size) >= 200*1024*1024*2)
- room = 128*2;
- else if (__le64_to_cpu(sb->size) > 8*1024*1024*2)
- room = 64*2;
- else
- room = 3*2;
+ room = choose_bm_space(__le64_to_cpu(sb->size));
} else {
room = __le64_to_cpu(sb->data_offset)
- __le64_to_cpu(sb->super_offset);
}
}
break;
+ default:
+ return 0;
}
if (chunk == UnSet && room > 128*2)
sb = sbv;
offset = __le64_to_cpu(sb->super_offset);
- offset += (long) __le32_to_cpu(sb->bitmap_offset);
+ offset += (int32_t) __le32_to_cpu(sb->bitmap_offset);
if (mustfree)
free(sb);
lseek64(fd, offset<<9, 0);
return rv;
}
+static void free_super1(void *super)
+{
+ if (super)
+ free(super);
+}
+
struct superswitch super1 = {
#ifndef MDASSEMBLE
.examine_super = examine_super1,
.brief_examine_super = brief_examine_super1,
.detail_super = detail_super1,
.brief_detail_super = brief_detail_super1,
+ .export_super = export_super1,
#endif
.match_home = match_home1,
.uuid_from_super = uuid_from_super1,
.add_internal_bitmap = add_internal_bitmap1,
.locate_bitmap = locate_bitmap1,
.write_bitmap = write_bitmap1,
+ .free_super = free_super1,
.major = 1,
#if __BYTE_ORDER == BIG_ENDIAN
.swapuuid = 0,