diff mbox series

[v9,01/41] block: add bio_add_zone_append_page

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

Commit Message

Naohiro Aota Oct. 30, 2020, 1:51 p.m. UTC
From: Johannes Thumshirn <johannes.thumshirn@wdc.com>

Add bio_add_zone_append_page(), a wrapper around bio_add_hw_page() which
is intended to be used by file systems that directly add pages to a bio
instead of using bio_iov_iter_get_pages().

Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
 block/bio.c         | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/bio.h |  2 ++
 2 files changed, 38 insertions(+)

Comments

Jens Axboe Oct. 31, 2020, 3:40 a.m. UTC | #1
On 10/30/20 7:51 AM, Naohiro Aota wrote:
> From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> 
> Add bio_add_zone_append_page(), a wrapper around bio_add_hw_page() which
> is intended to be used by file systems that directly add pages to a bio
> instead of using bio_iov_iter_get_pages().

Not sure what this is for, since I'm only on one patch in the series...

> +/**
> + * bio_add_zone_append_page - attempt to add page to zone-append bio
> + * @bio: destination bio
> + * @page: page to add
> + * @len: vec entry length
> + * @offset: vec entry offset
> + *
> + * Attempt to add a page to the bio_vec maplist of a bio that will be submitted
> + * for a zone-append request. This can fail for a number of reasons, such as the
> + * bio being full or the target block device is not a zoned block device or
> + * other limitations of the target block device. The target block device must
> + * allow bio's up to PAGE_SIZE, so it is always possible to add a single page
> + * to an empty bio.
> + */

This should include a

Return value:

section, explaining how it returns number of bytes added (and why 0 is thus
a failure case).

> +int bio_add_zone_append_page(struct bio *bio, struct page *page,
> +			     unsigned int len, unsigned int offset)

Should this return unsigned int? If not, how would it work if someone
asked for INT_MAX + 4k.
Naohiro Aota Nov. 2, 2020, 5:15 a.m. UTC | #2
On Fri, Oct 30, 2020 at 09:40:08PM -0600, Jens Axboe wrote:
>On 10/30/20 7:51 AM, Naohiro Aota wrote:
>> From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
>>
>> Add bio_add_zone_append_page(), a wrapper around bio_add_hw_page() which
>> is intended to be used by file systems that directly add pages to a bio
>> instead of using bio_iov_iter_get_pages().
>
>Not sure what this is for, since I'm only on one patch in the series...

I'm sorry for the missing context. This patch is for this series.

https://lore.kernel.org/linux-btrfs/cover.1604065156.git.naohiro.aota@wdc.com/T/

This patch uses bio_add_zone_append_page in place of bio_add_page for zoned
device.

https://lore.kernel.org/linux-btrfs/cover.1604065156.git.naohiro.aota@wdc.com/T/#m88184d5dd11ac30c0878582898cd9d6f7cbc21fc

>
>> +/**
>> + * bio_add_zone_append_page - attempt to add page to zone-append bio
>> + * @bio: destination bio
>> + * @page: page to add
>> + * @len: vec entry length
>> + * @offset: vec entry offset
>> + *
>> + * Attempt to add a page to the bio_vec maplist of a bio that will be submitted
>> + * for a zone-append request. This can fail for a number of reasons, such as the
>> + * bio being full or the target block device is not a zoned block device or
>> + * other limitations of the target block device. The target block device must
>> + * allow bio's up to PAGE_SIZE, so it is always possible to add a single page
>> + * to an empty bio.
>> + */
>
>This should include a
>
>Return value:
>
>section, explaining how it returns number of bytes added (and why 0 is thus
>a failure case).
>
>> +int bio_add_zone_append_page(struct bio *bio, struct page *page,
>> +			     unsigned int len, unsigned int offset)
>
>Should this return unsigned int? If not, how would it work if someone
>asked for INT_MAX + 4k.
>
>-- 
>Jens Axboe
>
Johannes Thumshirn Nov. 2, 2020, 8:24 a.m. UTC | #3
On 31/10/2020 04:40, Jens Axboe wrote:
> On 10/30/20 7:51 AM, Naohiro Aota wrote:
>> From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
>>
>> Add bio_add_zone_append_page(), a wrapper around bio_add_hw_page() which
>> is intended to be used by file systems that directly add pages to a bio
>> instead of using bio_iov_iter_get_pages().
> 
> Not sure what this is for, since I'm only on one patch in the series...

Sorry, we'll Cc you on the whole series.

> 
>> +/**
>> + * bio_add_zone_append_page - attempt to add page to zone-append bio
>> + * @bio: destination bio
>> + * @page: page to add
>> + * @len: vec entry length
>> + * @offset: vec entry offset
>> + *
>> + * Attempt to add a page to the bio_vec maplist of a bio that will be submitted
>> + * for a zone-append request. This can fail for a number of reasons, such as the
>> + * bio being full or the target block device is not a zoned block device or
>> + * other limitations of the target block device. The target block device must
>> + * allow bio's up to PAGE_SIZE, so it is always possible to add a single page
>> + * to an empty bio.
>> + */
> 
> This should include a
> 
> Return value:
> 
> section, explaining how it returns number of bytes added (and why 0 is thus
> a failure case).


I'll update the comment to include the return value. It was just a copy and paste
of bio_add_page() and it didn't have the return value documented, so this is why
I missed it here.

I'll probably should document the existing functions as well.

>> +int bio_add_zone_append_page(struct bio *bio, struct page *page,
>> +			     unsigned int len, unsigned int offset)
> 
> Should this return unsigned int? If not, how would it work if someone
> asked for INT_MAX + 4k.
> 

I don't think this is needed as we can't go over 2G anyways, can't we? bio_add_page() 
also returns an int and I wanted to have a consistent interface here.
diff mbox series

Patch

diff --git a/block/bio.c b/block/bio.c
index 58d765400226..2dfe40be4d6b 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -853,6 +853,42 @@  int bio_add_pc_page(struct request_queue *q, struct bio *bio,
 }
 EXPORT_SYMBOL(bio_add_pc_page);
 
+/**
+ * bio_add_zone_append_page - attempt to add page to zone-append bio
+ * @bio: destination bio
+ * @page: page to add
+ * @len: vec entry length
+ * @offset: vec entry offset
+ *
+ * Attempt to add a page to the bio_vec maplist of a bio that will be submitted
+ * for a zone-append request. This can fail for a number of reasons, such as the
+ * bio being full or the target block device is not a zoned block device or
+ * other limitations of the target block device. The target block device must
+ * allow bio's up to PAGE_SIZE, so it is always possible to add a single page
+ * to an empty bio.
+ */
+int bio_add_zone_append_page(struct bio *bio, struct page *page,
+			     unsigned int len, unsigned int offset)
+{
+	struct request_queue *q;
+	bool same_page = false;
+
+	if (WARN_ON_ONCE(bio_op(bio) != REQ_OP_ZONE_APPEND))
+		return 0;
+
+	if (WARN_ON_ONCE(!bio->bi_disk))
+		return 0;
+
+	q = bio->bi_disk->queue;
+
+	if (WARN_ON_ONCE(!blk_queue_is_zoned(q)))
+		return 0;
+
+	return bio_add_hw_page(q, bio, page, len, offset,
+			       queue_max_zone_append_sectors(q), &same_page);
+}
+EXPORT_SYMBOL_GPL(bio_add_zone_append_page);
+
 /**
  * __bio_try_merge_page - try appending data to an existing bvec.
  * @bio: destination bio
diff --git a/include/linux/bio.h b/include/linux/bio.h
index c6d765382926..7ef300cb4e9a 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -442,6 +442,8 @@  void bio_chain(struct bio *, struct bio *);
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
 			   unsigned int, unsigned int);
+int bio_add_zone_append_page(struct bio *bio, struct page *page,
+			     unsigned int len, unsigned int offset);
 bool __bio_try_merge_page(struct bio *bio, struct page *page,
 		unsigned int len, unsigned int off, bool *same_page);
 void __bio_add_page(struct bio *bio, struct page *page,