diff options
author | Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> | 2022-04-15 17:45:13 +0900 |
---|---|---|
committer | Mike Snitzer <snitzer@kernel.org> | 2022-04-15 16:16:09 -0400 |
commit | 92b914e29af3e99589f2d2876616c0b534892ed4 (patch) | |
tree | 88be1698935aecf7d069367065459eb5e6514c6f | |
parent | 7dd06a2548b2bf516ef2e79873a9cdd00b354b99 (diff) |
dm: fix bio length of empty flush
The commit 92986f6b4c8a ("dm: use bio_clone_fast in alloc_io/alloc_tio")
removed bio_clone_fast() call from alloc_tio() when ci->io->tio is
available. In this case, ci->bio is not copied to ci->io->tio.clone.
This is fine since init_clone_info() sets same values to ci->bio and
ci->io->tio.clone.
However, when incoming bios have REQ_PREFLUSH flag, __send_empty_flush()
prepares a zero length bio on stack and set it to ci->bio. At this time,
ci->io->tio.clone still keeps non-zero length. When alloc_tio() chooses
this ci->io->tio.clone as the bio to map, it is passed to targets as
non-empty flush bio. It causes bio length check failure in dm-zoned and
unexpected operation such as dm_accept_partial_bio() call.
To avoid the non-empty flush bio, set zero length to ci->io->tio.clone
in __send_empty_flush().
Fixes: 92986f6b4c8a ("dm: use bio_clone_fast in alloc_io/alloc_tio")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
-rw-r--r-- | drivers/md/dm.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index fc1f9583a271..82957bd460e8 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1391,6 +1391,7 @@ static void __send_empty_flush(struct clone_info *ci) ci->bio = &flush_bio; ci->sector_count = 0; + ci->io->tio.clone.bi_iter.bi_size = 0; while ((ti = dm_table_get_target(ci->map, target_nr++))) __send_duplicate_bios(ci, ti, ti->num_flush_bios, NULL); |