]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Limit size of bitmap to 2million chunks.
authorNeil Brown <neilb@suse.de>
Mon, 15 May 2006 04:21:33 +0000 (04:21 +0000)
committerNeil Brown <neilb@suse.de>
Mon, 15 May 2006 04:21:33 +0000 (04:21 +0000)
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>
Build.c
ChangeLog
Create.c
Grow.c
bitmap.c
mdadm.8
mdadm.c

diff --git a/Build.c b/Build.c
index bb53a11cfbdddb6fd5551defbf1dd69736d6f0bd..ff92cc1e695972dab09b8c85143fca943f1351e2 100644 (file)
--- 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 */
index 8e1d951c4b7bf2b8642fcf533d5581dafcc51854..e4f4dad9bde9c31ce63384adbe0312ba887c1deb 100644 (file)
--- 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
index df6d850ce249730e24af536d2c1ca119a56ff990..2cd644bf35ba82d93a93e2f98242cf249d5284b4 100644 (file)
--- 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 bc8a73f6502aa4c83f1d3879d230d3540bd294ec..742f656f02f72b0aefa7e1e8bdc1bf78910f2069 100644 (file)
--- 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++) {
index 33deab11bd829eff6d4ccf63c1c7819601613ee3..75492f759fe0c2ad2c8ee7464b556ed2163dc8ae 100644 (file)
--- 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 4ec2f76ace1d1ee2780ad4238340492cd8cf2716..57918bfb10635329eef9e07a0f8fe04e02e6ec6c 100644 (file)
--- 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 f31047476eec0478294059ad63ef40c2a152c533..7f109486a10d91c23c85f06b9c2d1fe5a1076711 100644 (file)
--- 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");