c = map_num(r5layout, __le32_to_cpu(sb->layout));
printf(" Layout : %s\n", c?c:"-unknown-");
}
+ if (__le32_to_cpu(sb->level) == 10) {
+ int lo = __le32_to_cpu(sb->layout);
+ printf(" Layout : near=%d, far=%d\n",
+ lo&255, (lo>>8)&255);
+ }
switch(__le32_to_cpu(sb->level)) {
case 0:
case 4:
info->array.patch_version = 0;
info->array.raid_disks = __le32_to_cpu(sb->raid_disks);
info->array.level = __le32_to_cpu(sb->level);
+ info->array.layout = __le32_to_cpu(sb->layout);
info->array.md_minor = -1;
info->array.ctime = __le64_to_cpu(sb->ctime);
struct mdp_superblock_1 *sb = sbv;
if (strcmp(update, "force")==0) {
- sb->events = __cpu_to_le32(info->events);
+ sb->events = __cpu_to_le64(info->events);
switch(__le32_to_cpu(sb->level)) {
case 5: case 4: case 6:
/* need to force clean */
static int load_super1(struct supertype *st, int fd, void **sbp, char *devname);
static int write_init_super1(struct supertype *st, void *sbv,
- mdu_disk_info_t *dinfo, char *devname,
- int reserve)
+ mdu_disk_info_t *dinfo, char *devname)
{
struct mdp_superblock_1 *sb = sbv;
- struct mdp_superblock_1 *refsb = NULL;
+ void *refsbv = NULL;
int fd = open(devname, O_RDWR | O_EXCL);
int rfd;
int rv;
if (rfd >= 0) close(rfd);
sb->events = 0;
- if (load_super1(st, fd, (void**)&refsb, NULL)==0) {
+ if (load_super1(st, fd, &refsbv, NULL)==0) {
+ struct mdp_superblock_1 *refsb = refsbv;
+
memcpy(sb->device_uuid, refsb->device_uuid, 16);
if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) {
/* same array, so preserve events and dev_number */
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 - reserve);
+ sb->data_size = __cpu_to_le64(sb_offset);
break;
case 1:
sb->super_offset = __cpu_to_le64(0);
- sb->data_offset = __cpu_to_le64(2 + reserve);
- sb->data_size = __cpu_to_le64(size - 2 - reserve);
+ sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */
+ sb->data_size = __cpu_to_le64(size - 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+2 + reserve);
- sb->data_size = __cpu_to_le64(size - 4*2 - 2 - reserve);
+ sb->data_offset = __cpu_to_le64(sb_offset+4*2);
+ sb->data_size = __cpu_to_le64(size - 4*2 - 4*2);
break;
default:
return -EINVAL;
if (rv)
fprintf(stderr, Name ": failed to write superblock to %s\n", devname);
- if (__le32_to_cpu(sb->feature_map) & 1) {
- /* write the bitmap */
- int towrite, n;
- char buf[4096];
-
- st->ss->locate_bitmap(st, fd);
- write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t));
- towrite = 62*1024;
- memset(buf, 0xff, sizeof(buf));
- while (towrite > 0) {
- n=towrite;
- if (n > sizeof(buf))
- n = sizeof(buf);
- n = write(fd, buf, n);
- if (n > 0)
- towrite -= n;
- else
- break;
- }
- if (towrite)
- rv = -2;
- }
- fsync(fd);
+ if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
+ rv = st->ss->write_bitmap(st, fd, sbv);
close(fd);
return rv;
}
* superblock type st, and reserving 'reserve' sectors for
* a possible bitmap
*/
-static __u64 avail_size1(struct supertype *st, __u64 devsize, int reserve)
+static __u64 avail_size1(struct supertype *st, __u64 devsize)
{
if (devsize < 24)
return 0;
switch(st->minor_version) {
case 0:
- /* at end, with reserve before it */
- return ((devsize - 8*2 ) & ~(4*2-1)) - reserve;
+ /* at end */
+ return ((devsize - 8*2 ) & ~(4*2-1));
case 1:
- /* at start, 1K for superblock */
- return devsize - 2 - reserve;
+ /* at start, 4K for superblock and possible bitmap */
+ return devsize - 4*2;
case 2:
- /* 4k from start, 1K for superblock */
- return devsize - (4+1)*2 - reserve;
+ /* 4k from start, 4K for superblock and possible bitmap */
+ return devsize - (4+4)*2;
}
return 0;
}
-static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size)
+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)
{
/*
- * The bitmap comes immediately before of after the superblock and must be 62K in size
- * at most. The default size is between 31K and 62K
+ * If not may_change, then this is a 'Grow', and the bitmap
+ * must fit after the superblock.
+ * If may_change, then this is create, and we can put 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 bits = size;
- unsigned long long max_bits = 62*1024*8;
+ unsigned long long bits;
+ unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8;
unsigned long long min_chunk;
struct mdp_superblock_1 *sb = sbv;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + 1024);
+ if (st->minor_version && !may_change &&
+ __le64_to_cpu(sb->data_offset) - __le64_to_cpu(sb->super_offset) < 8)
+ return 0; /* doesn't fit */
+
+
min_chunk = 4096; /* sub-page chunks don't work yet.. */
+ bits = (size*512)/min_chunk +1;
while (bits > max_bits) {
min_chunk *= 2;
bits = (bits+1)/2;
else if (chunk < min_chunk)
return 0; /* chunk size too small */
- if (st->minor_version == 0)
- sb->bitmap_offset = __cpu_to_le32(-64*2);
- else
- sb->bitmap_offset = __cpu_to_le32(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);
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);
bms->write_behind = __cpu_to_le32(write_behind);
-
-
return 1;
}
-void locate_bitmap1(struct supertype *st, int fd)
+void locate_bitmap1(struct supertype *st, int fd, void *sbv)
{
- unsigned long long dsize;
- unsigned long size;
unsigned long long offset;
+ struct mdp_superblock_1 *sb;
- switch(st->minor_version){
- case 0:
-#ifdef BLKGETSIZE64
- if (ioctl(fd, BLKGETSIZE64, &dsize) != 0)
-#endif
- {
- if (ioctl(fd, BLKGETSIZE, &size))
- return;
- else
- dsize = ((unsigned long long)size)<<9;
- }
-
- offset = (dsize - 8192) & ~4095ULL;
+ if (!sbv)
+ if (st->ss->load_super(st, fd, sbv, NULL))
+ return; /* no error I hope... */
- offset -= 65536;
- break;
+ sb = sbv;
- case 1:
- offset = 1024;
- break;
- case 2:
- offset = 4096+1024;
- }
- lseek64(fd, offset, 0);
+ offset = __le64_to_cpu(sb->super_offset);
+ offset += (long) __le32_to_cpu(sb->bitmap_offset);
+ if (!sbv)
+ free(sb);
+ lseek64(fd, offset<<9, 0);
}
int write_bitmap1(struct supertype *st, int fd, void *sbv)
{
struct mdp_superblock_1 *sb = sbv;
-
+ bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+1024);
int rv = 0;
int towrite, n;
char buf[4096];
- locate_bitmap1(st, fd);
+ locate_bitmap1(st, fd, sbv);
write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t));
- towrite = 62*1024 - sizeof(bitmap_super_t);
+ 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));
while (towrite > 0) {
n = towrite;