On Wed, Apr 29, 2026 at 7:20 AM Benjamin Marzinski <[email protected]> wrote:
>
> 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. We cannot handle the bio, and we
> cannot suspends while it is outstanding. But during normal operations,
> we should not push the bio back to dm. Instead, wait for the reshape
> to be resumed.
>
> Signed-off-by: Benjamin Marzinski <[email protected]>
> ---
>
> Changes from v1:
> - Track the dm device's suspending state in mddev->flags instead of
> adding a new integer to mddev.
>
> drivers/md/dm-raid.c | 6 ++++++
> drivers/md/md.h | 2 ++
> drivers/md/raid5.c | 7 +++++--
> 3 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
> index c5dc083c7244..8f5a5e1342a9 100644
> --- a/drivers/md/dm-raid.c
> +++ b/drivers/md/dm-raid.c
> @@ -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)
> diff --git a/drivers/md/md.h b/drivers/md/md.h
> index 52c378086046..9e5100609d12 100644
> --- a/drivers/md/md.h
> +++ b/drivers/md/md.h
> @@ -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 {
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 0d76e82f4506..65ae7d8930fc 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -6042,8 +6042,11 @@ static enum stripe_result make_stripe_request(struct
> mddev *mddev,
> 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;
> --
> 2.53.0
>
This patch looks good to me.
Reviewed-by: Xiao Ni <[email protected]>