aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2016-06-02 02:19:52 -0400
committerShaohua Li <shli@fb.com>2016-06-13 14:54:19 -0400
commit3f232d6a95fc0fe539e0855ee7f3854b03c8104e (patch)
treed8b5c58c05ff9c69b2f79d29cfcbdf665f0bf734 /drivers/md
parente50d3992328320acf2454c1e7301a094cd90aebc (diff)
md/raid5: add rcu protection to rdev accesses in want_replace
Being in the middle of resync is no longer protection against failed rdevs disappearing. So add rcu protection. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid5.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e56c7e0627fa..198b2a9eef98 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3239,15 +3239,16 @@ static int want_replace(struct stripe_head *sh, int disk_idx)
3239{ 3239{
3240 struct md_rdev *rdev; 3240 struct md_rdev *rdev;
3241 int rv = 0; 3241 int rv = 0;
3242 /* Doing recovery so rcu locking not required */ 3242
3243 rdev = sh->raid_conf->disks[disk_idx].replacement; 3243 rcu_read_lock();
3244 rdev = rcu_dereference(sh->raid_conf->disks[disk_idx].replacement);
3244 if (rdev 3245 if (rdev
3245 && !test_bit(Faulty, &rdev->flags) 3246 && !test_bit(Faulty, &rdev->flags)
3246 && !test_bit(In_sync, &rdev->flags) 3247 && !test_bit(In_sync, &rdev->flags)
3247 && (rdev->recovery_offset <= sh->sector 3248 && (rdev->recovery_offset <= sh->sector
3248 || rdev->mddev->recovery_cp <= sh->sector)) 3249 || rdev->mddev->recovery_cp <= sh->sector))
3249 rv = 1; 3250 rv = 1;
3250 3251 rcu_read_unlock();
3251 return rv; 3252 return rv;
3252} 3253}
3253 3254