diff options
author | NeilBrown <neilb@suse.com> | 2016-06-02 08:19:53 +0200 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2016-06-13 20:54:21 +0200 |
commit | f5b67ae86ee317db20c0e10d54f16a0bbbd3207d (patch) | |
tree | 8db4539e9c9f05624f2b198ddd1ccce54b281ce6 /drivers/md/raid5.c | |
parent | md/multipath: add rcu protection to rdev access in multipath_status. (diff) | |
download | linux-f5b67ae86ee317db20c0e10d54f16a0bbbd3207d.tar.xz linux-f5b67ae86ee317db20c0e10d54f16a0bbbd3207d.zip |
md: be extra careful not to take a reference to a Faulty device.
It is important that we never increment rdev->nr_pending on a Faulty
device as ->hot_remove_disk() assumes that once the Faulty flag is visible
no code will take a new reference.
Some places take a new reference after only check In_sync. This should
be safe as the two are changed together. However to make the code more
obviously safe, add checks for 'Faulty' as well.
Note: the actual rule is:
Never increment nr_pending if Faulty is set and Blocked is clear,
never clear Faulty, and never set Blocked without holding a reference
through nr_pending.
fix build error (Shaohua)
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c07b22e8d946..f6a191aaaa91 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3080,7 +3080,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, struct md_rdev *rdev; rcu_read_lock(); rdev = rcu_dereference(conf->disks[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); else rdev = NULL; |