diff options
author | NeilBrown <neilb@suse.de> | 2012-05-22 05:55:27 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-05-22 05:55:27 +0200 |
commit | a4a6125a074e1b08ee8ae34f700c5bca19eb9d18 (patch) | |
tree | 761a719a7d4f1a53d44349f7bef095368a9ae75a | |
parent | md/bitmap: make sure reshape request are reflected in superblock. (diff) | |
download | linux-a4a6125a074e1b08ee8ae34f700c5bca19eb9d18.tar.xz linux-a4a6125a074e1b08ee8ae34f700c5bca19eb9d18.zip |
md: allow array to be resized while bitmap is present.
Now that bitmaps can be resized, we can allow an array to be resized
while the bitmap is present.
This only covers resizing that involves changing the effective size
of member devices, not resizing that changes the number of devices.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | drivers/md/md.c | 6 | ||||
-rw-r--r-- | drivers/md/raid1.c | 11 | ||||
-rw-r--r-- | drivers/md/raid10.c | 10 | ||||
-rw-r--r-- | drivers/md/raid5.c | 14 |
4 files changed, 28 insertions, 13 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9e2336fbbd31..86adf4ac46cf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6153,11 +6153,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) */ if (mddev->sync_thread) return -EBUSY; - if (mddev->bitmap) - /* Sorry, cannot grow a bitmap yet, just remove it, - * grow, and re-add. - */ - return -EBUSY; + rdev_for_each(rdev, mddev) { sector_t avail = rdev->sectors; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 22cfc6660b18..8e717bd518e7 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2752,9 +2752,16 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors) * any io in the removed space completes, but it hardly seems * worth it. */ - md_set_array_sectors(mddev, raid1_size(mddev, sectors, 0)); - if (mddev->array_sectors > raid1_size(mddev, sectors, 0)) + sector_t newsize = raid1_size(mddev, sectors, 0); + if (mddev->external_size && + mddev->array_sectors > newsize) return -EINVAL; + if (mddev->bitmap) { + int ret = bitmap_resize(mddev->bitmap, newsize, 0, 0); + if (ret) + return ret; + } + md_set_array_sectors(mddev, newsize); set_capacity(mddev->gendisk, mddev->array_sectors); revalidate_disk(mddev->gendisk); if (sectors > mddev->dev_sectors && diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index fb9062b5022c..8fe3aa469987 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3678,9 +3678,15 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors) oldsize = raid10_size(mddev, 0, 0); size = raid10_size(mddev, sectors, 0); - md_set_array_sectors(mddev, size); - if (mddev->array_sectors > size) + if (mddev->external_size && + mddev->array_sectors > size) return -EINVAL; + if (mddev->bitmap) { + int ret = bitmap_resize(mddev->bitmap, size, 0, 0); + if (ret) + return ret; + } + md_set_array_sectors(mddev, size); set_capacity(mddev->gendisk, mddev->array_sectors); revalidate_disk(mddev->gendisk); if (sectors > mddev->dev_sectors && diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7bfd59b313d7..eab6168bb7f4 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5503,12 +5503,18 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors) * any io in the removed space completes, but it hardly seems * worth it. */ + sector_t newsize; sectors &= ~((sector_t)mddev->chunk_sectors - 1); - md_set_array_sectors(mddev, raid5_size(mddev, sectors, - mddev->raid_disks)); - if (mddev->array_sectors > - raid5_size(mddev, sectors, mddev->raid_disks)) + newsize = raid5_size(mddev, sectors, mddev->raid_disks); + if (mddev->external_size && + mddev->array_sectors > newsize) return -EINVAL; + if (mddev->bitmap) { + int ret = bitmap_resize(mddev->bitmap, sectors, 0, 0); + if (ret) + return ret; + } + md_set_array_sectors(mddev, newsize); set_capacity(mddev->gendisk, mddev->array_sectors); revalidate_disk(mddev->gendisk); if (sectors > mddev->dev_sectors && |