diff options
author | Yu Kuai <yukuai3@huawei.com> | 2023-08-25 11:16:19 +0800 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2023-09-22 10:28:25 -0700 |
commit | 3389d57f97531efe9e285a0740c9b767d6f29f6c (patch) | |
tree | 8eb7ac17734800c32e9b01bed26b032aeaeb115c /drivers/md | |
parent | db5e653d7c9fae8ed61da58ab5e9a8db2cd61a2b (diff) | |
download | linux-3389d57f97531efe9e285a0740c9b767d6f29f6c.tar.gz linux-3389d57f97531efe9e285a0740c9b767d6f29f6c.tar.bz2 linux-3389d57f97531efe9e285a0740c9b767d6f29f6c.zip |
md: factor out a helper rdev_removeable() from remove_and_add_spares()
There are no functional changes, just to make the code simpler and
prepare to delay remove_and_add_spares() to md_start_sync().
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20230825031622.1530464-5-yukuai1@huaweicloud.com
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 52fe795f9011..3118ab26cef6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9164,6 +9164,42 @@ void md_do_sync(struct md_thread *thread) } EXPORT_SYMBOL_GPL(md_do_sync); +static bool rdev_removeable(struct md_rdev *rdev) +{ + /* rdev is not used. */ + if (rdev->raid_disk < 0) + return false; + + /* There are still inflight io, don't remove this rdev. */ + if (atomic_read(&rdev->nr_pending)) + return false; + + /* + * An error occurred but has not yet been acknowledged by the metadata + * handler, don't remove this rdev. + */ + if (test_bit(Blocked, &rdev->flags)) + return false; + + /* Fautly rdev is not used, it's safe to remove it. */ + if (test_bit(Faulty, &rdev->flags)) + return true; + + /* Journal disk can only be removed if it's faulty. */ + if (test_bit(Journal, &rdev->flags)) + return false; + + /* + * 'In_sync' is cleared while 'raid_disk' is valid, which means + * replacement has just become active from pers->spare_active(), and + * then pers->hot_remove_disk() will replace this rdev with replacement. + */ + if (!test_bit(In_sync, &rdev->flags)) + return true; + + return false; +} + static int remove_and_add_spares(struct mddev *mddev, struct md_rdev *this) { @@ -9196,12 +9232,8 @@ static int remove_and_add_spares(struct mddev *mddev, synchronize_rcu(); rdev_for_each(rdev, mddev) { if ((this == NULL || rdev == this) && - rdev->raid_disk >= 0 && - !test_bit(Blocked, &rdev->flags) && - ((test_bit(RemoveSynchronized, &rdev->flags) || - (!test_bit(In_sync, &rdev->flags) && - !test_bit(Journal, &rdev->flags))) && - atomic_read(&rdev->nr_pending)==0)) { + (test_bit(RemoveSynchronized, &rdev->flags) || + rdev_removeable(rdev))) { if (mddev->pers->hot_remove_disk( mddev, rdev) == 0) { sysfs_unlink_rdev(mddev, rdev); |