summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-05-15 04:21:33 +0000
committerNeil Brown <neilb@suse.de>2006-05-15 04:21:33 +0000
commit1bfdbe01ff300ebbf92d68c15722d2ba861aac3b (patch)
treecc0f64dabdaddf62383a377f317ad0e2b94dc9ce
parent8686f3ed069671e5cbf8660cfd73c92b066563d0 (diff)
downloadmdadm-1bfdbe01ff300ebbf92d68c15722d2ba861aac3b.tar.gz
mdadm-1bfdbe01ff300ebbf92d68c15722d2ba861aac3b.tar.xz
mdadm-1bfdbe01ff300ebbf92d68c15722d2ba861aac3b.zip
Limit size of bitmap to 2million chunks.
When creating a file bitmap, choose a default size that results in fewer than 2^21 chunks. Without this kmalloc failure in the kernel becomes likely. Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r--Build.c4
-rw-r--r--ChangeLog3
-rw-r--r--Create.c3
-rw-r--r--Grow.c2
-rw-r--r--bitmap.c11
-rw-r--r--mdadm.85
-rw-r--r--mdadm.c1
7 files changed, 20 insertions, 9 deletions
diff --git a/Build.c b/Build.c
index bb53a11..ff92cc1 100644
--- a/Build.c
+++ b/Build.c
@@ -204,16 +204,18 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
bitmap_fd = open(bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
int major = BITMAP_MAJOR_HI;
+#if 0
if (bitmap_chunk == UnSet) {
fprintf(stderr, Name ": %s cannot be openned.",
bitmap_file);
return 1;
}
+#endif
if (vers < 9003) {
major = BITMAP_MAJOR_HOSTENDIAN;
#ifdef __BIG_ENDIAN
fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
- " between different architectured. Consider upgrading the Linux kernel.\n");
+ " between different architectures. Consider upgrading the Linux kernel.\n");
#endif
}
bitmapsize = size>>9; /* FIXME wrong for RAID10 */
diff --git a/ChangeLog b/ChangeLog
index 8e1d951..e4f4dad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@ Changes Prior to this release
DegradedArray) generates an Email.
- Assume "DEVICE partitions" if no DEVICE line is given.
- Support new 'offset' layout for raid10.
+ - When creating a bitmap file, choose a chunksize to limit number
+ of bitmap chunks to 2 million. More than this can cause kmalloc
+ failure.
Changes Prior to 2.4.1 release
- Honour --write-mostly when adding to an array without persistent
diff --git a/Create.c b/Create.c
index df6d850..2cd644b 100644
--- a/Create.c
+++ b/Create.c
@@ -432,9 +432,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
if (bitmap_file) {
int uuid[4];
- if (bitmap_chunk == UnSet)
- bitmap_chunk = DEFAULT_BITMAP_CHUNK;
-
st->ss->uuid_from_super(uuid, super);
if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk,
delay, write_behind,
diff --git a/Grow.c b/Grow.c
index bc8a73f..742f656 100644
--- a/Grow.c
+++ b/Grow.c
@@ -329,8 +329,6 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
int d;
int max_devs = st->max_devs;
void *super = NULL;
- if (chunk == UnSet)
- chunk = DEFAULT_BITMAP_CHUNK;
/* try to load a superblock */
for (d=0; d<max_devs; d++) {
diff --git a/bitmap.c b/bitmap.c
index 33deab1..75492f7 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -341,6 +341,17 @@ int CreateBitmap(char *filename, int force, char uuid[16],
return rv;
}
+ if (chunksize == UnSet) {
+ /* We don't want more than 2^21 chunks, as 2^11 fill up one
+ * 4K page (2 bytes per chunk), and 2^10 address of those
+ * fill up a 4K indexing page. 2^20 might be safer...
+ */
+ chunksize = DEFAULT_BITMAP_CHUNK;
+ /* <<21 for 2^21 chunks, >>9 to convert bytes to sectors */
+ while (array_size > (chunksize << (21-9)))
+ chunksize <<= 1;
+ }
+
memset(&sb, 0, sizeof(sb));
sb.magic = BITMAP_MAGIC;
sb.version = major;
diff --git a/mdadm.8 b/mdadm.8
index 4ec2f76..57918bf 100644
--- a/mdadm.8
+++ b/mdadm.8
@@ -447,11 +447,12 @@ slash ('/') if it is a real file (not 'internal' or 'none').
Note: external bitmaps are only known to work on ext2 and ext3.
Storing bitmap files on other filesystems may result in serious problems.
-
.TP
.BR --bitmap-chunk=
Set the chunksize of the bitmap. Each bit corresponds to that many
-Kilobytes of storage. Default is 4 when using a file based bitmap.
+Kilobytes of storage.
+When using a file based bitmap, the default is to use the smallest
+size that is atleast 4 and requires no more than 2^21 chunks.
When using an
.B internal
bitmap, the chunksize is automatically determined to make best use of
diff --git a/mdadm.c b/mdadm.c
index f310474..7f10948 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1020,7 +1020,6 @@ int main(int argc, char *argv[])
}
break;
case BUILD:
- if (bitmap_chunk == UnSet) bitmap_chunk = DEFAULT_BITMAP_CHUNK;
if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
if (write_behind && !bitmap_file) {
fprintf(stderr, Name ": write-behind mode requires a bitmap.\n");