*/
#include "mdadm.h"
-#include <endian.h>
-#include "asm/byteorder.h"
/*
* The version-1 superblock :
* All numeric fields are little-endian.
char *c;
printf(" Magic : %08x\n", __le32_to_cpu(sb->magic));
- printf(" Version : %02d.%02d\n", 1, __le32_to_cpu(sb->feature_map));
+ printf(" Version : %02d\n", 1);
+ printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map));
printf(" Array UUID : ");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0) printf(":");
}
printf("\n");
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));
+ }
if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) {
- printf(" Reshape pos'n : %llu%s\n", __le64_to_cpu(sb->reshape_position)/2,
+ printf(" Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2,
human_size(__le64_to_cpu(sb->reshape_position)<<9));
if (__le32_to_cpu(sb->delta_disks)) {
printf(" Delta Devices : %d", __le32_to_cpu(sb->delta_disks));
cuuid[i] = super->set_uuid[i];
}
-static void getinfo_super1(struct mdinfo *info, mddev_ident_t ident, void *sbv)
+static void getinfo_super1(struct mdinfo *info, void *sbv)
{
struct mdp_superblock_1 *sb = sbv;
int working = 0;
info->array.layout = __le32_to_cpu(sb->layout);
info->array.md_minor = -1;
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->data_offset = __le64_to_cpu(sb->data_offset);
+ info->component_size = __le64_to_cpu(sb->size);
info->disk.major = 0;
info->disk.minor = 0;
memcpy(info->uuid, sb->set_uuid, 16);
- strncpy(ident->name, sb->set_name, 32);
- ident->name[32] = 0;
+ strncpy(info->name, sb->set_name, 32);
+ info->name[32] = 0;
+
+ if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) {
+ info->reshape_active = 1;
+ info->reshape_progress = __le64_to_cpu(sb->reshape_position);
+ info->new_level = __le32_to_cpu(sb->new_level);
+ info->delta_disks = __le32_to_cpu(sb->delta_disks);
+ info->new_layout = __le32_to_cpu(sb->new_layout);
+ info->new_chunk = __le32_to_cpu(sb->new_chunk)<<9;
+ } else
+ info->reshape_active = 0;
for (i=0; i< __le32_to_cpu(sb->max_dev); i++) {
role = __le16_to_cpu(sb->dev_roles[i]);
}
if (strcmp(update, "uuid") == 0)
memcpy(sb->set_uuid, info->uuid, 16);
+ if (strcmp(update, "_reshape_progress")==0)
+ sb->reshape_position = __cpu_to_le64(info->reshape_progress);
sb->sb_csum = calc_sb_1_csum(sb);
return rv;
int rfd;
int rv;
- unsigned long size;
- unsigned long long dsize;
+ unsigned long size, space;
+ unsigned long long dsize, array_size;
long long sb_offset;
* 0: At least 8K, but less than 12K, from end of device
* 1: At start of device
* 2: 4K from start of device.
+ * Depending on the array size, we might leave extra space
+ * for a bitmap.
*/
+ array_size = __le64_to_cpu(sb->size);
switch(st->minor_version) {
case 0:
sb_offset = dsize;
sb_offset &= ~(4*2-1);
sb->super_offset = __cpu_to_le64(sb_offset);
sb->data_offset = __cpu_to_le64(0);
- sb->data_size = __cpu_to_le64(sb_offset);
+ if (sb_offset-64*2 >= array_size && array_size > 8*1024*1024*2)
+ sb->data_size = __cpu_to_le64(sb_offset-64*2);
+ else
+ sb->data_size = __cpu_to_le64(sb_offset);
break;
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(dsize - 4*2);
+ if (dsize - 64*2 >= array_size && array_size > 8*1024*1024*2)
+ space = 64*2;
+ else
+ space = 4*2;
+ sb->data_offset = __cpu_to_le64(space); /* leave space for super and bitmap */
+ sb->data_size = __cpu_to_le64(dsize - space);
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(sb_offset);
- sb->data_offset = __cpu_to_le64(sb_offset+4*2);
- sb->data_size = __cpu_to_le64(dsize - 4*2 - 4*2);
+ sb->data_offset = __cpu_to_le64(sb_offset+space);
+ sb->data_size = __cpu_to_le64(dsize - 4*2 - space);
break;
default:
return -EINVAL;
st->ss = &super1;
st->max_devs = 384;
if (strcmp(arg, "1") == 0 ||
- strcmp(arg, "1.0") == 0) {
+ strcmp(arg, "1.0") == 0 ||
+ strcmp(arg, "default/large") == 0) {
st->minor_version = 0;
return st;
}
if (devsize < 24)
return 0;
+ /* if the device is bigger than 8Gig, save 64k for bitmap usage,
+ * if biffer than 200Gig, save 128k
+ */
+ if (devsize > 200*1024*1024*2)
+ devsize -= 128*2;
+ else if (devsize > 8*1024*1024*2)
+ devsize -= 64*2;
+
switch(st->minor_version) {
case 0:
/* at end */
static int
add_internal_bitmap1(struct supertype *st, void *sbv,
- int chunk, int delay, int write_behind, unsigned long long size, int may_change, int major)
+ 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
chunk = min_chunk;
else if (chunk < min_chunk)
return 0; /* chunk size too small */
+ if (chunk == 0) /* rounding problem */
+ return 0;
sb->bitmap_offset = __cpu_to_le32(2);
{
unsigned long long offset;
struct mdp_superblock_1 *sb;
+ int mustfree = 0;
- if (!sbv)
- if (st->ss->load_super(st, fd, sbv, NULL))
+ if (!sbv) {
+ if (st->ss->load_super(st, fd, &sbv, NULL))
return; /* no error I hope... */
-
+ mustfree = 1;
+ }
sb = sbv;
offset = __le64_to_cpu(sb->super_offset);
offset += (long) __le32_to_cpu(sb->bitmap_offset);
- if (!sbv)
+ if (mustfree)
free(sb);
lseek64(fd, offset<<9, 0);
}
locate_bitmap1(st, fd, sbv);
- write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t));
+ if (write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)) !=
+ sizeof(bitmap_super_t))
+ return -2;
towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
towrite = (towrite+7) >> 3; /* bits to bytes */
memset(buf, 0xff, sizeof(buf));