• Ming Lei's avatar
    dm: fix BLK_STS_DM_REQUEUE handling when dm_io represents split bio · 61b6e2e5
    Ming Lei authored
    Commit 7dd76d1f ("dm: improve bio splitting and associated IO
    accounting") removed using cloned bio when dm io splitting is needed.
    Using bio_trim()+bio_inc_remaining() rather than bio_split()+bio_chain()
    causes multiple dm_io instances to share the same original bio, and it
    works fine if IOs are completed successfully.
    
    But a regression was caused for the case when BLK_STS_DM_REQUEUE is
    returned from any one of DM's cloned bios (whose dm_io share the same
    orig_bio). In this BLK_STS_DM_REQUEUE case only the mapped subset of
    the original bio for the current exact dm_io needs to be re-submitted.
    However, since the original bio is shared among all dm_io instances,
    the ->orig_bio actually only represents the last dm_io instance, so
    requeue can't work as expected. Also when more than one dm_io is
    requeued, the same original bio is requeued from all dm_io's
    completion handler, then race is caused.
    
    Fix this issue by still allocating one clone bio for completing io
    only, then io accounting can rely on ->orig_bio being unmodified. This
    is needed because the dm_io's sector_offset and sectors members are
    recorded relative to an unmodified ->orig_bio.
    
    In the future, we can go back to using bio_trim()+bio_inc_remaining()
    for dm's io splitting but then delay needing a bio clone only when
    handling BLK_STS_DM_REQUEUE, but that approach is a bit complicated
    (so it needs a development cycle):
    1) bio clone needs to be done in task context
    2) a block interface for unwinding bio is required
    
    Fixes: 7dd76d1f ("dm: improve bio splitting and associated IO accounting")
    Reported-by: default avatarBenjamin Marzinski <bmarzins@redhat.com>
    Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
    Signed-off-by: default avatarMike Snitzer <snitzer@kernel.org>
    61b6e2e5
dm.c 75.7 KB