Skip to content

Commit 760a54a

Browse files
Ming Leikawasaki
authored andcommitted
block: account for bi_bvec_done in bio_may_need_split()
When checking if a bio fits in a single segment, bio_may_need_split() compares bi_size against the current bvec's bv_len. However, for partially consumed bvecs (bi_bvec_done > 0), such as in cloned or split bios, the remaining bytes in the current bvec is actually (bv_len - bi_bvec_done), not bv_len. This could cause bio_may_need_split() to incorrectly return false, leading to nr_phys_segments being set to 1 when the bio actually spans multiple segments. This triggers the WARN_ON in __blk_rq_map_sg() when the actual mapped segments exceed the expected count. Fix by subtracting bi_bvec_done from bv_len in the comparison. Reported-by: Venkat Rao Bagalkote <[email protected]> Close: https://lore.kernel.org/linux-block/[email protected]/ Repored-and-bisected-by: Christoph Hellwig <[email protected]> Tested-by: Venkat Rao Bagalkote <[email protected]> Tested-by: Christoph Hellwig <[email protected]> Fixes: ee623c8 ("block: use bvec iterator helper for bio_may_need_split()") Cc: Nitesh Shetty <[email protected]> Signed-off-by: Ming Lei <[email protected]>
1 parent 2b94c1f commit 760a54a

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

block/blk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static inline bool bio_may_need_split(struct bio *bio,
380380
return true;
381381

382382
bv = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter);
383-
if (bio->bi_iter.bi_size > bv->bv_len)
383+
if (bio->bi_iter.bi_size > bv->bv_len - bio->bi_iter.bi_bvec_done)
384384
return true;
385385
return bv->bv_len + bv->bv_offset > lim->max_fast_segment_size;
386386
}

0 commit comments

Comments
 (0)