Message ID | 69a34ba773dd14f59b6220587029a09dbba3e104.1715688057.git.fdmanana@suse.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | btrfs: fix a bug in the direct IO write path for COW writes | expand |
在 2024/5/14 23:53, fdmanana@kernel.org 写道: > From: Filipe Manana <fdmanana@suse.com> > > Refactor btrfs_dio_submit_io() to avoid so much nesting and the need to > split long lines, making it a bit easier to read. > > Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Thanks, Qu > --- > fs/btrfs/inode.c | 52 +++++++++++++++++++++++------------------------- > 1 file changed, 25 insertions(+), 27 deletions(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index f04852e44123..c7f0239c3b68 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -7869,6 +7869,8 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, > struct btrfs_dio_private *dip = > container_of(bbio, struct btrfs_dio_private, bbio); > struct btrfs_dio_data *dio_data = iter->private; > + struct btrfs_ordered_extent *oe = dio_data->ordered; > + int ret; > > btrfs_bio_init(bbio, BTRFS_I(iter->inode)->root->fs_info, > btrfs_dio_end_io, bio->bi_private); > @@ -7880,6 +7882,8 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, > > dio_data->submitted += bio->bi_iter.bi_size; > > + if (!(iter->flags & IOMAP_WRITE)) > + goto submit_bio; > /* > * Check if we are doing a partial write. If we are, we need to split > * the ordered extent to match the submitted bio. Hang on to the > @@ -7887,37 +7891,31 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, > * cancelled in iomap_end to avoid a deadlock wherein faulting the > * remaining pages is blocked on the outstanding ordered extent. > */ > - if (iter->flags & IOMAP_WRITE) { > - struct btrfs_ordered_extent *oe = dio_data->ordered; > - int ret; > - > - ret = btrfs_extract_ordered_extent(bbio, oe); > - if (ret) { > - /* > - * If this is a COW write it means we created new extent > - * maps for the range and they point to an unwritten > - * location since we got an error and we don't submit > - * a bio. We must drop any extent maps within the range, > - * otherwise a fast fsync would log them and after a > - * crash and log replay we would have file extent items > - * that point to unwritten locations (garbage). > - */ > - if (!test_bit(BTRFS_ORDERED_NOCOW, &oe->flags)) { > - const u64 start = oe->file_offset; > - const u64 end = start + oe->num_bytes - 1; > + ret = btrfs_extract_ordered_extent(bbio, oe); > + if (!ret) > + goto submit_bio; > > - btrfs_drop_extent_map_range(bbio->inode, start, end, false); > - } > + /* > + * If this is a COW write it means we created new extent maps for the > + * range and they point to an unwritten location since we got an error > + * and we don't submit a bio. We must drop any extent maps within the > + * range, otherwise a fast fsync would log them and after a crash and > + * log replay we would have file extent items that point to unwritten > + * locations (garbage). > + */ > + if (!test_bit(BTRFS_ORDERED_NOCOW, &oe->flags)) { > + const u64 start = oe->file_offset; > + const u64 end = start + oe->num_bytes - 1; > > - btrfs_finish_ordered_extent(oe, NULL, > - file_offset, dip->bytes, > - !ret); > - bio->bi_status = errno_to_blk_status(ret); > - iomap_dio_bio_end_io(bio); > - return; > - } > + btrfs_drop_extent_map_range(bbio->inode, start, end, false); > } > > + btrfs_finish_ordered_extent(oe, NULL, file_offset, dip->bytes, false); > + bio->bi_status = errno_to_blk_status(ret); > + iomap_dio_bio_end_io(bio); > + return; > + > +submit_bio: > btrfs_submit_bio(bbio, 0); > } >
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f04852e44123..c7f0239c3b68 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7869,6 +7869,8 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, struct btrfs_dio_private *dip = container_of(bbio, struct btrfs_dio_private, bbio); struct btrfs_dio_data *dio_data = iter->private; + struct btrfs_ordered_extent *oe = dio_data->ordered; + int ret; btrfs_bio_init(bbio, BTRFS_I(iter->inode)->root->fs_info, btrfs_dio_end_io, bio->bi_private); @@ -7880,6 +7882,8 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, dio_data->submitted += bio->bi_iter.bi_size; + if (!(iter->flags & IOMAP_WRITE)) + goto submit_bio; /* * Check if we are doing a partial write. If we are, we need to split * the ordered extent to match the submitted bio. Hang on to the @@ -7887,37 +7891,31 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, * cancelled in iomap_end to avoid a deadlock wherein faulting the * remaining pages is blocked on the outstanding ordered extent. */ - if (iter->flags & IOMAP_WRITE) { - struct btrfs_ordered_extent *oe = dio_data->ordered; - int ret; - - ret = btrfs_extract_ordered_extent(bbio, oe); - if (ret) { - /* - * If this is a COW write it means we created new extent - * maps for the range and they point to an unwritten - * location since we got an error and we don't submit - * a bio. We must drop any extent maps within the range, - * otherwise a fast fsync would log them and after a - * crash and log replay we would have file extent items - * that point to unwritten locations (garbage). - */ - if (!test_bit(BTRFS_ORDERED_NOCOW, &oe->flags)) { - const u64 start = oe->file_offset; - const u64 end = start + oe->num_bytes - 1; + ret = btrfs_extract_ordered_extent(bbio, oe); + if (!ret) + goto submit_bio; - btrfs_drop_extent_map_range(bbio->inode, start, end, false); - } + /* + * If this is a COW write it means we created new extent maps for the + * range and they point to an unwritten location since we got an error + * and we don't submit a bio. We must drop any extent maps within the + * range, otherwise a fast fsync would log them and after a crash and + * log replay we would have file extent items that point to unwritten + * locations (garbage). + */ + if (!test_bit(BTRFS_ORDERED_NOCOW, &oe->flags)) { + const u64 start = oe->file_offset; + const u64 end = start + oe->num_bytes - 1; - btrfs_finish_ordered_extent(oe, NULL, - file_offset, dip->bytes, - !ret); - bio->bi_status = errno_to_blk_status(ret); - iomap_dio_bio_end_io(bio); - return; - } + btrfs_drop_extent_map_range(bbio->inode, start, end, false); } + btrfs_finish_ordered_extent(oe, NULL, file_offset, dip->bytes, false); + bio->bi_status = errno_to_blk_status(ret); + iomap_dio_bio_end_io(bio); + return; + +submit_bio: btrfs_submit_bio(bbio, 0); }