On Sat, Apr 06, 2019 at 09:53:07AM +0800, Qu Wenruo wrote: > Hi, > > I'm looking into a strange behavior that we can't break > bio_for_each_segment_all() after commit 6dc4f100c175 ("block: allow > bio_for_each_segment_all() to iterate over multi-page bvec"). > > It's screwing up all bio_for_each_segment_all() call with error out branch. > > > There is one relatively easy to trigger setup. > > Here is my kernel branch, which is based on David Sterb's misc-next branch: > https://github.com/adam900710/linux/tree/tree_checker_testing > > It's just two commits ahead. > > Then some debug diff: > > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c > index c2c0640aea55..05c880a5254b 100644 > --- a/fs/btrfs/disk-io.c > +++ b/fs/btrfs/disk-io.c > @@ -851,16 +851,22 @@ static blk_status_t btree_csum_one_bio(struct bio > *bio) > struct bio_vec *bvec; > struct btrfs_root *root; > int i, ret = 0; > + int err = 0; > struct bvec_iter_all iter_all; > > ASSERT(!bio_flagged(bio, BIO_CLONED)); > bio_for_each_segment_all(bvec, bio, i, iter_all) { > root = BTRFS_I(bvec->bv_page->mapping->host)->root; > ret = csum_dirty_buffer(root->fs_info, bvec->bv_page); > - if (ret) > + if (ret) { > + err = ret; > + pr_info("breaking out with ret=%d\n", ret); > break; > + } > } > > + if (err) > + pr_info("err=%d out, but ret=%d\n",err, ret); > return errno_to_blk_status(ret); > } > > Straightforward, if we break, we should have err == ret. > Thanks for the report, and it should be easy to fix, will post patch soon. Thanks, Ming