]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
dm-raid: only requeue bios when dm is suspending
authorBenjamin Marzinski <bmarzins@redhat.com>
Tue, 28 Apr 2026 23:20:10 +0000 (19:20 -0400)
committerYu Kuai <yukuai@fygo.io>
Sun, 31 May 2026 11:09:17 +0000 (19:09 +0800)
Returning DM_MAPIO_REQUEUE from the target map() function only requeues
the bio during noflush suspends. During regular operations or during
flushing suspends, it fails the bio. Failing the bio during flushing
suspends is the correct behavior here. The bio cannot be handled, and
dm-raid cannot suspend while it is outstanding. But during normal
operations, dm-raid should not push the bio back to dm. Instead, wait
for the reshape to be resumed.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Xiao Ni <xiao@kernel.org>
Link: https://patch.msgid.link/20260428232010.2785514-1-bmarzins@redhat.com
Signed-off-by: Yu Kuai <yukuai@fygo.io>
drivers/md/dm-raid.c
drivers/md/md.h
drivers/md/raid5.c

index c5dc083c724416226cabceef42277d2fb4d57cd3..8f5a5e1342a956cb4173f596053fd84207c3435e 100644 (file)
@@ -3831,6 +3831,7 @@ static void raid_presuspend(struct dm_target *ti)
         * resume, raid_postsuspend() is too late.
         */
        set_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
+       set_bit(MD_DM_SUSPENDING, &mddev->flags);
 
        if (!reshape_interrupted(mddev))
                return;
@@ -3847,13 +3848,16 @@ static void raid_presuspend(struct dm_target *ti)
 static void raid_presuspend_undo(struct dm_target *ti)
 {
        struct raid_set *rs = ti->private;
+       struct mddev *mddev = &rs->md;
 
+       clear_bit(MD_DM_SUSPENDING, &mddev->flags);
        clear_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
 }
 
 static void raid_postsuspend(struct dm_target *ti)
 {
        struct raid_set *rs = ti->private;
+       struct mddev *mddev = &rs->md;
 
        if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
                /*
@@ -3864,6 +3868,8 @@ static void raid_postsuspend(struct dm_target *ti)
                mddev_suspend(&rs->md, false);
                rs->md.ro = MD_RDONLY;
        }
+       clear_bit(MD_DM_SUSPENDING, &mddev->flags);
+
 }
 
 static void attempt_restore_of_faulty_devices(struct raid_set *rs)
index 52c378086046467ae0a5f2780dd0a7024817057b..9e5100609d1208cc1f8f92f2a15bea7a375bdd3e 100644 (file)
@@ -346,6 +346,7 @@ struct md_cluster_operations;
  * @MD_HAS_SUPERBLOCK: There is persistence sb in member disks.
  * @MD_FAILLAST_DEV: Allow last rdev to be removed.
  * @MD_SERIALIZE_POLICY: Enforce write IO is not reordered, just used by raid1.
+ * @MD_DM_SUSPENDING: This DM raid device is suspending.
  *
  * change UNSUPPORTED_MDDEV_FLAGS for each array type if new flag is added
  */
@@ -365,6 +366,7 @@ enum mddev_flags {
        MD_HAS_SUPERBLOCK,
        MD_FAILLAST_DEV,
        MD_SERIALIZE_POLICY,
+       MD_DM_SUSPENDING,
 };
 
 enum mddev_sb_flags {
index 0d76e82f4506e694ae57fff88a7d632356df762f..65ae7d8930fcaa32366b5c573173d61c695b91cf 100644 (file)
@@ -6042,8 +6042,11 @@ out_release:
        raid5_release_stripe(sh);
 out:
        if (ret == STRIPE_SCHEDULE_AND_RETRY && reshape_interrupted(mddev)) {
-               bi->bi_status = BLK_STS_RESOURCE;
-               ret = STRIPE_WAIT_RESHAPE;
+               if (!mddev_is_dm(mddev) ||
+                   test_bit(MD_DM_SUSPENDING, &mddev->flags)) {
+                       bi->bi_status = BLK_STS_RESOURCE;
+                       ret = STRIPE_WAIT_RESHAPE;
+               }
                pr_err_ratelimited("dm-raid456: io across reshape position while reshape can't make progress");
        }
        return ret;