summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-01-14 09:14:33 +1100
committerNeilBrown <neilb@suse.de>2011-01-14 09:14:33 +1100
commitdefad61a5b16352d3e22a04d4c930a5b5a7fd1f0 (patch)
treec353bd036c12011d0eee7f7924c230888fd34b0a
parent43c73ca43b3e03bb228ff9350b6b44d0e560f262 (diff)
downloadlinux-defad61a5b16352d3e22a04d4c930a5b5a7fd1f0.tar.gz
linux-defad61a5b16352d3e22a04d4c930a5b5a7fd1f0.tar.bz2
linux-defad61a5b16352d3e22a04d4c930a5b5a7fd1f0.zip
md: md_stop_writes requires mddev_lock.
As md_stop_writes manipulates the sync_thread and calls md_update_sb, it need to be called with mddev_lock held. In all internal cases it is, but the symbol is exported for dm-raid to call and in that case the lock won't be help. Do make an exported version which takes the lock, and an internal version which does not. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/md.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 540347c538f9..f43ff2962b2b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4704,7 +4704,7 @@ static void md_clean(mddev_t *mddev)
mddev->plug = NULL;
}
-void md_stop_writes(mddev_t *mddev)
+static void __md_stop_writes(mddev_t *mddev)
{
if (mddev->sync_thread) {
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -4724,6 +4724,13 @@ void md_stop_writes(mddev_t *mddev)
md_update_sb(mddev, 1);
}
}
+
+void md_stop_writes(mddev_t *mddev)
+{
+ mddev_lock(mddev);
+ __md_stop_writes(mddev);
+ mddev_unlock(mddev);
+}
EXPORT_SYMBOL_GPL(md_stop_writes);
void md_stop(mddev_t *mddev)
@@ -4748,7 +4755,7 @@ static int md_set_readonly(mddev_t *mddev, int is_open)
goto out;
}
if (mddev->pers) {
- md_stop_writes(mddev);
+ __md_stop_writes(mddev);
err = -ENXIO;
if (mddev->ro==1)
@@ -4785,7 +4792,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
if (mddev->ro)
set_disk_ro(disk, 0);
- md_stop_writes(mddev);
+ __md_stop_writes(mddev);
md_stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;