From cc3130a7863c21d773e1afad703b3f252debe075 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 May 2013 15:38:49 +1000 Subject: [PATCH] super1: improve calculation of space_before/space_after 1/ these must allow for bad-block-list 2/ they must match the kernel, which has a 32k buffer after the superblock. Signed-off-by: NeilBrown --- super1.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/super1.c b/super1.c index 08d94a3..1ce2668 100644 --- a/super1.c +++ b/super1.c @@ -910,15 +910,24 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) unsigned long long end; info->space_before = info->data_offset; end = super_offset; - if (info->bitmap_offset < 0) - end += info->bitmap_offset; + + if (sb->bblog_offset && sb->bblog_size) { + unsigned long long bboffset = super_offset; + bboffset += (int32_t)__le32_to_cpu(sb->bblog_offset); + if (bboffset < end) + end = bboffset; + } + + if (super_offset + info->bitmap_offset < end) + end = super_offset + info->bitmap_offset; + if (info->data_offset + data_size < end) info->space_after = end - data_size - info->data_offset; else info->space_after = 0; } else { - info->space_before = (info->data_offset - - super_offset); + unsigned long long earliest; + earliest = super_offset + (32+4)*2; /* match kernel */ if (info->bitmap_offset > 0) { unsigned long long bmend = info->bitmap_offset; unsigned long long size = __le64_to_cpu(bsb->sync_size); @@ -927,13 +936,21 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) size += sizeof(bitmap_super_t); size = ROUND_UP(size, 4096); size /= 512; - size += bmend; - if (size < info->space_before) - info->space_before -= size; - else - info->space_before = 0; - } else - info->space_before -= 8; /* superblock */ + bmend += size; + if (bmend > earliest) + bmend = earliest; + } + if (sb->bblog_offset && sb->bblog_size) { + unsigned long long bbend = super_offset; + bbend += (int32_t)__le32_to_cpu(sb->bblog_offset); + bbend += __le32_to_cpu(sb->bblog_size); + if (bbend > earliest) + earliest = bbend; + } + if (earliest < info->data_offset) + info->space_before = info->data_offset - earliest; + else + info->space_before = 0; info->space_after = misc->device_size - data_size - info->data_offset; }