Support internal bitmaps with format-1 superblocks.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
Neil Brown 2005-08-25 04:31:44 +00:00
parent eb3b43aa2a
commit 34163fc7cf
9 changed files with 236 additions and 43 deletions

View File

@ -210,7 +210,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
ldsize = dsize; ldsize = dsize;
ldsize <<= 9; ldsize <<= 9;
} }
freesize = st->ss->avail_size(ldsize >> 9); freesize = st->ss->avail_size(st, ldsize >> 9, 64*2);
if (freesize == 0) { if (freesize == 0) {
fprintf(stderr, Name ": %s is too small: %luK\n", fprintf(stderr, Name ": %s is too small: %luK\n",
dname, (unsigned long)(ldsize>>10)); dname, (unsigned long)(ldsize>>10));
@ -355,7 +355,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n"); fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
return 1; return 1;
} }
if (!st->ss->add_internal_bitmap(super, bitmap_chunk, delay, write_behind, if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
size ? size : maxsize)) { size ? size : maxsize)) {
fprintf(stderr, Name ": Given bitmap chunk size not supported.\n"); fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
return 1; return 1;
@ -451,7 +451,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
break; break;
case 2: case 2:
if (disk.state == 1) break; if (disk.state == 1) break;
st->ss->write_init_super(st, super, &disk, dv->devname); st->ss->write_init_super(st, super, &disk, dv->devname, 64*2);
if (ioctl(mdfd, ADD_NEW_DISK, &disk)) { if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n", fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",

2
Grow.c
View File

@ -273,7 +273,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
if (fd2 < 0) if (fd2 < 0)
continue; continue;
if (st->ss->load_super(st, fd2, &super, NULL)==0) { if (st->ss->load_super(st, fd2, &super, NULL)==0) {
st->ss->add_internal_bitmap(super, st->ss->add_internal_bitmap(st, super,
chunk, delay, write_behind, chunk, delay, write_behind,
array.size); array.size);
st->ss->write_bitmap(st, fd2, super); st->ss->write_bitmap(st, fd2, super);

View File

@ -311,7 +311,7 @@ int Manage_subdevs(char *devname, int fd,
if (dv->writemostly) if (dv->writemostly)
disc.state |= 1 << MD_DISK_WRITEMOSTLY; disc.state |= 1 << MD_DISK_WRITEMOSTLY;
st->ss->add_to_super(dsuper, &disc); st->ss->add_to_super(dsuper, &disc);
if (st->ss->write_init_super(st, dsuper, &disc, dv->devname)) if (st->ss->write_init_super(st, dsuper, &disc, dv->devname, 0 /* FIXME */))
return 1; return 1;
} else if (dv->re_add) { } else if (dv->re_add) {
/* this had better be raid1. /* this had better be raid1.

View File

@ -177,11 +177,12 @@ out:
return info; return info;
} }
bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype *st) bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype **stp)
{ {
int fd; int fd;
bitmap_info_t *info; bitmap_info_t *info;
struct stat stb; struct stat stb;
struct supertype *st = *stp;
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) { if (fd < 0) {
@ -199,6 +200,8 @@ bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype *st)
} else { } else {
st->ss->locate_bitmap(st, fd); st->ss->locate_bitmap(st, fd);
} }
ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */
*stp = st;
} }
info = bitmap_fd_read(fd, brief); info = bitmap_fd_read(fd, brief);
@ -206,6 +209,18 @@ bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype *st)
return info; return info;
} }
__u32 swapl(__u32 l)
{
char *c = (char*)&l;
char t= c[0];
c[0] = c[3];
c[3] = t;
t = c[1];
c[1] = c[2];
c[2] = t;
return l;
}
int ExamineBitmap(char *filename, int brief, struct supertype *st) int ExamineBitmap(char *filename, int brief, struct supertype *st)
{ {
/* /*
@ -217,7 +232,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
int rv = 1; int rv = 1;
char buf[64]; char buf[64];
info = bitmap_file_read(filename, brief, st); info = bitmap_file_read(filename, brief, &st);
if (!info) if (!info)
return rv; return rv;
@ -234,11 +249,19 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
} }
rv = 0; rv = 0;
if (st && st->ss->swapuuid) {
printf(" UUID : %08x.%08x.%08x.%08x\n",
swapl(*(__u32 *)(sb->uuid+0)),
swapl(*(__u32 *)(sb->uuid+4)),
swapl(*(__u32 *)(sb->uuid+8)),
swapl(*(__u32 *)(sb->uuid+12)));
} else {
printf(" UUID : %08x.%08x.%08x.%08x\n", printf(" UUID : %08x.%08x.%08x.%08x\n",
*(__u32 *)(sb->uuid+0), *(__u32 *)(sb->uuid+0),
*(__u32 *)(sb->uuid+4), *(__u32 *)(sb->uuid+4),
*(__u32 *)(sb->uuid+8), *(__u32 *)(sb->uuid+8),
*(__u32 *)(sb->uuid+12)); *(__u32 *)(sb->uuid+12));
}
printf(" Events : %llu\n", sb->events); printf(" Events : %llu\n", sb->events);
printf(" Events Cleared : %llu\n", sb->events_cleared); printf(" Events Cleared : %llu\n", sb->events_cleared);
printf(" State : %s\n", bitmap_state(sb->state)); printf(" State : %s\n", bitmap_state(sb->state));

View File

@ -185,12 +185,12 @@ extern struct superswitch {
int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, char *name); int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, char *name);
void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo); void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo);
int (*store_super)(struct supertype *st, int fd, void *sbv); int (*store_super)(struct supertype *st, int fd, void *sbv);
int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname); int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname, int reserve);
int (*compare_super)(void **firstp, void *secondv); int (*compare_super)(void **firstp, void *secondv);
int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname); int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname);
struct supertype * (*match_metadata_desc)(char *arg); struct supertype * (*match_metadata_desc)(char *arg);
__u64 (*avail_size)(__u64 size); __u64 (*avail_size)(struct supertype *st, __u64 size, int reserve);
int (*add_internal_bitmap)(void *sbv, int chunk, int delay, int write_behind, unsigned long long size); int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size);
void (*locate_bitmap)(struct supertype *st, int fd); void (*locate_bitmap)(struct supertype *st, int fd);
int (*write_bitmap)(struct supertype *st, int fd, void *sbv); int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
int major; int major;

View File

@ -472,7 +472,7 @@ static int store_super0(struct supertype *st, int fd, void *sbv)
return 0; return 0;
} }
static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname) static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname, int reserve)
{ {
mdp_super_t *sb = sbv; mdp_super_t *sb = sbv;
int fd = open(devname, O_RDWR|O_EXCL); int fd = open(devname, O_RDWR|O_EXCL);
@ -664,14 +664,15 @@ static struct supertype *match_metadata_desc0(char *arg)
return NULL; return NULL;
} }
static __u64 avail_size0(__u64 devsize) static __u64 avail_size0(struct supertype *st, __u64 devsize, int reserve)
{ {
if (devsize < MD_RESERVED_SECTORS*2) if (devsize < MD_RESERVED_SECTORS*2)
return 0ULL; return 0ULL;
if (reserve > 64*2) return 0ULL;
return MD_NEW_SIZE_SECTORS(devsize); return MD_NEW_SIZE_SECTORS(devsize);
} }
static int add_internal_bitmap0(void *sbv, int chunk, int delay, int write_behind, unsigned long long size) static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size)
{ {
/* /*
* The bitmap comes immediately after the superblock and must be 60K in size * The bitmap comes immediately after the superblock and must be 60K in size

216
super1.c
View File

@ -54,7 +54,11 @@ struct mdp_superblock_1 {
__u32 chunksize; /* in 512byte sectors */ __u32 chunksize; /* in 512byte sectors */
__u32 raid_disks; __u32 raid_disks;
__u8 pad1[128-96]; /* set to 0 when written */ __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts
* NOTE: signed, so bitmap can be before superblock
* only meaningful of feature_map[0] is set.
*/
__u8 pad1[128-100]; /* set to 0 when written */
/* constant this-device information - 64 bytes */ /* constant this-device information - 64 bytes */
__u64 data_offset; /* sector start of data, often 0 */ __u64 data_offset; /* sector start of data, often 0 */
@ -131,8 +135,8 @@ static void examine_super1(void *sbv)
printf(" Version : %02d.%02d\n", 1, __le32_to_cpu(sb->feature_map)); printf(" Version : %02d.%02d\n", 1, __le32_to_cpu(sb->feature_map));
printf(" Array UUID : "); printf(" Array UUID : ");
for (i=0; i<16; i++) { for (i=0; i<16; i++) {
printf("%02x", sb->set_uuid[i]);
if ((i&3)==0 && i != 0) printf(":"); if ((i&3)==0 && i != 0) printf(":");
printf("%02x", sb->set_uuid[i]);
} }
printf("\n"); printf("\n");
printf(" Name : %.32s\n", sb->set_name); printf(" Name : %.32s\n", sb->set_name);
@ -151,13 +155,13 @@ static void examine_super1(void *sbv)
printf(" State : %s\n", (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean"); printf(" State : %s\n", (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean");
printf(" Device UUID : "); printf(" Device UUID : ");
for (i=0; i<16; i++) { for (i=0; i<16; i++) {
printf("%02x", sb->set_uuid[i]);
if ((i&3)==0 && i != 0) printf(":"); if ((i&3)==0 && i != 0) printf(":");
printf("%02x", sb->device_uuid[i]);
} }
printf("\n"); printf("\n");
if (sb->devflags) { if (sb->devflags) {
printf(" Flags :"); printf(" Flags :");
if (sb->devflags & WriteMostly1) if (sb->devflags & WriteMostly1)
printf(" write-mostly"); printf(" write-mostly");
printf("\n"); printf("\n");
} }
@ -243,8 +247,8 @@ static void detail_super1(void *sbv)
printf(" Name : %.32s\n", sb->set_name); printf(" Name : %.32s\n", sb->set_name);
printf(" UUID : "); printf(" UUID : ");
for (i=0; i<16; i++) { for (i=0; i<16; i++) {
printf("%02x", sb->set_uuid[i]);
if ((i&3)==0 && i != 0) printf(":"); if ((i&3)==0 && i != 0) printf(":");
printf("%02x", sb->set_uuid[i]);
} }
printf("\n Events : %llu\n\n", (unsigned long long)__le64_to_cpu(sb->events)); printf("\n Events : %llu\n\n", (unsigned long long)__le64_to_cpu(sb->events));
} }
@ -258,8 +262,8 @@ static void brief_detail_super1(void *sbv)
printf(" name=%.32s", sb->set_name); printf(" name=%.32s", sb->set_name);
printf(" UUID="); printf(" UUID=");
for (i=0; i<16; i++) { for (i=0; i<16; i++) {
printf("%02x", sb->set_uuid[i]);
if ((i&3)==0 && i != 0) printf(":"); if ((i&3)==0 && i != 0) printf(":");
printf("%02x", sb->set_uuid[i]);
} }
} }
@ -385,8 +389,9 @@ static __u64 event_super1(void *sbv)
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, char *name)
{ {
struct mdp_superblock_1 *sb = malloc(1024); struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t));
int spares; int spares;
int rfd;
memset(sb, 0, 1024); memset(sb, 0, 1024);
if (info->major_version == -1) if (info->major_version == -1)
@ -405,10 +410,15 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
sb->major_version = __cpu_to_le32(1); sb->major_version = __cpu_to_le32(1);
sb->feature_map = 0; sb->feature_map = 0;
sb->pad0 = 0; sb->pad0 = 0;
*(__u32*)(sb->set_uuid) = random();
*(__u32*)(sb->set_uuid+4) = random(); if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
*(__u32*)(sb->set_uuid+8) = random(); read(rfd, sb->set_uuid, 16) != 16) {
*(__u32*)(sb->set_uuid+12) = random(); *(__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);
memset(sb->set_name, 0, 32); memset(sb->set_name, 0, 32);
strcpy(sb->set_name, name); strcpy(sb->set_name, name);
@ -431,7 +441,7 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
sb->resync_offset = ~0ULL; sb->resync_offset = ~0ULL;
else else
sb->resync_offset = 0; sb->resync_offset = 0;
sb->max_dev = __cpu_to_le32((1024- sizeof(struct mdp_superblock_1))/ sb->max_dev = __cpu_to_le32((1024- sizeof(struct mdp_superblock_1))/
sizeof(sb->dev_roles[0])); sizeof(sb->dev_roles[0]));
memset(sb->pad3, 0, sizeof(sb->pad3)); memset(sb->pad3, 0, sizeof(sb->pad3));
@ -450,7 +460,7 @@ static void add_to_super1(void *sbv, mdu_disk_info_t *dk)
*rp = __cpu_to_le16(dk->raid_disk); *rp = __cpu_to_le16(dk->raid_disk);
else if ((dk->state & ~2) == 0) /* active or idle -> spare */ else if ((dk->state & ~2) == 0) /* active or idle -> spare */
*rp = 0xffff; *rp = 0xffff;
else else
*rp = 0xfffe; *rp = 0xfffe;
} }
@ -493,7 +503,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
} }
if (sb_offset != __le64_to_cpu(sb->super_offset) && if (sb_offset != __le64_to_cpu(sb->super_offset) &&
0 != __le64_to_cpu(sb->super_offset) 0 != __le64_to_cpu(sb->super_offset)
) { ) {
@ -515,7 +525,9 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
static int load_super1(struct supertype *st, int fd, void **sbp, char *devname); 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) static int write_init_super1(struct supertype *st, void *sbv,
mdu_disk_info_t *dinfo, char *devname,
int reserve)
{ {
struct mdp_superblock_1 *sb = sbv; struct mdp_superblock_1 *sb = sbv;
struct mdp_superblock_1 *refsb = NULL; struct mdp_superblock_1 *refsb = NULL;
@ -534,7 +546,7 @@ static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *d
} }
sb->dev_number = __cpu_to_le32(dinfo->number); sb->dev_number = __cpu_to_le32(dinfo->number);
if (dinfo->state & (1<<MD_DISK_WRITEMOSTLY)) if (dinfo->state & (1<<MD_DISK_WRITEMOSTLY))
sb->devflags |= WriteMostly1; sb->devflags |= WriteMostly1;
if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 || if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
@ -556,7 +568,7 @@ static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *d
} }
free(refsb); free(refsb);
} }
if (ioctl(fd, BLKGETSIZE, &size)) { if (ioctl(fd, BLKGETSIZE, &size)) {
close(fd); close(fd);
return 1; return 1;
@ -583,18 +595,18 @@ static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *d
sb_offset &= ~(4*2-1); sb_offset &= ~(4*2-1);
sb->super_offset = __cpu_to_le64(sb_offset); sb->super_offset = __cpu_to_le64(sb_offset);
sb->data_offset = __cpu_to_le64(0); sb->data_offset = __cpu_to_le64(0);
sb->data_size = sb->super_offset; sb->data_size = __cpu_to_le64(sb_offset - reserve);
break; break;
case 1: case 1:
sb->super_offset = __cpu_to_le64(0); sb->super_offset = __cpu_to_le64(0);
sb->data_offset = __cpu_to_le64(2); sb->data_offset = __cpu_to_le64(2 + reserve);
sb->data_size = __cpu_to_le64(size - 2); sb->data_size = __cpu_to_le64(size - 2 - reserve);
break; break;
case 2: case 2:
sb_offset = 4*2; sb_offset = 4*2;
sb->super_offset = __cpu_to_le64(sb_offset); sb->super_offset = __cpu_to_le64(sb_offset);
sb->data_offset = __cpu_to_le64(sb_offset+2); sb->data_offset = __cpu_to_le64(sb_offset+2 + reserve);
sb->data_size = __cpu_to_le64(size - 4*2 - 2); sb->data_size = __cpu_to_le64(size - 4*2 - 2 - reserve);
break; break;
default: default:
return -EINVAL; return -EINVAL;
@ -605,6 +617,30 @@ static int write_init_super1(struct supertype *st, void *sbv, mdu_disk_info_t *d
rv = store_super1(st, fd, sb); rv = store_super1(st, fd, sb);
if (rv) if (rv)
fprintf(stderr, Name ": failed to write superblock to %s\n", devname); 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);
close(fd); close(fd);
return rv; return rv;
} }
@ -686,7 +722,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
return 2; return 2;
} }
if (ioctl(fd, BLKGETSIZE, &size)) { if (ioctl(fd, BLKGETSIZE, &size)) {
if (devname) if (devname)
fprintf(stderr, Name ": cannot find device size for %s: %s\n", fprintf(stderr, Name ": cannot find device size for %s: %s\n",
devname, strerror(errno)); devname, strerror(errno));
return 1; return 1;
@ -733,7 +769,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
return 1; return 1;
} }
super = malloc(1024); super = malloc(1024 + sizeof(bitmap_super_t));
if (read(fd, super, 1024) != 1024) { if (read(fd, super, 1024) != 1024) {
if (devname) if (devname)
@ -795,12 +831,137 @@ static struct supertype *match_metadata_desc1(char *arg)
return NULL; return NULL;
} }
static __u64 avail_size1(__u64 devsize) /* find available size on device with this devsize, using
* superblock type st, and reserving 'reserve' sectors for
* a possible bitmap
*/
static __u64 avail_size1(struct supertype *st, __u64 devsize, int reserve)
{ {
if (devsize < 24) if (devsize < 24)
return 0; return 0;
return (devsize - 8*2 ) & ~(4*2-1); switch(st->minor_version) {
case 0:
/* at end, with reserve before it */
return ((devsize - 8*2 ) & ~(4*2-1)) - reserve;
case 1:
/* at start, 1K for superblock */
return devsize - 2 - reserve;
case 2:
/* 4k from start, 1K for superblock */
return devsize - (4+1)*2 - reserve;
}
return 0;
}
static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size)
{
/*
* 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
*
* size is in K, chunk is in bytes !!!
*/
unsigned long long bits = size;
unsigned long long max_bits = 62*1024*8;
unsigned long long min_chunk;
struct mdp_superblock_1 *sb = sbv;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + 1024);
min_chunk = 4096; /* sub-page chunks don't work yet.. */
while (bits > max_bits) {
min_chunk *= 2;
bits = (bits+1)/2;
}
if (chunk == UnSet)
chunk = min_chunk;
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->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);
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)
{
unsigned long long dsize;
unsigned long size;
unsigned long long offset;
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;
offset -= 65536;
break;
case 1:
offset = 1024;
break;
case 2:
offset = 4096+1024;
}
lseek64(fd, offset, 0);
}
int write_bitmap1(struct supertype *st, int fd, void *sbv)
{
struct mdp_superblock_1 *sb = sbv;
int rv = 0;
int towrite, n;
char buf[4096];
locate_bitmap1(st, fd);
write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t));
towrite = 62*1024 - sizeof(bitmap_super_t);
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;
}
fsync(fd);
if (towrite)
rv = -2;
return rv;
} }
struct superswitch super1 = { struct superswitch super1 = {
@ -822,6 +983,9 @@ struct superswitch super1 = {
.load_super = load_super1, .load_super = load_super1,
.match_metadata_desc = match_metadata_desc1, .match_metadata_desc = match_metadata_desc1,
.avail_size = avail_size1, .avail_size = avail_size1,
.add_internal_bitmap = add_internal_bitmap1,
.locate_bitmap = locate_bitmap1,
.write_bitmap = write_bitmap1,
.major = 1, .major = 1,
#if __BYTE_ORDER == BIG_ENDIAN #if __BYTE_ORDER == BIG_ENDIAN
.swapuuid = 0, .swapuuid = 0,

11
test
View File

@ -27,7 +27,9 @@ md0=/dev/md0 md1=/dev/md1 md2=/dev/md2
targetdir=/tmp targetdir=/tmp
size=20000 size=20000
mdsize0=19904 mdsize0=19904
mdsize1=19992 mdsize1=19928
mdsize11=19935
mdsize12=19931
cleanup() { cleanup() {
$mdadm -Ss $mdadm -Ss
@ -96,7 +98,7 @@ check() {
bitmap ) bitmap )
grep -s bitmap > /dev/null /proc/mdstat || { grep -s bitmap > /dev/null /proc/mdstat || {
echo >&2 ERROR no bitmap ; cat /proc/mdstat ; exist 1; } echo >&2 ERROR no bitmap ; cat /proc/mdstat ; exit 1; }
;; ;;
nobitmap ) nobitmap )
if grep -s "bitmap" > /dev/null /proc/mdstat if grep -s "bitmap" > /dev/null /proc/mdstat
@ -134,8 +136,10 @@ rotest() {
for script in tests/$prefix*[^~] for script in tests/$prefix tests/$prefix*[^~]
do do
if [ -f "$script" ]
then
# source script in a subshell, so it has access to our # source script in a subshell, so it has access to our
# namespace, but cannot change it. # namespace, but cannot change it.
if ( set -ex ; . $script ) 2> $targetdir/log if ( set -ex ; . $script ) 2> $targetdir/log
@ -144,5 +148,6 @@ do
echo "$script failed" echo "$script failed"
exit 1 exit 1
fi fi
fi
done done
exit 0 exit 0

View File

@ -84,7 +84,7 @@ mdadm -A $md2 -u $uuid $devlist
$tst $tst
mdadm -S $md2 mdadm -S $md2
# version 1 has now super-minor # version 1 has no super-minor
# mdadm --assemble $md2 --super-minor=2 $devlist # # mdadm --assemble $md2 --super-minor=2 $devlist #
# $tst # $tst
# mdadm -S $md2 # mdadm -S $md2