summaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorYu Kuai <yukuai3@huawei.com>2023-11-25 09:16:00 +0100
committerSong Liu <song@kernel.org>2023-11-28 00:49:04 +0100
commitc891f1fd90e66e584bb1353e1859cef7c9eb36f8 (patch)
tree564d8541ff7bc4be1145f85bb0ef194c833ea587 /drivers/md/raid5.c
parentRevert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d" (diff)
downloadlinux-c891f1fd90e66e584bb1353e1859cef7c9eb36f8.tar.xz
linux-c891f1fd90e66e584bb1353e1859cef7c9eb36f8.zip
md: remove flag RemoveSynchronized
rcu is not used correctly here, because synchronize_rcu() is called before replacing old value, for example: remove_and_add_spares // other path synchronize_rcu // called before replacing old value set_bit(RemoveSynchronized) rcu_read_lock() rdev = conf->mirros[].rdev pers->hot_remove_disk conf->mirros[].rdev = NULL; if (!test_bit(RemoveSynchronized)) synchronize_rcu /* * won't be called, and won't wait * for concurrent readers to be done. */ // access rdev after remove_and_add_spares() rcu_read_unlock() Fortunately, there is a separate rcu protection to prevent such rdev to be freed: md_kick_rdev_from_array //other path rcu_read_lock() rdev = conf->mirros[].rdev list_del_rcu(&rdev->same_set) rcu_read_unlock() /* * rdev can be removed from conf, but * rdev won't be freed. */ synchronize_rcu() free rdev Hence remove this useless flag and prepare to remove rcu protection to access rdev from 'conf'. Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20231125081604.3939938-2-yukuai1@huaweicloud.com
Diffstat (limited to '')
-rw-r--r--drivers/md/raid5.c9
1 files changed, 0 insertions, 9 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index fcc8a44dd4fd..d431e4625cc5 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -8233,15 +8233,6 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
goto abort;
}
*rdevp = NULL;
- if (!test_bit(RemoveSynchronized, &rdev->flags)) {
- lockdep_assert_held(&mddev->reconfig_mutex);
- synchronize_rcu();
- if (atomic_read(&rdev->nr_pending)) {
- /* lost the race, try later */
- err = -EBUSY;
- rcu_assign_pointer(*rdevp, rdev);
- }
- }
if (!err) {
err = log_modify(conf, rdev, false);
if (err)