summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-22 13:55:34 +1000
committerNeilBrown <neilb@suse.de>2012-05-22 13:55:34 +1000
commit1dff2b87a34a1ac1d1898ea109bf97ed396aca53 (patch)
tree041386083d0b7242aa802d6545dd86c51c2a405e
parent63aced61023a054825ffd6e33ac1ab99036dadd2 (diff)
downloadlinux-3.10-1dff2b87a34a1ac1d1898ea109bf97ed396aca53.tar.gz
linux-3.10-1dff2b87a34a1ac1d1898ea109bf97ed396aca53.tar.bz2
linux-3.10-1dff2b87a34a1ac1d1898ea109bf97ed396aca53.zip
md/bitmap: record the space available for the bitmap in the superblock.
Now that bitmaps can grow and shrink it is best if we record how much space is available. This means that when we reduce the size of the bitmap we won't "lose" the space for late when we might want to increase the size of the bitmap again. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/bitmap.c7
-rw-r--r--drivers/md/bitmap.h4
2 files changed, 10 insertions, 1 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 8f681da0027..15dbe03117e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -423,6 +423,8 @@ void bitmap_update_sb(struct bitmap *bitmap)
/* This might have been changed by a reshape */
sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
sb->chunksize = cpu_to_le32(bitmap->mddev->bitmap_info.chunksize);
+ sb->sectors_reserved = cpu_to_le32(bitmap->mddev->
+ bitmap_info.space);
kunmap_atomic(sb);
write_page(bitmap, bitmap->storage.sb_page, 1);
}
@@ -536,6 +538,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
bitmap_super_t *sb;
unsigned long chunksize, daemon_sleep, write_behind;
unsigned long long events;
+ unsigned long sectors_reserved = 0;
int err = -EINVAL;
struct page *sb_page;
@@ -573,6 +576,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
chunksize = le32_to_cpu(sb->chunksize);
daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;
write_behind = le32_to_cpu(sb->write_behind);
+ sectors_reserved = le32_to_cpu(sb->sectors_reserved);
/* verify that the bitmap-specific fields are valid */
if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
@@ -633,6 +637,9 @@ out_no_sb:
bitmap->mddev->bitmap_info.chunksize = chunksize;
bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
bitmap->mddev->bitmap_info.max_write_behind = write_behind;
+ if (bitmap->mddev->bitmap_info.space == 0 ||
+ bitmap->mddev->bitmap_info.space > sectors_reserved)
+ bitmap->mddev->bitmap_info.space = sectors_reserved;
if (err)
bitmap_print_sb(bitmap);
return err;
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
index 04dcde3871b..df4aeb6ac6f 100644
--- a/drivers/md/bitmap.h
+++ b/drivers/md/bitmap.h
@@ -128,8 +128,10 @@ typedef struct bitmap_super_s {
__le32 chunksize; /* 52 the bitmap chunk size in bytes */
__le32 daemon_sleep; /* 56 seconds between disk flushes */
__le32 write_behind; /* 60 number of outstanding write-behind writes */
+ __le32 sectors_reserved; /* 64 number of 512-byte sectors that are
+ * reserved for the bitmap. */
- __u8 pad[256 - 64]; /* set to zero */
+ __u8 pad[256 - 68]; /* set to zero */
} bitmap_super_t;
/* notes: