Support internal bitmaps with format-1 superblocks.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
parent
eb3b43aa2a
commit
34163fc7cf
6
Create.c
6
Create.c
|
@ -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
2
Grow.c
|
@ -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);
|
||||||
|
|
2
Manage.c
2
Manage.c
|
@ -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.
|
||||||
|
|
27
bitmap.c
27
bitmap.c
|
@ -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));
|
||||||
|
|
6
mdadm.h
6
mdadm.h
|
@ -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;
|
||||||
|
|
7
super0.c
7
super0.c
|
@ -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
216
super1.c
|
@ -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
11
test
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue