At endio time, bio->bi_iter is no longer valid (there are some cases they are still valid, but never ensured). Thus if we really want to get the full size of bio, we have to iterate them. In btrfs_end_dio_bio() when we hit error, we would grab bio size from bi_iter which can be wrong. Fix it by iterating the bvecs and calculate the bio size. Signed-off-by: Qu Wenruo <wqu@xxxxxxxx> --- fs/btrfs/inode.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6079d30f83e8..126d2117954c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8175,12 +8175,19 @@ static void btrfs_end_dio_bio(struct bio *bio) struct btrfs_dio_private *dip = bio->bi_private; blk_status_t err = bio->bi_status; - if (err) + if (err) { + struct bvec_iter_all iter_all; + struct bio_vec *bvec; + u32 bi_size = 0; + + bio_for_each_segment_all(bvec, bio, iter_all) + bi_size += bvec->bv_len; + btrfs_warn(BTRFS_I(dip->inode)->root->fs_info, "direct IO failed ino %llu rw %d,%u sector %#Lx len %u err no %d", btrfs_ino(BTRFS_I(dip->inode)), bio_op(bio), - bio->bi_opf, bio->bi_iter.bi_sector, - bio->bi_iter.bi_size, err); + bio->bi_opf, bio->bi_iter.bi_sector, bi_size, err); + } if (bio_op(bio) == REQ_OP_READ) err = btrfs_check_read_dio_bio(dip, btrfs_bio(bio), !err); -- 2.34.1