Commit 69ccf3f4 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David Sterba

btrfs: handle recording of zoned writes in the storage layer

Move the code that splits the ordered extents and records the physical
location for them to the storage layer so that the higher level consumers
don't have to care about physical block numbers at all.  This will also
allow to eventually remove accounting for the zone append write sizes in
the upper layer with a little bit more block layer work.
Reviewed-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent f8a53bb5
...@@ -281,6 +281,8 @@ static void btrfs_simple_end_io(struct bio *bio) ...@@ -281,6 +281,8 @@ static void btrfs_simple_end_io(struct bio *bio)
INIT_WORK(&bbio->end_io_work, btrfs_end_bio_work); INIT_WORK(&bbio->end_io_work, btrfs_end_bio_work);
queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work); queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work);
} else { } else {
if (bio_op(bio) == REQ_OP_ZONE_APPEND)
btrfs_record_physical_zoned(bbio);
bbio->end_io(bbio); bbio->end_io(bbio);
} }
} }
...@@ -599,6 +601,12 @@ void btrfs_submit_bio(struct btrfs_fs_info *fs_info, struct bio *bio, int mirror ...@@ -599,6 +601,12 @@ void btrfs_submit_bio(struct btrfs_fs_info *fs_info, struct bio *bio, int mirror
} }
if (btrfs_op(bio) == BTRFS_MAP_WRITE) { if (btrfs_op(bio) == BTRFS_MAP_WRITE) {
if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
ret = btrfs_extract_ordered_extent(btrfs_bio(bio));
if (ret)
goto fail;
}
/* /*
* Csum items for reloc roots have already been cloned at this * Csum items for reloc roots have already been cloned at this
* point, so they are handled as part of the no-checksum case. * point, so they are handled as part of the no-checksum case.
......
...@@ -410,6 +410,7 @@ void btrfs_submit_data_read_bio(struct btrfs_inode *inode, struct bio *bio, ...@@ -410,6 +410,7 @@ void btrfs_submit_data_read_bio(struct btrfs_inode *inode, struct bio *bio,
int mirror_num, enum btrfs_compression_type compress_type); int mirror_num, enum btrfs_compression_type compress_type);
int btrfs_check_sector_csum(struct btrfs_fs_info *fs_info, struct page *page, int btrfs_check_sector_csum(struct btrfs_fs_info *fs_info, struct page *page,
u32 pgoff, u8 *csum, const u8 * const csum_expected); u32 pgoff, u8 *csum, const u8 * const csum_expected);
blk_status_t btrfs_extract_ordered_extent(struct btrfs_bio *bbio);
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev, bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
u32 bio_offset, struct bio_vec *bv); u32 bio_offset, struct bio_vec *bv);
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
......
...@@ -273,7 +273,6 @@ static void end_compressed_bio_write(struct btrfs_bio *bbio) ...@@ -273,7 +273,6 @@ static void end_compressed_bio_write(struct btrfs_bio *bbio)
if (refcount_dec_and_test(&cb->pending_ios)) { if (refcount_dec_and_test(&cb->pending_ios)) {
struct btrfs_fs_info *fs_info = btrfs_sb(cb->inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(cb->inode->i_sb);
btrfs_record_physical_zoned(cb->inode, cb->start, &bbio->bio);
queue_work(fs_info->compressed_write_workers, &cb->write_end_work); queue_work(fs_info->compressed_write_workers, &cb->write_end_work);
} }
bio_put(&bbio->bio); bio_put(&bbio->bio);
......
...@@ -586,7 +586,6 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio) ...@@ -586,7 +586,6 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio)
u64 start; u64 start;
u64 end; u64 end;
struct bvec_iter_all iter_all; struct bvec_iter_all iter_all;
bool first_bvec = true;
ASSERT(!bio_flagged(bio, BIO_CLONED)); ASSERT(!bio_flagged(bio, BIO_CLONED));
bio_for_each_segment_all(bvec, bio, iter_all) { bio_for_each_segment_all(bvec, bio, iter_all) {
...@@ -608,11 +607,6 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio) ...@@ -608,11 +607,6 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio)
start = page_offset(page) + bvec->bv_offset; start = page_offset(page) + bvec->bv_offset;
end = start + bvec->bv_len - 1; end = start + bvec->bv_len - 1;
if (first_bvec) {
btrfs_record_physical_zoned(inode, start, bio);
first_bvec = false;
}
end_extent_writepage(page, error, start, end); end_extent_writepage(page, error, start, end);
btrfs_page_clear_writeback(fs_info, page, start, bvec->bv_len); btrfs_page_clear_writeback(fs_info, page, start, bvec->bv_len);
......
...@@ -2647,19 +2647,19 @@ static int split_zoned_em(struct btrfs_inode *inode, u64 start, u64 len, ...@@ -2647,19 +2647,19 @@ static int split_zoned_em(struct btrfs_inode *inode, u64 start, u64 len,
return ret; return ret;
} }
static blk_status_t extract_ordered_extent(struct btrfs_inode *inode, blk_status_t btrfs_extract_ordered_extent(struct btrfs_bio *bbio)
struct bio *bio, loff_t file_offset)
{ {
u64 start = (u64)bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
u64 len = bbio->bio.bi_iter.bi_size;
struct btrfs_inode *inode = bbio->inode;
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
u64 start = (u64)bio->bi_iter.bi_sector << SECTOR_SHIFT;
u64 file_len; u64 file_len;
u64 len = bio->bi_iter.bi_size;
u64 end = start + len; u64 end = start + len;
u64 ordered_end; u64 ordered_end;
u64 pre, post; u64 pre, post;
int ret = 0; int ret = 0;
ordered = btrfs_lookup_ordered_extent(inode, file_offset); ordered = btrfs_lookup_ordered_extent(inode, bbio->file_offset);
if (WARN_ON_ONCE(!ordered)) if (WARN_ON_ONCE(!ordered))
return BLK_STS_IOERR; return BLK_STS_IOERR;
...@@ -2699,7 +2699,7 @@ static blk_status_t extract_ordered_extent(struct btrfs_inode *inode, ...@@ -2699,7 +2699,7 @@ static blk_status_t extract_ordered_extent(struct btrfs_inode *inode,
ret = btrfs_split_ordered_extent(ordered, pre, post); ret = btrfs_split_ordered_extent(ordered, pre, post);
if (ret) if (ret)
goto out; goto out;
ret = split_zoned_em(inode, file_offset, file_len, pre, post); ret = split_zoned_em(inode, bbio->file_offset, file_len, pre, post);
out: out:
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
...@@ -2709,19 +2709,7 @@ static blk_status_t extract_ordered_extent(struct btrfs_inode *inode, ...@@ -2709,19 +2709,7 @@ static blk_status_t extract_ordered_extent(struct btrfs_inode *inode,
void btrfs_submit_data_write_bio(struct btrfs_inode *inode, struct bio *bio, int mirror_num) void btrfs_submit_data_write_bio(struct btrfs_inode *inode, struct bio *bio, int mirror_num)
{ {
struct btrfs_fs_info *fs_info = inode->root->fs_info; btrfs_submit_bio(inode->root->fs_info, bio, mirror_num);
blk_status_t ret;
if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
ret = extract_ordered_extent(inode, bio,
page_offset(bio_first_bvec_all(bio)->bv_page));
if (ret) {
btrfs_bio_end_io(btrfs_bio(bio), ret);
return;
}
}
btrfs_submit_bio(fs_info, bio, mirror_num);
} }
void btrfs_submit_data_read_bio(struct btrfs_inode *inode, struct bio *bio, void btrfs_submit_data_read_bio(struct btrfs_inode *inode, struct bio *bio,
...@@ -7816,8 +7804,6 @@ static void btrfs_end_dio_bio(struct btrfs_bio *bbio) ...@@ -7816,8 +7804,6 @@ static void btrfs_end_dio_bio(struct btrfs_bio *bbio)
dip->bio.bi_status = err; dip->bio.bi_status = err;
} }
btrfs_record_physical_zoned(&dip->inode->vfs_inode, bbio->file_offset, bio);
bio_put(bio); bio_put(bio);
btrfs_dio_private_put(dip); btrfs_dio_private_put(dip);
} }
...@@ -7876,15 +7862,6 @@ static void btrfs_submit_direct(const struct iomap_iter *iter, ...@@ -7876,15 +7862,6 @@ static void btrfs_submit_direct(const struct iomap_iter *iter,
dip); dip);
btrfs_bio(bio)->file_offset = file_offset; btrfs_bio(bio)->file_offset = file_offset;
if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
status = extract_ordered_extent(BTRFS_I(inode), bio,
file_offset);
if (status) {
bio_put(bio);
goto out_err;
}
}
ASSERT(submit_len >= clone_len); ASSERT(submit_len >= clone_len);
submit_len -= clone_len; submit_len -= clone_len;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "space-info.h" #include "space-info.h"
#include "fs.h" #include "fs.h"
#include "accessors.h" #include "accessors.h"
#include "bio.h"
/* Maximum number of zones to report per blkdev_report_zones() call */ /* Maximum number of zones to report per blkdev_report_zones() call */
#define BTRFS_REPORT_NR_ZONES 4096 #define BTRFS_REPORT_NR_ZONES 4096
...@@ -1660,21 +1661,17 @@ bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start) ...@@ -1660,21 +1661,17 @@ bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start)
return ret; return ret;
} }
void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset, void btrfs_record_physical_zoned(struct btrfs_bio *bbio)
struct bio *bio)
{ {
const u64 physical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
const u64 physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
if (bio_op(bio) != REQ_OP_ZONE_APPEND) ordered = btrfs_lookup_ordered_extent(bbio->inode, bbio->file_offset);
return;
ordered = btrfs_lookup_ordered_extent(BTRFS_I(inode), file_offset);
if (WARN_ON(!ordered)) if (WARN_ON(!ordered))
return; return;
ordered->physical = physical; ordered->physical = physical;
ordered->bdev = bio->bi_bdev; ordered->bdev = bbio->bio.bi_bdev;
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
} }
......
...@@ -57,8 +57,7 @@ void btrfs_redirty_list_add(struct btrfs_transaction *trans, ...@@ -57,8 +57,7 @@ void btrfs_redirty_list_add(struct btrfs_transaction *trans,
struct extent_buffer *eb); struct extent_buffer *eb);
void btrfs_free_redirty_list(struct btrfs_transaction *trans); void btrfs_free_redirty_list(struct btrfs_transaction *trans);
bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start); bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start);
void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset, void btrfs_record_physical_zoned(struct btrfs_bio *bbio);
struct bio *bio);
void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered); void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered);
bool btrfs_check_meta_write_pointer(struct btrfs_fs_info *fs_info, bool btrfs_check_meta_write_pointer(struct btrfs_fs_info *fs_info,
struct extent_buffer *eb, struct extent_buffer *eb,
...@@ -190,8 +189,7 @@ static inline bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start) ...@@ -190,8 +189,7 @@ static inline bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start)
return false; return false;
} }
static inline void btrfs_record_physical_zoned(struct inode *inode, static inline void btrfs_record_physical_zoned(struct btrfs_bio *bbio)
u64 file_offset, struct bio *bio)
{ {
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment