Support bitmaps with raid10

And a couple of other little things

Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
Neil Brown 2005-11-22 03:37:14 +00:00
parent 7f48e21079
commit f9c25f1d2a
10 changed files with 50 additions and 23 deletions

View File

@ -58,6 +58,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
mddev_dev_t dv; mddev_dev_t dv;
int bitmap_fd; int bitmap_fd;
unsigned long long size = ~0ULL; unsigned long long size = ~0ULL;
unsigned long long bitmapsize;
/* scan all devices, make sure they really are block devices */ /* scan all devices, make sure they really are block devices */
for (dv = devlist; dv; dv=dv->next) { for (dv = devlist; dv; dv=dv->next) {
@ -215,8 +216,9 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
" between different architectured. Consider upgrading the Linux kernel.\n"); " between different architectured. Consider upgrading the Linux kernel.\n");
#endif #endif
} }
bitmapsize = size>>9; /* FIXME wrong for RAID10 */
if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk, if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
delay, write_behind, size>>9, major)) { delay, write_behind, bitmapsize, major)) {
return 1; return 1;
} }
bitmap_fd = open(bitmap_file, O_RDWR); bitmap_fd = open(bitmap_file, O_RDWR);

View File

@ -1,4 +1,10 @@
Changes Prior to this release Changes Prior to this release
- Assorted bug fixes
- Support write-intent-bitmaps on raid10
- Support little-endian (Rather than hostendian) bitmaps.
- Return correct error code from 'mdadm -S'
Changes Prior to 2.1 release
- Fix assembling of raid10 array when devices are missing. - Fix assembling of raid10 array when devices are missing.
mdadm now correctly detects if a array is workable or not mdadm now correctly detects if a array is workable or not
depending on which devices are present, and so will correctly depending on which devices are present, and so will correctly

View File

@ -69,6 +69,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
int vers; int vers;
int rv; int rv;
int bitmap_fd; int bitmap_fd;
unsigned long long bitmapsize;
mdu_array_info_t array; mdu_array_info_t array;
int major = BITMAP_MAJOR_HI; int major = BITMAP_MAJOR_HI;
@ -322,6 +323,17 @@ int Create(struct supertype *st, char *mddev, int mdfd,
else else
array.state = 0; /* not clean, but no errors */ array.state = 0; /* not clean, but no errors */
if (level == 10) {
/* for raid10, the bitmap size is the capacity of the array,
* which is array.size * raid_disks / ncopies;
* .. but convert to sectors.
*/
int ncopies = (layout>>8) * (layout & 255);
bitmapsize = (unsigned long long)array.size * raiddisks / ncopies * 2;
printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, array.size, raiddisks, ncopies);
} else
bitmapsize = (unsigned long long)array.size * 2;
/* There is lots of redundancy in these disk counts, /* There is lots of redundancy in these disk counts,
* raid_disks is the most meaningful value * raid_disks is the most meaningful value
* it describes the geometry of the array * it describes the geometry of the array
@ -365,7 +377,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
return 1; return 1;
} }
if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind, if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
&array.size, 1, major)) { bitmapsize, 1, major)) {
fprintf(stderr, Name ": Given bitmap chunk size not supported.\n"); fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
return 1; return 1;
} }
@ -397,7 +409,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
st->ss->uuid_from_super(uuid, super); st->ss->uuid_from_super(uuid, super);
if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk, if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk,
delay, write_behind, delay, write_behind,
array.size*2ULL /* FIXME wrong for raid10 */, bitmapsize,
major)) { major)) {
return 1; return 1;
} }

11
Grow.c
View File

@ -208,6 +208,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
struct supertype *st; struct supertype *st;
int major = BITMAP_MAJOR_HI; int major = BITMAP_MAJOR_HI;
int vers = md_get_version(fd); int vers = md_get_version(fd);
unsigned long long bitmapsize;
if (vers < 9003) { if (vers < 9003) {
major = BITMAP_MAJOR_HOSTENDIAN; major = BITMAP_MAJOR_HOSTENDIAN;
@ -254,6 +255,12 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
devname); devname);
return 1; return 1;
} }
bitmapsize = array.size * 2;
if (array.level == 10) {
int ncopies = (array.layout&255)*(array.layout>>8);
bitmapsize = bitmapsize * array.raid_disks / ncopies;
}
st = super_by_version(array.major_version, array.minor_version); st = super_by_version(array.major_version, array.minor_version);
if (!st) { if (!st) {
fprintf(stderr, Name ": Cannot understand version %d.%d\n", fprintf(stderr, Name ": Cannot understand version %d.%d\n",
@ -285,7 +292,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) { if (st->ss->load_super(st, fd2, &super, NULL)==0) {
st->ss->add_internal_bitmap(st, super, st->ss->add_internal_bitmap(st, super,
chunk, delay, write_behind, chunk, delay, write_behind,
&array.size, 0, major); bitmapsize, 0, major);
st->ss->write_bitmap(st, fd2, super); st->ss->write_bitmap(st, fd2, super);
} }
close(fd2); close(fd2);
@ -332,7 +339,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
return 1; return 1;
} }
if (CreateBitmap(file, 0, (char*)uuid, chunk, if (CreateBitmap(file, 0, (char*)uuid, chunk,
delay, write_behind, array.size*2ULL, major)) { delay, write_behind, bitmapsize, major)) {
return 1; return 1;
} }
bitmap_fd = open(file, O_RDWR); bitmap_fd = open(file, O_RDWR);

View File

@ -126,7 +126,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
info = malloc(sizeof(*info)); info = malloc(sizeof(*info));
if (info == NULL) { if (info == NULL) {
fprintf(stderr, Name ": failed to allocate %d bytes\n", fprintf(stderr, Name ": failed to allocate %zd bytes\n",
sizeof(*info)); sizeof(*info));
return NULL; return NULL;
} }
@ -168,7 +168,8 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
if (read_bits < total_bits) { /* file truncated... */ if (read_bits < total_bits) { /* file truncated... */
fprintf(stderr, Name ": WARNING: bitmap file is not large " fprintf(stderr, Name ": WARNING: bitmap file is not large "
"enough for array size %llu!\n\n", info->sb.sync_size); "enough for array size %llu!\n\n",
(unsigned long long)info->sb.sync_size);
total_bits = read_bits; total_bits = read_bits;
} }
out: out:
@ -263,8 +264,8 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
*(__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", (unsigned long long)sb->events);
printf(" Events Cleared : %llu\n", sb->events_cleared); printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
printf(" State : %s\n", bitmap_state(sb->state)); printf(" State : %s\n", bitmap_state(sb->state));
printf(" Chunksize : %s\n", human_chunksize(sb->chunksize)); printf(" Chunksize : %s\n", human_chunksize(sb->chunksize));
printf(" Daemon : %ds flush period\n", sb->daemon_sleep); printf(" Daemon : %ds flush period\n", sb->daemon_sleep);
@ -273,7 +274,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
else else
sprintf(buf, "Normal"); sprintf(buf, "Normal");
printf(" Write Mode : %s\n", buf); printf(" Write Mode : %s\n", buf);
printf(" Sync Size : %llu%s\n", sb->sync_size/2, printf(" Sync Size : %llu%s\n", (unsigned long long)sb->sync_size/2,
human_size(sb->sync_size * 512)); human_size(sb->sync_size * 512));
if (brief) if (brief)
goto free_info; goto free_info;

View File

@ -516,8 +516,8 @@ will not try to be so clever.
Instruct mdadm to create the device file if needed, possibly allocating Instruct mdadm to create the device file if needed, possibly allocating
an unused minor number. "md" causes a non-partitionable array an unused minor number. "md" causes a non-partitionable array
to be used. "mdp", "part" or "p" causes a partitionable array (2.6 and to be used. "mdp", "part" or "p" causes a partitionable array (2.6 and
later) to be used. "yes" requires the named md device to have a later) to be used. "yes" requires the named md device to haveo
'standard' format, and the type and minor number will be determined a 'standard' format, and the type and minor number will be determined
from this. See DEVICE NAMES below. from this. See DEVICE NAMES below.
The argument can also come immediately after The argument can also come immediately after

View File

@ -1059,7 +1059,7 @@ int main(int argc, char *argv[])
put_md_name(name); put_md_name(name);
} }
} while (!last && err); } while (!last && err);
if (err) rv |= 1 if (err) rv |= 1;
} else { } else {
fprintf(stderr, Name ": No devices given.\n"); fprintf(stderr, Name ": No devices given.\n");
exit(2); exit(2);

View File

@ -190,7 +190,8 @@ extern struct superswitch {
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)(struct supertype *st, __u64 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, int major); int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind,
unsigned long long size, int may_change, int major);
void (*locate_bitmap)(struct supertype *st, int fd, void *sbv); void (*locate_bitmap)(struct supertype *st, int fd, void *sbv);
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

@ -657,7 +657,7 @@ static __u64 avail_size0(struct supertype *st, __u64 devsize)
return MD_NEW_SIZE_SECTORS(devsize); return MD_NEW_SIZE_SECTORS(devsize);
} }
static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change, int major) static int add_internal_bitmap0(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 after the superblock and must be 60K in size * The bitmap comes immediately after the superblock and must be 60K in size
@ -665,7 +665,6 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
* *
* size is in K, chunk is in bytes !!! * size is in K, chunk is in bytes !!!
*/ */
unsigned long long size = *sizep;
unsigned long long bits; unsigned long long bits;
unsigned long long max_bits = 60*1024*8; unsigned long long max_bits = 60*1024*8;
unsigned long long min_chunk; unsigned long long min_chunk;
@ -674,7 +673,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
min_chunk = 4096; /* sub-page chunks don't work yet.. */ min_chunk = 4096; /* sub-page chunks don't work yet.. */
bits = (size * 1024)/ min_chunk +1; bits = (size * 512)/ min_chunk +1;
while (bits > max_bits) { while (bits > max_bits) {
min_chunk *= 2; min_chunk *= 2;
bits = (bits+1)/2; bits = (bits+1)/2;
@ -692,7 +691,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
uuid_from_super0((int*)bms->uuid, sb); uuid_from_super0((int*)bms->uuid, sb);
bms->chunksize = __cpu_to_le32(chunk); bms->chunksize = __cpu_to_le32(chunk);
bms->daemon_sleep = __cpu_to_le32(delay); bms->daemon_sleep = __cpu_to_le32(delay);
bms->sync_size = __cpu_to_le64(size<<1); bms->sync_size = __cpu_to_le64(size);
bms->write_behind = __cpu_to_le32(write_behind); bms->write_behind = __cpu_to_le32(write_behind);

View File

@ -842,7 +842,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
static int static int
add_internal_bitmap1(struct supertype *st, void *sbv, add_internal_bitmap1(struct supertype *st, void *sbv,
int chunk, int delay, int write_behind, int *sizep, 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 * If not may_change, then this is a 'Grow', and the bitmap
@ -851,10 +851,9 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
* before the superblock if we like, or may move the start. * before the superblock if we like, or may move the start.
* For now, just squeeze the bitmap into 3k and don't change anything. * 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 size = *sizep;
unsigned long long bits; unsigned long long bits;
unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8; unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8;
unsigned long long min_chunk; unsigned long long min_chunk;
@ -868,7 +867,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
min_chunk = 4096; /* sub-page chunks don't work yet.. */ min_chunk = 4096; /* sub-page chunks don't work yet.. */
bits = (size*1024)/min_chunk +1; bits = (size*512)/min_chunk +1;
while (bits > max_bits) { while (bits > max_bits) {
min_chunk *= 2; min_chunk *= 2;
bits = (bits+1)/2; bits = (bits+1)/2;
@ -887,7 +886,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
uuid_from_super1((int*)bms->uuid, sb); uuid_from_super1((int*)bms->uuid, sb);
bms->chunksize = __cpu_to_le32(chunk); bms->chunksize = __cpu_to_le32(chunk);
bms->daemon_sleep = __cpu_to_le32(delay); bms->daemon_sleep = __cpu_to_le32(delay);
bms->sync_size = __cpu_to_le64(size<<1); bms->sync_size = __cpu_to_le64(size);
bms->write_behind = __cpu_to_le32(write_behind); bms->write_behind = __cpu_to_le32(write_behind);
return 1; return 1;