summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-09 20:49:32 +1000
committerNeilBrown <neilb@suse.de>2012-05-09 20:49:32 +1000
commit164a67cd3b3319972b55d70080efad0537d22178 (patch)
tree1d54ba7bd0443e566bfdab5ca4263a59bcf97eb5
parentd91b51cbe6ad36164200231f666e485cc9be0af2 (diff)
downloadmdadm-r10-reshape.tar.gz
super1: reserve at least 2 chunks for reshape headroom.r10-reshape
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>
-rw-r--r--super1.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/super1.c b/super1.c
index 1310f97..6624077 100644
--- 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 */