summaryrefslogtreecommitdiffstats
path: root/drivers/md/multipath.c
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2016-07-28 18:34:14 +0200
committerShaohua Li <shli@fb.com>2016-07-28 18:34:14 +0200
commit3f35e210ed4617a68b6baa9b7ac6c72bf7e313d9 (patch)
tree2cce851a454be4deea141593c3db62001ab65108 /drivers/md/multipath.c
parentAdd braces to avoid "ambiguous ‘else’" compiler warnings (diff)
parentMD: fix null pointer deference (diff)
downloadlinux-3f35e210ed4617a68b6baa9b7ac6c72bf7e313d9.tar.xz
linux-3f35e210ed4617a68b6baa9b7ac6c72bf7e313d9.zip
Merge branch 'mymd/for-next' into mymd/for-linus
Diffstat (limited to 'drivers/md/multipath.c')
-rw-r--r--drivers/md/multipath.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 72ea98e89e57..4974682842ae 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -43,7 +43,8 @@ static int multipath_map (struct mpconf *conf)
rcu_read_lock();
for (i = 0; i < disks; i++) {
struct md_rdev *rdev = rcu_dereference(conf->multipaths[i].rdev);
- if (rdev && test_bit(In_sync, &rdev->flags)) {
+ if (rdev && test_bit(In_sync, &rdev->flags) &&
+ !test_bit(Faulty, &rdev->flags)) {
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
return i;
@@ -141,17 +142,19 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
return;
}
-static void multipath_status (struct seq_file *seq, struct mddev *mddev)
+static void multipath_status(struct seq_file *seq, struct mddev *mddev)
{
struct mpconf *conf = mddev->private;
int i;
seq_printf (seq, " [%d/%d] [", conf->raid_disks,
conf->raid_disks - mddev->degraded);
- for (i = 0; i < conf->raid_disks; i++)
- seq_printf (seq, "%s",
- conf->multipaths[i].rdev &&
- test_bit(In_sync, &conf->multipaths[i].rdev->flags) ? "U" : "_");
+ rcu_read_lock();
+ for (i = 0; i < conf->raid_disks; i++) {
+ struct md_rdev *rdev = rcu_dereference(conf->multipaths[i].rdev);
+ seq_printf (seq, "%s", rdev && test_bit(In_sync, &rdev->flags) ? "U" : "_");
+ }
+ rcu_read_unlock();
seq_printf (seq, "]");
}
@@ -295,12 +298,14 @@ static int multipath_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
goto abort;
}
p->rdev = NULL;
- synchronize_rcu();
- if (atomic_read(&rdev->nr_pending)) {
- /* lost the race, try later */
- err = -EBUSY;
- p->rdev = rdev;
- goto abort;
+ if (!test_bit(RemoveSynchronized, &rdev->flags)) {
+ synchronize_rcu();
+ if (atomic_read(&rdev->nr_pending)) {
+ /* lost the race, try later */
+ err = -EBUSY;
+ p->rdev = rdev;
+ goto abort;
+ }
}
err = md_integrity_register(mddev);
}