Commit 725d6e57 authored by NeilBrown's avatar NeilBrown

md/raid10: check In_sync flag in 'enough()'.

It isn't really enough to check that the rdev is present, we need to
also be sure that the device is still In_sync.

Doing this requires using rcu_dereference to access the rdev, and
holding the rcu_read_lock() to ensure the rdev doesn't disappear while
we look at it.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 635f6416
...@@ -1633,6 +1633,7 @@ static void status(struct seq_file *seq, struct mddev *mddev) ...@@ -1633,6 +1633,7 @@ static void status(struct seq_file *seq, struct mddev *mddev)
static int _enough(struct r10conf *conf, int previous, int ignore) static int _enough(struct r10conf *conf, int previous, int ignore)
{ {
int first = 0; int first = 0;
int has_enough = 0;
int disks, ncopies; int disks, ncopies;
if (previous) { if (previous) {
disks = conf->prev.raid_disks; disks = conf->prev.raid_disks;
...@@ -1642,21 +1643,27 @@ static int _enough(struct r10conf *conf, int previous, int ignore) ...@@ -1642,21 +1643,27 @@ static int _enough(struct r10conf *conf, int previous, int ignore)
ncopies = conf->geo.near_copies; ncopies = conf->geo.near_copies;
} }
rcu_read_lock();
do { do {
int n = conf->copies; int n = conf->copies;
int cnt = 0; int cnt = 0;
int this = first; int this = first;
while (n--) { while (n--) {
if (conf->mirrors[this].rdev && struct md_rdev *rdev;
this != ignore) if (this != ignore &&
(rdev = rcu_dereference(conf->mirrors[this].rdev)) &&
test_bit(In_sync, &rdev->flags))
cnt++; cnt++;
this = (this+1) % disks; this = (this+1) % disks;
} }
if (cnt == 0) if (cnt == 0)
return 0; goto out;
first = (first + ncopies) % disks; first = (first + ncopies) % disks;
} while (first != 0); } while (first != 0);
return 1; has_enough = 1;
out:
rcu_read_unlock();
return has_enough;
} }
static int enough(struct r10conf *conf, int ignore) static int enough(struct r10conf *conf, int ignore)
......
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