]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
md: allow array to be resized while bitmap is present.
authorNeilBrown <neilb@suse.de>
Tue, 24 Apr 2012 00:57:58 +0000 (10:57 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 24 Apr 2012 00:57:58 +0000 (10:57 +1000)
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>
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c

index 895d35fe7e3d56352670ef755282fb0d18da6970..227c4ee7936ad2064687409c91bd8aa997aab3be 100644 (file)
@@ -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;
 
index 22cfc6660b188ffa6b2099783560e193b9d5f0f8..8e717bd518e7c712087748286175380a1078f550 100644 (file)
@@ -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 &&
index 728fcab972e62d091212dc1a070f014303f4c9b7..cd64c89ccc0141c17e6b86d5d37c10cf44ccac45 100644 (file)
@@ -3666,9 +3666,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 &&
index 7bfd59b313d756f67fe392b6d0bb020ab7098cf6..eab6168bb7f46fa5110369311de7dacdb732fa7a 100644 (file)
@@ -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 &&