aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-core.h
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2022-06-23 21:20:05 +0800
committerMike Snitzer <snitzer@kernel.org>2022-06-23 14:33:13 -0400
commit61b6e2e5321da281ab3c0c04e1962b3d000f6248 (patch)
tree0e3d4eb1c7d51ca0b95232075b68b2ddb4b13760 /drivers/md/dm-core.h
parentdm: do not return early from dm_io_complete if BLK_STS_AGAIN without polling (diff)
downloadlinux-dev-61b6e2e5321da281ab3c0c04e1962b3d000f6248.tar.xz
linux-dev-61b6e2e5321da281ab3c0c04e1962b3d000f6248.zip
dm: fix BLK_STS_DM_REQUEUE handling when dm_io represents split bio
Commit 7dd76d1feec7 ("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: 7dd76d1feec7 ("dm: improve bio splitting and associated IO accounting") Reported-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Diffstat (limited to 'drivers/md/dm-core.h')
-rw-r--r--drivers/md/dm-core.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
index 54c0473a51dd..c954ff91870e 100644
--- a/drivers/md/dm-core.h
+++ b/drivers/md/dm-core.h
@@ -272,6 +272,7 @@ struct dm_io {
atomic_t io_count;
struct mapped_device *md;
+ struct bio *split_bio;
/* The three fields represent mapped part of original bio */
struct bio *orig_bio;
unsigned int sector_offset; /* offset to end of orig_bio */