diff options
author | NeilBrown <neilb@suse.com> | 2016-06-02 02:19:52 -0400 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2016-06-13 14:54:19 -0400 |
commit | 3f232d6a95fc0fe539e0855ee7f3854b03c8104e (patch) | |
tree | d8b5c58c05ff9c69b2f79d29cfcbdf665f0bf734 /drivers/md | |
parent | e50d3992328320acf2454c1e7301a094cd90aebc (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.c | 7 |
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 | ||