md/raid5: reallocate page array after setting new stripe_size
authorYufen Yu <yuyufen@huawei.com>
Thu, 20 Aug 2020 13:22:14 +0000 (09:22 -0400)
committerSong Liu <songliubraving@fb.com>
Thu, 24 Sep 2020 23:44:45 +0000 (16:44 -0700)
When try to resize stripe_size, we also need to free old
shared page array and allocate new.

Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
drivers/md/raid5.c

index c23e408f76231a939f21d55825814e1e1ecb369d..66690b40818e704bf6b2efa776e22f33404c1eab 100644 (file)
@@ -6682,6 +6682,7 @@ raid5_store_stripe_size(struct mddev  *mddev, const char *page, size_t len)
        struct r5conf *conf;
        unsigned long new;
        int err;
+       int size;
 
        if (len >= PAGE_SIZE)
                return -EINVAL;
@@ -6714,10 +6715,29 @@ raid5_store_stripe_size(struct mddev  *mddev, const char *page, size_t len)
        pr_debug("md/raid: change stripe_size from %lu to %lu\n",
                        conf->stripe_size, new);
 
+       if (mddev->sync_thread ||
+               test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+               mddev->reshape_position != MaxSector ||
+               mddev->sysfs_active) {
+               err = -EBUSY;
+               goto out_unlock;
+       }
+
        mddev_suspend(mddev);
+       mutex_lock(&conf->cache_size_mutex);
+       size = conf->max_nr_stripes;
+
+       shrink_stripes(conf);
+
        conf->stripe_size = new;
        conf->stripe_shift = ilog2(new) - 9;
        conf->stripe_sectors = new >> 9;
+       if (grow_stripes(conf, size)) {
+               pr_warn("md/raid:%s: couldn't allocate buffers\n",
+                               mdname(mddev));
+               err = -ENOMEM;
+       }
+       mutex_unlock(&conf->cache_size_mutex);
        mddev_resume(mddev);
 
 out_unlock: