]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
super1: reserve at least 2 chunks for reshape headroom. r10-reshape
authorNeilBrown <neilb@suse.de>
Wed, 9 May 2012 10:49:32 +0000 (20:49 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 9 May 2012 10:49:32 +0000 (20:49 +1000)
sometimes 0.1% isn't enough, though mostly only in testing.

We need one chunk for a successful reshape, so reserve 2.

Signed-off-by: NeilBrown <neilb@suse.de>
super1.c

index 1310f97692ead703e76371b29962e56ad6d814a2..66240773ee64b093b4a3cb1156a8ca2a3bfad16e 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1234,11 +1234,15 @@ static int write_init_super1(struct supertype *st)
                /* We try to leave 0.1% at the start for reshape
                 * operations, but limit this to 128Meg (0.1% of 10Gig)
                 * which is plenty for efficient reshapes
+                * However we make it at least 2 chunks as one chunk
+                * is minimum needed for reshape.
                 */
                headroom = 128 * 1024 * 2;
-               while  (headroom << 10 > array_size)
+               while  (headroom << 10 > array_size &&
+                       headroom/2 >= __le32_to_cpu(sb->chunksize) * 2)
                        headroom >>= 1;
 
+
                switch(st->minor_version) {
                case 0:
                        sb_offset = dsize;
@@ -1569,14 +1573,14 @@ 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,
-                        long long data_offset)
+static __u64 _avail_size1(struct supertype *st, __u64 devsize,
+                        long long data_offset, int chunksize)
 {
        struct mdp_superblock_1 *super = st->sb;
        int bmspace = 0;
        if (devsize < 24)
                return 0;
-
+       printf("chunksize %d\n", chunksize);
        if (super == NULL)
                /* creating:  allow suitable space for bitmap */
                bmspace = choose_bm_space(devsize);
@@ -1613,7 +1617,9 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
                 * Limit slack to 128M, but aim for about 0.1%
                 */
                unsigned long long headroom = 128*1024*2;
-               while ((headroom << 10) > devsize)
+               while ((headroom << 10) > devsize &&
+                      (chunksize == 0 ||
+                       headroom / 2 >= ((unsigned)chunksize*2)*2))
                        headroom >>= 1;
                devsize -= headroom;
        }
@@ -1630,6 +1636,11 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
        }
        return 0;
 }
+static __u64 avail_size1(struct supertype *st, __u64 devsize,
+                        long long data_offset)
+{
+       return _avail_size1(st, devsize, data_offset, 0);
+}
 
 static int
 add_internal_bitmap1(struct supertype *st,
@@ -1870,7 +1881,7 @@ static int validate_geometry1(struct supertype *st, int level,
        }
        close(fd);
 
-       *freesize = avail_size1(st, ldsize >> 9, data_offset);
+       *freesize = _avail_size1(st, ldsize >> 9, data_offset, *chunk);
        return 1;
 }
 #endif /* MDASSEMBLE */