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]>

Reply via email to