summaryrefslogtreecommitdiff
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorYufen Yu <yuyufen@huawei.com>2020-08-20 09:22:14 -0400
committerSong Liu <songliubraving@fb.com>2020-09-24 16:44:45 -0700
commit389125844352c784abf8c186589343466d03cd6a (patch)
treee61e0098e77815ca7409f83d8c7e6baeadfe50e6 /drivers/md/raid5.c
parentf16acaf328c5615fdaea74f9bd0b4019544532d6 (diff)
md/raid5: reallocate page array after setting new stripe_size
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>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index c23e408f7623..66690b40818e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -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: