From: Yu Kuai <yuku...@huawei.com>

This flag is used by llbitmap in later patches to skip raid456 initial
recover and delay building initial xor data to first write.

Signed-off-by: Yu Kuai <yuku...@huawei.com>
---
 drivers/md/md.c | 12 +++++++++++-
 drivers/md/md.h |  2 ++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index c23ee9c19cf9..a5dd7a403ea5 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -9133,6 +9133,14 @@ static sector_t md_sync_position(struct mddev *mddev, 
enum sync_action action)
                                start = rdev->recovery_offset;
                rcu_read_unlock();
 
+               /*
+                * If there are no spares, and raid456 lazy initial recover is
+                * requested.
+                */
+               if (test_bit(MD_RECOVERY_LAZY_RECOVER, &mddev->recovery) &&
+                   start == MaxSector)
+                       start = 0;
+
                /* If there is a bitmap, we need to make sure all
                 * writes that started before we added a spare
                 * complete before we start doing a recovery.
@@ -9697,6 +9705,7 @@ static bool md_choose_sync_action(struct mddev *mddev, 
int *spares)
        if (mddev->recovery_cp < MaxSector) {
                set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
                clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
+               clear_bit(MD_RECOVERY_LAZY_RECOVER, &mddev->recovery);
                return true;
        }
 
@@ -9706,7 +9715,7 @@ static bool md_choose_sync_action(struct mddev *mddev, 
int *spares)
         * re-add.
         */
        *spares = remove_and_add_spares(mddev, NULL);
-       if (*spares) {
+       if (*spares || test_bit(MD_RECOVERY_LAZY_RECOVER, &mddev->recovery)) {
                clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
                clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
                clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
@@ -10029,6 +10038,7 @@ void md_reap_sync_thread(struct mddev *mddev)
        clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
        clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
        clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+       clear_bit(MD_RECOVERY_LAZY_RECOVER, &mddev->recovery);
        /*
         * We call mddev->cluster_ops->update_size here because sync_size could
         * be changed by md_update_sb, and MD_RECOVERY_RESHAPE is cleared,
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 99f6c7a92b48..0c89bf0e8e4f 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -667,6 +667,8 @@ enum recovery_flags {
        MD_RECOVERY_RESHAPE,
        /* remote node is running resync thread */
        MD_RESYNCING_REMOTE,
+       /* raid456 lazy initial recover */
+       MD_RECOVERY_LAZY_RECOVER,
 };
 
 enum md_ro_state {
-- 
2.39.2


Reply via email to