Commit 6791875e authored by NeilBrown's avatar NeilBrown

md: make reconfig_mutex optional for writes to md sysfs files.

Rather than using mddev_lock() to take the reconfig_mutex
when writing to any md sysfs file, we only take mddev_lock()
in the particular _store() functions that require it.
Admittedly this is most, but it isn't all.

This also allows us to remove special-case handling for new_dev_store
(in md_attr_store).
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 5c47daf6
This diff is collapsed.
...@@ -5400,21 +5400,25 @@ EXPORT_SYMBOL(raid5_set_cache_size); ...@@ -5400,21 +5400,25 @@ EXPORT_SYMBOL(raid5_set_cache_size);
static ssize_t static ssize_t
raid5_store_stripe_cache_size(struct mddev *mddev, const char *page, size_t len) raid5_store_stripe_cache_size(struct mddev *mddev, const char *page, size_t len)
{ {
struct r5conf *conf = mddev->private; struct r5conf *conf;
unsigned long new; unsigned long new;
int err; int err;
if (len >= PAGE_SIZE) if (len >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
if (!conf)
return -ENODEV;
if (kstrtoul(page, 10, &new)) if (kstrtoul(page, 10, &new))
return -EINVAL; return -EINVAL;
err = raid5_set_cache_size(mddev, new); err = mddev_lock(mddev);
if (err) if (err)
return err; return err;
return len; conf = mddev->private;
if (!conf)
err = -ENODEV;
else
err = raid5_set_cache_size(mddev, new);
mddev_unlock(mddev);
return err ?: len;
} }
static struct md_sysfs_entry static struct md_sysfs_entry
...@@ -5438,19 +5442,27 @@ raid5_show_preread_threshold(struct mddev *mddev, char *page) ...@@ -5438,19 +5442,27 @@ raid5_show_preread_threshold(struct mddev *mddev, char *page)
static ssize_t static ssize_t
raid5_store_preread_threshold(struct mddev *mddev, const char *page, size_t len) raid5_store_preread_threshold(struct mddev *mddev, const char *page, size_t len)
{ {
struct r5conf *conf = mddev->private; struct r5conf *conf;
unsigned long new; unsigned long new;
int err;
if (len >= PAGE_SIZE) if (len >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
if (!conf)
return -ENODEV;
if (kstrtoul(page, 10, &new)) if (kstrtoul(page, 10, &new))
return -EINVAL; return -EINVAL;
if (new > conf->max_nr_stripes)
return -EINVAL; err = mddev_lock(mddev);
conf->bypass_threshold = new; if (err)
return len; return err;
conf = mddev->private;
if (!conf)
err = -ENODEV;
else if (new > conf->max_nr_stripes)
err = -EINVAL;
else
conf->bypass_threshold = new;
mddev_unlock(mddev);
return err ?: len;
} }
static struct md_sysfs_entry static struct md_sysfs_entry
...@@ -5475,29 +5487,35 @@ raid5_show_skip_copy(struct mddev *mddev, char *page) ...@@ -5475,29 +5487,35 @@ raid5_show_skip_copy(struct mddev *mddev, char *page)
static ssize_t static ssize_t
raid5_store_skip_copy(struct mddev *mddev, const char *page, size_t len) raid5_store_skip_copy(struct mddev *mddev, const char *page, size_t len)
{ {
struct r5conf *conf = mddev->private; struct r5conf *conf;
unsigned long new; unsigned long new;
int err;
if (len >= PAGE_SIZE) if (len >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
if (!conf)
return -ENODEV;
if (kstrtoul(page, 10, &new)) if (kstrtoul(page, 10, &new))
return -EINVAL; return -EINVAL;
new = !!new; new = !!new;
if (new == conf->skip_copy)
return len;
mddev_suspend(mddev); err = mddev_lock(mddev);
conf->skip_copy = new; if (err)
if (new) return err;
mddev->queue->backing_dev_info.capabilities |= conf = mddev->private;
BDI_CAP_STABLE_WRITES; if (!conf)
else err = -ENODEV;
mddev->queue->backing_dev_info.capabilities &= else if (new != conf->skip_copy) {
~BDI_CAP_STABLE_WRITES; mddev_suspend(mddev);
mddev_resume(mddev); conf->skip_copy = new;
return len; if (new)
mddev->queue->backing_dev_info.capabilities |=
BDI_CAP_STABLE_WRITES;
else
mddev->queue->backing_dev_info.capabilities &=
~BDI_CAP_STABLE_WRITES;
mddev_resume(mddev);
}
mddev_unlock(mddev);
return err ?: len;
} }
static struct md_sysfs_entry static struct md_sysfs_entry
...@@ -5538,7 +5556,7 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt, ...@@ -5538,7 +5556,7 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt,
static ssize_t static ssize_t
raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len) raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
{ {
struct r5conf *conf = mddev->private; struct r5conf *conf;
unsigned long new; unsigned long new;
int err; int err;
struct r5worker_group *new_groups, *old_groups; struct r5worker_group *new_groups, *old_groups;
...@@ -5546,41 +5564,41 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len) ...@@ -5546,41 +5564,41 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
if (len >= PAGE_SIZE) if (len >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
if (!conf)
return -ENODEV;
if (kstrtoul(page, 10, &new)) if (kstrtoul(page, 10, &new))
return -EINVAL; return -EINVAL;
if (new == conf->worker_cnt_per_group) err = mddev_lock(mddev);
return len; if (err)
return err;
mddev_suspend(mddev); conf = mddev->private;
if (!conf)
err = -ENODEV;
else if (new != conf->worker_cnt_per_group) {
mddev_suspend(mddev);
old_groups = conf->worker_groups; old_groups = conf->worker_groups;
if (old_groups) if (old_groups)
flush_workqueue(raid5_wq); flush_workqueue(raid5_wq);
err = alloc_thread_groups(conf, new, err = alloc_thread_groups(conf, new,
&group_cnt, &worker_cnt_per_group, &group_cnt, &worker_cnt_per_group,
&new_groups); &new_groups);
if (!err) { if (!err) {
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
conf->group_cnt = group_cnt; conf->group_cnt = group_cnt;
conf->worker_cnt_per_group = worker_cnt_per_group; conf->worker_cnt_per_group = worker_cnt_per_group;
conf->worker_groups = new_groups; conf->worker_groups = new_groups;
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
if (old_groups) if (old_groups)
kfree(old_groups[0].workers); kfree(old_groups[0].workers);
kfree(old_groups); kfree(old_groups);
}
mddev_resume(mddev);
} }
mddev_unlock(mddev);
mddev_resume(mddev); return err ?: len;
if (err)
return err;
return len;
} }
static struct md_sysfs_entry static struct md_sysfs_entry
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment