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));
+ (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)) {
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,
}
}
+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)
info->array.ctime = __le64_to_cpu(sb->ctime);
info->array.utime = __le64_to_cpu(sb->utime);
info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512;
- info->array.state = (__le64_to_cpu(sb->resync_offset)+1) ? 0 : 1;
+ info->array.state =
+ (__le64_to_cpu(sb->resync_offset) >= __le64_to_cpu(sb->size))
+ ? 1 : 0;
info->data_offset = __le64_to_cpu(sb->data_offset);
info->component_size = __le64_to_cpu(sb->size);
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 */
sb->resync_offset = 0ULL;
}
if (strcmp(update, "uuid") == 0) {
- memcpy(sb->set_uuid, info->uuid, 16);
+ copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid);
+
if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
struct bitmap_super_s *bm;
bm = (struct bitmap_super_s*)(sbv+1024);
- memcpy(bm->uuid, info->uuid, 16);
+ memcpy(bm->uuid, sb->set_uuid, 16);
}
}
if (strcmp(update, "homehost") == 0 &&
/* 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 init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
- unsigned long long size, char *name, char *homehost)
+ unsigned long long size, char *name, char *homehost, int *uuid)
{
struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t) +
sizeof(struct misc_dev_info));
sb->feature_map = 0;
sb->pad0 = 0;
- if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
- read(rfd, sb->set_uuid, 16) != 16) {
- *(__u32*)(sb->set_uuid) = random();
- *(__u32*)(sb->set_uuid+4) = random();
- *(__u32*)(sb->set_uuid+8) = random();
- *(__u32*)(sb->set_uuid+12) = random();
+ if (uuid)
+ copy_uuid(sb->set_uuid, uuid, super1.swapuuid);
+ else {
+ if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
+ read(rfd, sb->set_uuid, 16) != 16) {
+ *(__u32*)(sb->set_uuid) = random();
+ *(__u32*)(sb->set_uuid+4) = random();
+ *(__u32*)(sb->set_uuid+8) = random();
+ *(__u32*)(sb->set_uuid+12) = random();
+ }
+ if (rfd >= 0) close(rfd);
}
- if (rfd >= 0) close(rfd);
if (name == NULL || *name == 0) {
sprintf(defname, "%d", info->md_minor);
struct mdp_superblock_1 *sb = sbv;
unsigned long long sb_offset;
int sbsize;
- unsigned long size;
unsigned long long dsize;
-#ifdef BLKGETSIZE64
- if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
-#endif
- {
- if (ioctl(fd, BLKGETSIZE, &size))
- return 1;
- else
- dsize = (unsigned long long)size;
- } else
- dsize >>= 9;
+ if (!get_dev_size(fd, NULL, &dsize))
+ return 1;
+
+ dsize >>= 9;
if (dsize < 24)
return 2;
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;
free(refsb);
}
-#ifdef BLKGETSIZE64
- if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
-#endif
- {
- unsigned long size;
- if (ioctl(fd, BLKGETSIZE, &size))
- return 1;
- else
- dsize = size;
- } else
- dsize >>= 9;
+ if (!get_dev_size(fd, NULL, &dsize))
+ return 1;
+ dsize >>= 9;
if (dsize < 24) {
close(fd);
*/
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 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);
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 );
static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
{
- unsigned long size;
unsigned long long dsize;
unsigned long long sb_offset;
struct mdp_superblock_1 *super;
st->ss = NULL;
return 2;
}
-#ifdef BLKGETSIZE64
- if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
-#endif
- {
- if (ioctl(fd, BLKGETSIZE, &size)) {
- if (devname)
- fprintf(stderr, Name ": cannot find device size for %s: %s\n",
- devname, strerror(errno));
- return 1;
- }
- dsize = size;
- } else
- dsize >>= 9;
+ if (!get_dev_size(fd, devname, &dsize))
+ return 1;
+ dsize >>= 9;
if (dsize < 24) {
if (devname)
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 0:
* 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);
.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,