diff mbox series

[v12,20/41] btrfs: use bio_add_zone_append_page for zoned btrfs

Message ID 9cb19c5a674bede549a357b676627083bf71345d.1610693037.git.naohiro.aota@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: zoned block device support | expand

Commit Message

Naohiro Aota Jan. 15, 2021, 6:53 a.m. UTC
Zoned device has its own hardware restrictions e.g. max_zone_append_size
when using REQ_OP_ZONE_APPEND. To follow the 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 memoize the target device to btrfs_io_bio(bio)->device.

Currently, zoned btrfs only supports SINGLE profile. In the feature,
btrfs_io_bio can hold extent_map and check the restrictions for all the
devices the bio will be mapped.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/extent_io.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

Comments

Josef Bacik Jan. 15, 2021, 10:16 p.m. UTC | #1
On 1/15/21 1:53 AM, Naohiro Aota wrote:
> Zoned device has its own hardware restrictions e.g. max_zone_append_size
> when using REQ_OP_ZONE_APPEND. To follow the 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 memoize the target device to btrfs_io_bio(bio)->device.
> 
> Currently, zoned btrfs only supports SINGLE profile. In the feature,
> btrfs_io_bio can hold extent_map and check the restrictions for all the
> devices the bio will be mapped.
> 
> Reviewed-by: Josef Bacik <josef@toxicpanda.com>
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
> ---
>   fs/btrfs/extent_io.c | 30 +++++++++++++++++++++++++++---
>   1 file changed, 27 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> index 96f43b9121d6..41fccfbaee15 100644
> --- a/fs/btrfs/extent_io.c
> +++ b/fs/btrfs/extent_io.c
> @@ -3083,6 +3083,7 @@ static bool btrfs_bio_add_page(struct bio *bio, struct page *page, u64 logical,
>   {
>   	sector_t sector = logical >> SECTOR_SHIFT;
>   	bool contig;
> +	int ret;
>   
>   	if (prev_bio_flags != bio_flags)
>   		return false;
> @@ -3097,7 +3098,12 @@ static bool btrfs_bio_add_page(struct bio *bio, struct page *page, u64 logical,
>   	if (btrfs_bio_fits_in_stripe(page, size, bio, bio_flags))
>   		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;
>   }
>   
>   /*
> @@ -3128,7 +3134,9 @@ static int submit_extent_page(unsigned int opf,
>   	int ret = 0;
>   	struct bio *bio;
>   	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);
>   
> @@ -3159,11 +3167,27 @@ static int submit_extent_page(unsigned int opf,
>   	if (wbc) {
>   		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);
>   		wbc_init_bio(wbc, bio);
>   		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, offset, io_size);

Same goes for this, it fails to compile on misc-next.  Thanks,

Josef
diff mbox series

Patch

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 96f43b9121d6..41fccfbaee15 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3083,6 +3083,7 @@  static bool btrfs_bio_add_page(struct bio *bio, struct page *page, u64 logical,
 {
 	sector_t sector = logical >> SECTOR_SHIFT;
 	bool contig;
+	int ret;
 
 	if (prev_bio_flags != bio_flags)
 		return false;
@@ -3097,7 +3098,12 @@  static bool btrfs_bio_add_page(struct bio *bio, struct page *page, u64 logical,
 	if (btrfs_bio_fits_in_stripe(page, size, bio, bio_flags))
 		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;
 }
 
 /*
@@ -3128,7 +3134,9 @@  static int submit_extent_page(unsigned int opf,
 	int ret = 0;
 	struct bio *bio;
 	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);
 
@@ -3159,11 +3167,27 @@  static int submit_extent_page(unsigned int opf,
 	if (wbc) {
 		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);
 		wbc_init_bio(wbc, bio);
 		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, offset, 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;