Passes all tests, nearly ready for release.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
parent
8431b2b286
commit
1bf4e2d962
6
Create.c
6
Create.c
|
@ -210,7 +210,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
ldsize = dsize;
|
||||
ldsize <<= 9;
|
||||
}
|
||||
freesize = st->ss->avail_size(st, ldsize >> 9, 64*2);
|
||||
freesize = st->ss->avail_size(st, ldsize >> 9);
|
||||
if (freesize == 0) {
|
||||
fprintf(stderr, Name ": %s is too small: %luK\n",
|
||||
dname, (unsigned long)(ldsize>>10));
|
||||
|
@ -356,7 +356,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
return 1;
|
||||
}
|
||||
if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
|
||||
size ? size : maxsize)) {
|
||||
&array.size, 1)) {
|
||||
fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
break;
|
||||
case 2:
|
||||
if (disk.state == 1) break;
|
||||
st->ss->write_init_super(st, super, &disk, dv->devname, 64*2);
|
||||
st->ss->write_init_super(st, super, &disk, dv->devname);
|
||||
|
||||
if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
|
||||
fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",
|
||||
|
|
2
Grow.c
2
Grow.c
|
@ -275,7 +275,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
|
|||
if (st->ss->load_super(st, fd2, &super, NULL)==0) {
|
||||
st->ss->add_internal_bitmap(st, super,
|
||||
chunk, delay, write_behind,
|
||||
array.size);
|
||||
&array.size, 0);
|
||||
st->ss->write_bitmap(st, fd2, super);
|
||||
}
|
||||
close(fd2);
|
||||
|
|
2
Manage.c
2
Manage.c
|
@ -311,7 +311,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
if (dv->writemostly)
|
||||
disc.state |= 1 << MD_DISK_WRITEMOSTLY;
|
||||
st->ss->add_to_super(dsuper, &disc);
|
||||
if (st->ss->write_init_super(st, dsuper, &disc, dv->devname, 0 /* FIXME */))
|
||||
if (st->ss->write_init_super(st, dsuper, &disc, dv->devname))
|
||||
return 1;
|
||||
} else if (dv->re_add) {
|
||||
/* this had better be raid1.
|
||||
|
|
6
bitmap.c
6
bitmap.c
|
@ -285,9 +285,9 @@ free_info:
|
|||
}
|
||||
|
||||
int CreateBitmap(char *filename, int force, char uuid[16],
|
||||
unsigned long chunksize, unsigned long daemon_sleep,
|
||||
unsigned long write_behind,
|
||||
unsigned long long array_size)
|
||||
unsigned long chunksize, unsigned long daemon_sleep,
|
||||
unsigned long write_behind,
|
||||
unsigned long long array_size /* sectors */)
|
||||
{
|
||||
/*
|
||||
* Create a bitmap file with a superblock and (optionally) a full bitmap
|
||||
|
|
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);
|
||||
void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo);
|
||||
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 reserve);
|
||||
int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname);
|
||||
int (*compare_super)(void **firstp, void *secondv);
|
||||
int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname);
|
||||
struct supertype * (*match_metadata_desc)(char *arg);
|
||||
__u64 (*avail_size)(struct supertype *st, __u64 size, int reserve);
|
||||
int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size);
|
||||
__u64 (*avail_size)(struct supertype *st, __u64 size);
|
||||
int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change);
|
||||
void (*locate_bitmap)(struct supertype *st, int fd);
|
||||
int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
|
||||
int major;
|
||||
|
|
37
super0.c
37
super0.c
|
@ -472,7 +472,7 @@ static int store_super0(struct supertype *st, int fd, void *sbv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname, int reserve)
|
||||
static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname)
|
||||
{
|
||||
mdp_super_t *sb = sbv;
|
||||
int fd = open(devname, O_RDWR|O_EXCL);
|
||||
|
@ -490,27 +490,8 @@ static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *d
|
|||
sb->sb_csum = calc_sb0_csum(sb);
|
||||
rv = store_super0(st, fd, sb);
|
||||
|
||||
if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) {
|
||||
int towrite, n;
|
||||
char buf[4096];
|
||||
|
||||
write(fd, ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t));
|
||||
towrite = 64*1024 - MD_SB_BYTES - 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;
|
||||
}
|
||||
if (rv == 0 && (sb->state & (1<<MD_SB_BITMAP_PRESENT)))
|
||||
rv = st->ss->write_bitmap(st, fd, sbv);
|
||||
|
||||
close(fd);
|
||||
if (rv)
|
||||
|
@ -664,15 +645,14 @@ static struct supertype *match_metadata_desc0(char *arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static __u64 avail_size0(struct supertype *st, __u64 devsize, int reserve)
|
||||
static __u64 avail_size0(struct supertype *st, __u64 devsize)
|
||||
{
|
||||
if (devsize < MD_RESERVED_SECTORS*2)
|
||||
return 0ULL;
|
||||
if (reserve > 64*2) return 0ULL;
|
||||
return MD_NEW_SIZE_SECTORS(devsize);
|
||||
}
|
||||
|
||||
static int add_internal_bitmap0(struct supertype *st, 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, int *sizep, int may_change)
|
||||
{
|
||||
/*
|
||||
* The bitmap comes immediately after the superblock and must be 60K in size
|
||||
|
@ -680,8 +660,8 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
|
|||
*
|
||||
* size is in K, chunk is in bytes !!!
|
||||
*/
|
||||
|
||||
unsigned long long bits = size;
|
||||
unsigned long long size = *sizep;
|
||||
unsigned long long bits;
|
||||
unsigned long long max_bits = 60*1024*8;
|
||||
unsigned long long min_chunk;
|
||||
mdp_super_t *sb = sbv;
|
||||
|
@ -689,6 +669,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
|
|||
|
||||
|
||||
min_chunk = 4096; /* sub-page chunks don't work yet.. */
|
||||
bits = (size * 1024)/ min_chunk +1;
|
||||
while (bits > max_bits) {
|
||||
min_chunk *= 2;
|
||||
bits = (bits+1)/2;
|
||||
|
@ -706,7 +687,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
|
|||
uuid_from_super0((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->sync_size = __cpu_to_le64(size<<1);
|
||||
bms->write_behind = __cpu_to_le32(write_behind);
|
||||
|
||||
|
||||
|
|
117
super1.c
117
super1.c
|
@ -526,8 +526,7 @@ 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 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;
|
||||
|
@ -595,18 +594,18 @@ static int write_init_super1(struct supertype *st, void *sbv,
|
|||
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;
|
||||
|
@ -618,29 +617,8 @@ static int write_init_super1(struct supertype *st, void *sbv,
|
|||
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;
|
||||
}
|
||||
|
@ -835,42 +813,54 @@ static struct supertype *match_metadata_desc1(char *arg)
|
|||
* 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, int *sizep, int may_change)
|
||||
{
|
||||
/*
|
||||
* 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 !!!
|
||||
*/
|
||||
|
||||
unsigned long long bits = size;
|
||||
unsigned long long max_bits = 62*1024*8;
|
||||
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;
|
||||
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*1024)/min_chunk +1;
|
||||
while (bits > max_bits) {
|
||||
min_chunk *= 2;
|
||||
bits = (bits+1)/2;
|
||||
|
@ -880,10 +870,7 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int
|
|||
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);
|
||||
|
@ -892,7 +879,7 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int
|
|||
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->sync_size = __cpu_to_le64(size<<1);
|
||||
bms->write_behind = __cpu_to_le32(write_behind);
|
||||
|
||||
return 1;
|
||||
|
@ -901,40 +888,21 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int
|
|||
|
||||
void locate_bitmap1(struct supertype *st, int fd)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (st->ss->load_super(st, fd, (void**)&sb, NULL))
|
||||
return; /* no error I hope... */
|
||||
offset = __le64_to_cpu(sb->super_offset);
|
||||
offset += (long) __le32_to_cpu(sb->bitmap_offset);
|
||||
|
||||
offset = (dsize - 8192) & ~4095ULL;
|
||||
|
||||
offset -= 65536;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
offset = 1024;
|
||||
break;
|
||||
case 2:
|
||||
offset = 4096+1024;
|
||||
}
|
||||
lseek64(fd, offset, 0);
|
||||
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;
|
||||
|
@ -943,7 +911,8 @@ int write_bitmap1(struct supertype *st, int fd, void *sbv)
|
|||
locate_bitmap1(st, fd);
|
||||
|
||||
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;
|
||||
|
|
8
test
8
test
|
@ -24,12 +24,12 @@ md0=/dev/md0 md1=/dev/md1 md2=/dev/md2
|
|||
|
||||
# We test mdadm on loop-back block devices.
|
||||
# dir for storing files should be settable by command line maybe
|
||||
targetdir=/tmp
|
||||
targetdir=/var/tmp
|
||||
size=20000
|
||||
mdsize0=19904
|
||||
mdsize1=19928
|
||||
mdsize11=19935
|
||||
mdsize12=19931
|
||||
mdsize1=19992
|
||||
mdsize11=19996
|
||||
mdsize12=19992
|
||||
|
||||
cleanup() {
|
||||
$mdadm -Ss
|
||||
|
|
|
@ -27,7 +27,7 @@ testdev $md0 1 $[size/2] 1
|
|||
mdadm --grow $md0 --size max
|
||||
check resync
|
||||
check wait
|
||||
testdev $md0 1 $[size-1-64] 1
|
||||
testdev $md0 1 $[size-4] 1
|
||||
|
||||
mdadm --grow $md0 --size $[size/2]
|
||||
check nosync
|
||||
|
|
|
@ -27,7 +27,7 @@ testdev $md0 3 $[size/2] 128
|
|||
mdadm --grow $md0 --size max
|
||||
check resync
|
||||
check wait
|
||||
testdev $md0 3 $[size-1-64] 128
|
||||
testdev $md0 3 $[size-4] 128
|
||||
|
||||
mdadm --grow $md0 --size $[size/2]
|
||||
check nosync
|
||||
|
|
|
@ -27,7 +27,7 @@ testdev $md0 2 $[size/2] 128
|
|||
mdadm --grow $md0 --size max
|
||||
check resync
|
||||
check wait
|
||||
testdev $md0 2 $[size-1-64] 128
|
||||
testdev $md0 2 $[size-4] 128
|
||||
|
||||
mdadm --grow $md0 --size $[size/2]
|
||||
check nosync
|
||||
|
|
|
@ -15,7 +15,7 @@ mdadm $md0 -f $dev2
|
|||
sleep 1
|
||||
mdadm $md0 -r $dev2
|
||||
mdadm $md0 -a $dev2
|
||||
cat /proc/mdstat
|
||||
#cat /proc/mdstat
|
||||
check nosync
|
||||
|
||||
mdadm $md0 -f $dev2
|
||||
|
|
Loading…
Reference in New Issue