diff options
author | Li Nan <linan122@huawei.com> | 2023-07-01 10:05:29 +0200 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2023-07-27 09:13:30 +0200 |
commit | 673643490b9a0eb3b25633abe604f62b8f63dba1 (patch) | |
tree | cb2f1857aacb43328b738fe6598eda3609d8e360 /drivers/md | |
parent | md/raid10: factor out dereference_rdev_and_rrdev() (diff) | |
download | linux-673643490b9a0eb3b25633abe604f62b8f63dba1.tar.xz linux-673643490b9a0eb3b25633abe604f62b8f63dba1.zip |
md/raid10: use dereference_rdev_and_rrdev() to get devices
Commit 2ae6aaf76912 ("md/raid10: fix io loss while replacement replace
rdev") reads replacement first to prevent io loss. However, there are same
issue in wait_blocked_dev() and raid10_handle_discard(), too. Fix it by
using dereference_rdev_and_rrdev() to get devices.
Fixes: d30588b2731f ("md/raid10: improve raid10 discard request")
Fixes: f2e7e269a752 ("md/raid10: pull the code that wait for blocked dev into one function")
Signed-off-by: Li Nan <linan122@huawei.com>
Link: https://lore.kernel.org/r/20230701080529.2684932-4-linan666@huaweicloud.com
Signed-off-by: Song Liu <song@kernel.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid10.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d21aeb9546d9..16aa9d735880 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1350,11 +1350,9 @@ retry_wait: blocked_rdev = NULL; rcu_read_lock(); for (i = 0; i < conf->copies; i++) { - struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[i].replacement); - if (rdev == rrdev) - rrdev = NULL; + struct md_rdev *rdev, *rrdev; + + rdev = dereference_rdev_and_rrdev(&conf->mirrors[i], &rrdev); if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { atomic_inc(&rdev->nr_pending); blocked_rdev = rdev; @@ -1789,15 +1787,12 @@ retry_discard: */ rcu_read_lock(); for (disk = 0; disk < geo->raid_disks; disk++) { - struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[disk].replacement); + struct md_rdev *rdev, *rrdev; + rdev = dereference_rdev_and_rrdev(&conf->mirrors[disk], &rrdev); r10_bio->devs[disk].bio = NULL; r10_bio->devs[disk].repl_bio = NULL; - if (rdev == rrdev) - rrdev = NULL; if (rdev && (test_bit(Faulty, &rdev->flags))) rdev = NULL; if (rrdev && (test_bit(Faulty, &rrdev->flags))) |