__u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
};
+/* feature_map bits */
+#define MD_FEATURE_BITMAP_OFFSET 1
+#define MD_FEATURE_RECOVERY_OFFSET 2 /* recovery_offset is present and
+ * must be honoured
+ */
+
+#define MD_FEATURE_ALL (1|2)
+
#ifndef offsetof
#define offsetof(t,f) ((int)&(((t*)0)->f))
#endif
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
printf("\n");
printf(" Device Size : %llu%s\n", (unsigned long long)sb->data_size, human_size(sb->data_size<<9));
+ if (sb->size != sb->data_size)
+ printf(" Used Size : %llu%s\n", (unsigned long long)sb->size, human_size(sb->size<<9));
if (sb->data_offset)
printf(" Data Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->data_offset));
if (sb->super_offset)
printf(" Super Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->super_offset));
+ if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_RECOVERY_OFFSET)
+ printf("Recovery Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->recovery_offset));
printf(" State : %s\n", (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean");
printf(" Device UUID : ");
for (i=0; i<16; i++) {
case 0:
case 4:
case 5:
+ case 6:
+ case 10:
printf(" Chunk Size : %dK\n", __le32_to_cpu(sb->chunksize/2));
break;
case -1:
/* make sure resync happens */
sb->resync_offset = ~0ULL;
}
+ if (strcmp(update, "uuid") == 0)
+ memcpy(sb->set_uuid, info->uuid, 16);
sb->sb_csum = calc_sb_1_csum(sb);
return rv;
return __le64_to_cpu(sb->events);
}
-static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, char *name)
+static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name)
{
struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t));
int spares;
sb->ctime = __cpu_to_le64((unsigned long long)time(0));
sb->level = __cpu_to_le32(info->level);
sb->layout = __cpu_to_le32(info->layout);
- sb->size = __cpu_to_le64(info->size*2ULL);
+ sb->size = __cpu_to_le64(size*2ULL);
sb->chunksize = __cpu_to_le32(info->chunk_size>>9);
sb->raid_disks = __cpu_to_le32(info->raid_disks);
struct mdp_superblock_1 *sb = sbv;
unsigned long long sb_offset;
int sbsize;
- long size;
-
- if (ioctl(fd, BLKGETSIZE, &size))
- return 1;
+ 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 (size < 24)
+ if (dsize < 24)
return 2;
/*
*/
switch(st->minor_version) {
case 0:
- sb_offset = size;
+ sb_offset = dsize;
sb_offset -= 8*2;
sb_offset &= ~(4*2-1);
break;
int rfd;
int rv;
- long size;
+ unsigned long size;
+ unsigned long long dsize;
long long sb_offset;
free(refsb);
}
- if (ioctl(fd, BLKGETSIZE, &size)) {
- close(fd);
- return 1;
- }
+#ifdef BLKGETSIZE64
+ if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
+#endif
+ {
+ if (ioctl(fd, BLKGETSIZE, &size))
+ return 1;
+ else
+ dsize = size;
+ } else
+ dsize >>= 9;
- if (size < 24) {
+ if (dsize < 24) {
close(fd);
return 2;
}
*/
switch(st->minor_version) {
case 0:
- sb_offset = size;
+ sb_offset = dsize;
sb_offset -= 8*2;
sb_offset &= ~(4*2-1);
sb->super_offset = __cpu_to_le64(sb_offset);
case 1:
sb->super_offset = __cpu_to_le64(0);
sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */
- sb->data_size = __cpu_to_le64(size - 4*2);
+ sb->data_size = __cpu_to_le64(dsize - 4*2);
break;
case 2:
sb_offset = 4*2;
sb->super_offset = __cpu_to_le64(sb_offset);
sb->data_offset = __cpu_to_le64(sb_offset+4*2);
- sb->data_size = __cpu_to_le64(size - 4*2 - 4*2);
+ sb->data_size = __cpu_to_le64(dsize - 4*2 - 4*2);
break;
default:
return -EINVAL;
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;
}
- if (ioctl(fd, BLKGETSIZE, &size)) {
- if (devname)
- fprintf(stderr, Name ": cannot find device size for %s: %s\n",
- devname, strerror(errno));
- return 1;
- }
+#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 (size < 24) {
+ if (dsize < 24) {
if (devname)
- fprintf(stderr, Name ": %s is too small for md: size is %lu sectors.\n",
- devname, size);
+ fprintf(stderr, Name ": %s is too small for md: size is %llu sectors.\n",
+ devname, dsize);
return 1;
}
*/
switch(st->minor_version) {
case 0:
- sb_offset = size;
+ sb_offset = dsize;
sb_offset -= 8*2;
sb_offset &= ~(4*2-1);
break;
static int
add_internal_bitmap1(struct supertype *st, void *sbv,
- int chunk, int delay, int write_behind, int *sizep, int may_change)
+ int chunk, int delay, int write_behind, unsigned long long size, int may_change, int major)
{
/*
* If not may_change, then this is a 'Grow', and the bitmap
* before the superblock if we like, or may move the start.
* For now, just squeeze the bitmap into 3k and don't change anything.
*
- * size is in K, chunk is in bytes !!!
+ * size is in sectors, chunk is in bytes !!!
*/
- unsigned long long size = *sizep;
unsigned long long bits;
unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8;
unsigned long long min_chunk;
min_chunk = 4096; /* sub-page chunks don't work yet.. */
- bits = (size*1024)/min_chunk +1;
+ bits = (size*512)/min_chunk +1;
while (bits > max_bits) {
min_chunk *= 2;
bits = (bits+1)/2;
sb->bitmap_offset = __cpu_to_le32(2);
sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | 1);
- memset(bms, sizeof(*bms), 0);
+ memset(bms, 0, sizeof(*bms));
bms->magic = __cpu_to_le32(BITMAP_MAGIC);
- bms->version = __cpu_to_le32(BITMAP_MAJOR);
+ bms->version = __cpu_to_le32(major);
uuid_from_super1((int*)bms->uuid, sb);
bms->chunksize = __cpu_to_le32(chunk);
bms->daemon_sleep = __cpu_to_le32(delay);
- bms->sync_size = __cpu_to_le64(size<<1);
+ bms->sync_size = __cpu_to_le64(size);
bms->write_behind = __cpu_to_le32(write_behind);
return 1;