Commit e1326f03 authored by Naohiro Aota's avatar Naohiro Aota Committed by David Sterba

btrfs: zoned: use bio_add_zone_append_page

A zoned device has its own hardware restrictions e.g. max_zone_append_size
when using REQ_OP_ZONE_APPEND. To follow these restrictions, use
bio_add_zone_append_page() instead of bio_add_page(). We need target device
to use bio_add_zone_append_page(), so this commit reads the chunk
information to cache the target device to btrfs_io_bio(bio)->device.

Caching only the target device is sufficient here as zoned filesystems
only supports the single profile at the moment. Once more profiles will be
supported btrfs_io_bio can hold an extent_map to be able to check for the
restrictions of all devices the btrfs_bio will be mapped to.
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 953651eb
...@@ -3109,6 +3109,7 @@ static bool btrfs_bio_add_page(struct bio *bio, struct page *page, ...@@ -3109,6 +3109,7 @@ static bool btrfs_bio_add_page(struct bio *bio, struct page *page,
{ {
const sector_t sector = disk_bytenr >> SECTOR_SHIFT; const sector_t sector = disk_bytenr >> SECTOR_SHIFT;
bool contig; bool contig;
int ret;
if (prev_bio_flags != bio_flags) if (prev_bio_flags != bio_flags)
return false; return false;
...@@ -3123,7 +3124,12 @@ static bool btrfs_bio_add_page(struct bio *bio, struct page *page, ...@@ -3123,7 +3124,12 @@ static bool btrfs_bio_add_page(struct bio *bio, struct page *page,
if (btrfs_bio_fits_in_stripe(page, size, bio, bio_flags)) if (btrfs_bio_fits_in_stripe(page, size, bio, bio_flags))
return false; return false;
return bio_add_page(bio, page, size, pg_offset) == size; if (bio_op(bio) == REQ_OP_ZONE_APPEND)
ret = bio_add_zone_append_page(bio, page, size, pg_offset);
else
ret = bio_add_page(bio, page, size, pg_offset);
return ret == size;
} }
/* /*
...@@ -3154,7 +3160,9 @@ static int submit_extent_page(unsigned int opf, ...@@ -3154,7 +3160,9 @@ static int submit_extent_page(unsigned int opf,
int ret = 0; int ret = 0;
struct bio *bio; struct bio *bio;
size_t io_size = min_t(size_t, size, PAGE_SIZE); size_t io_size = min_t(size_t, size, PAGE_SIZE);
struct extent_io_tree *tree = &BTRFS_I(page->mapping->host)->io_tree; struct btrfs_inode *inode = BTRFS_I(page->mapping->host);
struct extent_io_tree *tree = &inode->io_tree;
struct btrfs_fs_info *fs_info = inode->root->fs_info;
ASSERT(bio_ret); ASSERT(bio_ret);
...@@ -3185,11 +3193,26 @@ static int submit_extent_page(unsigned int opf, ...@@ -3185,11 +3193,26 @@ static int submit_extent_page(unsigned int opf,
if (wbc) { if (wbc) {
struct block_device *bdev; struct block_device *bdev;
bdev = BTRFS_I(page->mapping->host)->root->fs_info->fs_devices->latest_bdev; bdev = fs_info->fs_devices->latest_bdev;
bio_set_dev(bio, bdev); bio_set_dev(bio, bdev);
wbc_init_bio(wbc, bio); wbc_init_bio(wbc, bio);
wbc_account_cgroup_owner(wbc, page, io_size); wbc_account_cgroup_owner(wbc, page, io_size);
} }
if (btrfs_is_zoned(fs_info) && bio_op(bio) == REQ_OP_ZONE_APPEND) {
struct extent_map *em;
struct map_lookup *map;
em = btrfs_get_chunk_map(fs_info, disk_bytenr, io_size);
if (IS_ERR(em))
return PTR_ERR(em);
map = em->map_lookup;
/* We only support single profile for now */
ASSERT(map->num_stripes == 1);
btrfs_io_bio(bio)->device = map->stripes[0].dev;
free_extent_map(em);
}
*bio_ret = bio; *bio_ret = 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