summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--super1.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/super1.c b/super1.c
index 2770a7f..36369d8 100644
--- a/super1.c
+++ b/super1.c
@@ -1094,7 +1094,7 @@ static int write_init_super1(struct supertype *st)
unsigned long long reserved;
struct devinfo *di;
unsigned long long dsize, array_size;
- unsigned long long sb_offset;
+ unsigned long long sb_offset, headroom;
for (di = st->info; di && ! rv ; di = di->next) {
if (di->disk.state == 1)
@@ -1167,6 +1167,14 @@ static int write_init_super1(struct supertype *st)
/* work out how much space we left for a bitmap */
bm_space = choose_bm_space(array_size);
+ /* 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
+ */
+ headroom = 128 * 1024 * 2;
+ while (headroom << 10 > array_size)
+ headroom >>= 1;
+
switch(st->minor_version) {
case 0:
sb_offset = dsize;
@@ -1189,6 +1197,9 @@ static int write_init_super1(struct supertype *st)
/* force 4K alignment */
reserved &= ~7ULL;
+ if (reserved < headroom)
+ reserved = headroom;
+
sb->data_offset = __cpu_to_le64(reserved);
sb->data_size = __cpu_to_le64(dsize - reserved);
break;
@@ -1209,6 +1220,9 @@ static int write_init_super1(struct supertype *st)
/* force 4K alignment */
reserved &= ~7ULL;
+ if (reserved < headroom)
+ reserved = headroom;
+
sb->data_offset = __cpu_to_le64(reserved);
sb->data_size = __cpu_to_le64(dsize - reserved);
break;
@@ -1506,12 +1520,13 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
st->minor_version = 2;
if (super == NULL && st->minor_version > 0) {
/* haven't committed to a size yet, so allow some
- * slack for alignment of data_offset.
- * We haven't access to device details so allow
- * 1 Meg if bigger than 1Gig
+ * slack for space for reshape.
+ * Limit slack to 128M, but aim for about 0.1%
*/
- if (devsize > 1024*1024*2)
- devsize -= 1024*2;
+ unsigned long long headroom = 128*1024*2;
+ while ((headroom << 10) > devsize)
+ headroom >>= 1;
+ devsize -= headroom;
}
switch(st->minor_version) {
case 0: