summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Build.c4
-rw-r--r--ChangeLog6
-rw-r--r--Create.c16
-rw-r--r--Grow.c11
-rw-r--r--bitmap.c11
-rw-r--r--mdadm.84
-rw-r--r--mdadm.c2
-rw-r--r--mdadm.h3
-rw-r--r--super0.c7
-rw-r--r--super1.c9
10 files changed, 50 insertions, 23 deletions
diff --git a/Build.c b/Build.c
index 2fcc47e1..bb53a11c 100644
--- a/Build.c
+++ b/Build.c
@@ -58,6 +58,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
mddev_dev_t dv;
int bitmap_fd;
unsigned long long size = ~0ULL;
+ unsigned long long bitmapsize;
/* scan all devices, make sure they really are block devices */
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");
#endif
}
+ bitmapsize = size>>9; /* FIXME wrong for RAID10 */
if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
- delay, write_behind, size>>9, major)) {
+ delay, write_behind, bitmapsize, major)) {
return 1;
}
bitmap_fd = open(bitmap_file, O_RDWR);
diff --git a/ChangeLog b/ChangeLog
index cb66fc48..824400e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
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.
mdadm now correctly detects if a array is workable or not
depending on which devices are present, and so will correctly
diff --git a/Create.c b/Create.c
index 148ab0e7..0fd38a58 100644
--- a/Create.c
+++ b/Create.c
@@ -69,6 +69,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
int vers;
int rv;
int bitmap_fd;
+ unsigned long long bitmapsize;
mdu_array_info_t array;
int major = BITMAP_MAJOR_HI;
@@ -322,6 +323,17 @@ int Create(struct supertype *st, char *mddev, int mdfd,
else
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,
* raid_disks is the most meaningful value
* it describes the geometry of the array
@@ -365,7 +377,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,
- &array.size, 1, major)) {
+ bitmapsize, 1, major)) {
fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
return 1;
}
@@ -397,7 +409,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
st->ss->uuid_from_super(uuid, super);
if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk,
delay, write_behind,
- array.size*2ULL /* FIXME wrong for raid10 */,
+ bitmapsize,
major)) {
return 1;
}
diff --git a/Grow.c b/Grow.c
index aa14638a..d669a4e2 100644
--- a/Grow.c
+++ b/Grow.c
@@ -208,6 +208,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
struct supertype *st;
int major = BITMAP_MAJOR_HI;
int vers = md_get_version(fd);
+ unsigned long long bitmapsize;
if (vers < 9003) {
major = BITMAP_MAJOR_HOSTENDIAN;
@@ -254,6 +255,12 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
devname);
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);
if (!st) {
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) {
st->ss->add_internal_bitmap(st, super,
chunk, delay, write_behind,
- &array.size, 0, major);
+ bitmapsize, 0, major);
st->ss->write_bitmap(st, fd2, super);
}
close(fd2);
@@ -332,7 +339,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
return 1;
}
if (CreateBitmap(file, 0, (char*)uuid, chunk,
- delay, write_behind, array.size*2ULL, major)) {
+ delay, write_behind, bitmapsize, major)) {
return 1;
}
bitmap_fd = open(file, O_RDWR);
diff --git a/bitmap.c b/bitmap.c
index bc29768f..bdfd4055 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -126,7 +126,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
info = malloc(sizeof(*info));
if (info == NULL) {
- fprintf(stderr, Name ": failed to allocate %d bytes\n",
+ fprintf(stderr, Name ": failed to allocate %zd bytes\n",
sizeof(*info));
return NULL;
}
@@ -168,7 +168,8 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
if (read_bits < total_bits) { /* file truncated... */
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;
}
out:
@@ -263,8 +264,8 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
*(__u32 *)(sb->uuid+8),
*(__u32 *)(sb->uuid+12));
}
- printf(" Events : %llu\n", sb->events);
- printf(" Events Cleared : %llu\n", sb->events_cleared);
+ printf(" Events : %llu\n", (unsigned long long)sb->events);
+ printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
printf(" State : %s\n", bitmap_state(sb->state));
printf(" Chunksize : %s\n", human_chunksize(sb->chunksize));
printf(" Daemon : %ds flush period\n", sb->daemon_sleep);
@@ -273,7 +274,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
else
sprintf(buf, "Normal");
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));
if (brief)
goto free_info;
diff --git a/mdadm.8 b/mdadm.8
index aa39a236..45326f62 100644
--- a/mdadm.8
+++ b/mdadm.8
@@ -516,8 +516,8 @@ will not try to be so clever.
Instruct mdadm to create the device file if needed, possibly allocating
an unused minor number. "md" causes a non-partitionable array
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
-'standard' format, and the type and minor number will be determined
+later) to be used. "yes" requires the named md device to haveo
+a 'standard' format, and the type and minor number will be determined
from this. See DEVICE NAMES below.
The argument can also come immediately after
diff --git a/mdadm.c b/mdadm.c
index ad3d1517..8af61e96 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1059,7 +1059,7 @@ int main(int argc, char *argv[])
put_md_name(name);
}
} while (!last && err);
- if (err) rv |= 1
+ if (err) rv |= 1;
} else {
fprintf(stderr, Name ": No devices given.\n");
exit(2);
diff --git a/mdadm.h b/mdadm.h
index 85a853b6..2abb0f0c 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -190,7 +190,8 @@ extern struct superswitch {
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 (*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);
int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
int major;
diff --git a/super0.c b/super0.c
index 4ab40af9..6b8c2081 100644
--- a/super0.c
+++ b/super0.c
@@ -657,7 +657,7 @@ static __u64 avail_size0(struct supertype *st, __u64 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
@@ -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 !!!
*/
- unsigned long long size = *sizep;
unsigned long long bits;
unsigned long long max_bits = 60*1024*8;
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.. */
- bits = (size * 1024)/ min_chunk +1;
+ bits = (size * 512)/ min_chunk +1;
while (bits > max_bits) {
min_chunk *= 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);
bms->chunksize = __cpu_to_le32(chunk);
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);
diff --git a/super1.c b/super1.c
index 46ce82d9..a0a3a682 100644
--- a/super1.c
+++ b/super1.c
@@ -842,7 +842,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
static int
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
@@ -851,10 +851,9 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
* 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 size = *sizep;
unsigned long long bits;
unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8;
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.. */
- bits = (size*1024)/min_chunk +1;
+ bits = (size*512)/min_chunk +1;
while (bits > max_bits) {
min_chunk *= 2;
bits = (bits+1)/2;
@@ -887,7 +886,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
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<<1);
+ bms->sync_size = __cpu_to_le64(size);
bms->write_behind = __cpu_to_le32(write_behind);
return 1;