From: Matthew Wilcox (Oracle) Date: Thu, 28 May 2026 17:59:03 +0000 (+0100) Subject: block: Add bvec_folio() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca36c1aaee095d009d73f6623fb5e536ada80032;p=thirdparty%2Flinux.git block: Add bvec_folio() This is a simple helper which replaces page_folio(bvec->bv_page). Minor improvement in readability, but the real motivation is to reduce the number of references to bvec->bv_page so that it can be changed with less work. Signed-off-by: Matthew Wilcox (Oracle) Cc: Leon Romanovsky Reviewed-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Reviewed-by: William Kucharski Link: https://patch.msgid.link/20260528175905.1102280-2-willy@infradead.org Signed-off-by: Jens Axboe --- diff --git a/block/bio.c b/block/bio.c index e9944dab01327..c3d0a00a27f15 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1299,7 +1299,7 @@ static void bio_free_folios(struct bio *bio) int i; bio_for_each_bvec_all(bv, bio, i) { - struct folio *folio = page_folio(bv->bv_page); + struct folio *folio = bvec_folio(bv); if (!is_zero_folio(folio)) folio_put(folio); @@ -1406,7 +1406,7 @@ int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter, size_t maxlen) static void bvec_unpin(struct bio_vec *bv, bool mark_dirty) { - struct folio *folio = page_folio(bv->bv_page); + struct folio *folio = bvec_folio(bv); size_t nr_pages = (bv->bv_offset + bv->bv_len - 1) / PAGE_SIZE - bv->bv_offset / PAGE_SIZE + 1; @@ -1440,7 +1440,7 @@ static void bio_iov_iter_unbounce_read(struct bio *bio, bool is_error, bvec_unpin(&bio->bi_io_vec[1 + i], mark_dirty); } - folio_put(page_folio(bio->bi_io_vec[0].bv_page)); + folio_put(bvec_folio(&bio->bi_io_vec[0])); } /** diff --git a/include/linux/bio.h b/include/linux/bio.h index 97f993d4d914e..26ebfff93a16d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -283,7 +283,7 @@ static inline void bio_first_folio(struct folio_iter *fi, struct bio *bio, return; } - fi->folio = page_folio(bvec->bv_page); + fi->folio = bvec_folio(bvec); fi->offset = bvec->bv_offset + PAGE_SIZE * folio_page_idx(fi->folio, bvec->bv_page); fi->_seg_count = bvec->bv_len; diff --git a/include/linux/bvec.h b/include/linux/bvec.h index f4c7ec282ac9c..c939f2b3be87f 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h @@ -74,6 +74,21 @@ static inline void bvec_set_virt(struct bio_vec *bv, void *vaddr, bvec_set_page(bv, virt_to_page(vaddr), len, offset_in_page(vaddr)); } +/** + * bvec_folio - Return the first folio referenced by this bvec + * @bv: bvec to access + * + * A bvec can contain non-folio memory, so this should only be called by + * the creator of the bvec; drivers have no business looking at the owner + * of the memory. It may not even be the right interface for the caller + * to use as a bvec can span multiple folios. You may be better off using + * something like bio_for_each_folio_all() which iterates over all folios. + */ +static inline struct folio *bvec_folio(const struct bio_vec *bv) +{ + return page_folio(bv->bv_page); +} + struct bvec_iter { /* * Current device address in 512 byte sectors. Only updated by the bio diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 650303626be6e..5d792f70ec1ed 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -102,7 +102,7 @@ static void io_release_ubuf(void *priv) unsigned int i; for (i = 0; i < imu->nr_bvecs; i++) { - struct folio *folio = page_folio(imu->bvec[i].bv_page); + struct folio *folio = bvec_folio(&imu->bvec[i]); unpin_user_folio(folio, 1); } diff --git a/mm/page_io.c b/mm/page_io.c index 70cea9e24d2fd..a59b73f8bdd9d 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -490,7 +490,7 @@ static void sio_read_complete(struct kiocb *iocb, long ret) if (ret == sio->len) { for (p = 0; p < sio->pages; p++) { - struct folio *folio = page_folio(sio->bvec[p].bv_page); + struct folio *folio = bvec_folio(&sio->bvec[p]); count_mthp_stat(folio_order(folio), MTHP_STAT_SWPIN); count_memcg_folio_events(folio, PSWPIN, folio_nr_pages(folio)); @@ -500,7 +500,7 @@ static void sio_read_complete(struct kiocb *iocb, long ret) count_vm_events(PSWPIN, sio->len >> PAGE_SHIFT); } else { for (p = 0; p < sio->pages; p++) { - struct folio *folio = page_folio(sio->bvec[p].bv_page); + struct folio *folio = bvec_folio(&sio->bvec[p]); folio_unlock(folio); }