Message ID | 1487950971-1131-3-git-send-email-tom.leiming@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Feb 24, 2017 at 11:42:39PM +0800, Ming Lei wrote: > MD need this helper to remove the last added page, so introduce > it. If MD really has a valid use case for this it should open code the operation. The semantics look deeply fishy to me.
On Sun, Feb 26, 2017 at 2:23 AM, Christoph Hellwig <hch@infradead.org> wrote: > On Fri, Feb 24, 2017 at 11:42:39PM +0800, Ming Lei wrote: >> MD need this helper to remove the last added page, so introduce >> it. > > If MD really has a valid use case for this it should open code the > operation. The semantics look deeply fishy to me. Thinking about MD's case further, and looks bio_add_page() won't fail at all in case that queue's limit isn't applied in bio_add_page() in future. So I will change MD's handling in this case and avoid to introduce bio_remove_last_page() in V2. Thanks, Ming Lei
diff --git a/block/bio.c b/block/bio.c index 5eec5e08417f..0ce7ffcd7939 100644 --- a/block/bio.c +++ b/block/bio.c @@ -837,6 +837,29 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page EXPORT_SYMBOL(bio_add_pc_page); /** + * bio_remove_last_page - remove the last added page + * @bio: destination bio + * + * Attempt to remove the last added page from the bio_vec maplist. + */ +void bio_remove_last_page(struct bio *bio) +{ + /* + * cloned bio must not modify vec list + */ + if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED))) + return; + + if (bio->bi_vcnt > 0) { + struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; + + bio->bi_iter.bi_size -= bv->bv_len; + bio->bi_vcnt--; + } +} +EXPORT_SYMBOL(bio_remove_last_page); + +/** * bio_add_page - attempt to add page to bio * @bio: destination bio * @page: page to add diff --git a/include/linux/bio.h b/include/linux/bio.h index 3364b3ed90e7..32aeb493d1fe 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -443,6 +443,7 @@ extern void bio_init(struct bio *bio, struct bio_vec *table, extern void bio_reset(struct bio *); void bio_chain(struct bio *, struct bio *); +extern void bio_remove_last_page(struct bio *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);
MD need this helper to remove the last added page, so introduce it. Signed-off-by: Ming Lei <tom.leiming@gmail.com> --- block/bio.c | 23 +++++++++++++++++++++++ include/linux/bio.h | 1 + 2 files changed, 24 insertions(+)