md: delay remove_and_add_spares() for read only array to md_start_sync()
authorYu Kuai <yukuai3@huawei.com>
Fri, 25 Aug 2023 03:16:22 +0000 (11:16 +0800)
committerSong Liu <song@kernel.org>
Fri, 22 Sep 2023 17:28:26 +0000 (10:28 -0700)
commit81e2ce1b3d5a896e24fe5af83896fec057860a25
tree8fae9d9ebc89210535f083250536b112e9a241e6
parenta0ae7e4e0bc00ae178e42391157e8ddb88b2838a
md: delay remove_and_add_spares() for read only array to md_start_sync()

Before this patch, for read-only array:

md_check_recovery() check that 'MD_RECOVERY_NEEDED' is set, then it will
call remove_and_add_spares() directly to try to remove and add rdevs
from array.

After this patch:

1) md_check_recovery() check that 'MD_RECOVERY_NEEDED' is set, and the
   worker 'sync_work' is not pending, and there are rdevs can be added
   or removed, then it will queue new work md_start_sync();
2) md_start_sync() will call remove_and_add_spares() and exist;

This change make sure that array reconfiguration is independent from
daemon, and it'll be much easier to synchronize it with io, consier
that io may rely on daemon thread to be done.

Also fix a problem that 'pers->spars_active' is called after
remove_and_add_spares(), which order is wrong, because spares must
active first, and then remove_and_add_spares() can add spares to the
array, like what read-write case does:

1) daemon set 'MD_RECOVERY_RUNNING', register new sync thread to do
   recovery;
2) recovery is done, md_do_sync() set 'MD_RECOVERY_DONE' before return;
3) daemon call 'pers->spars_active', and clear 'MD_RECOVERY_RUNNING';
4) in the next round of daemon, call remove_and_add_spares() to add
   spares to the array.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20230825031622.1530464-8-yukuai1@huaweicloud.com
drivers/md/md.c