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) <willy@infradead.org>
Cc: Leon Romanovsky <leon@kernel.org>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: William Kucharski <william.kucharski@linux.dev>
Link: https://patch.msgid.link/20260528175905.1102280-2-willy@infradead.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Matthew Wilcox (Oracle) 2026-05-28 18:59:03 +01:00 committed by Jens Axboe
parent 7d6eb455ec
commit ca36c1aaee
5 changed files with 22 additions and 7 deletions

View File

@ -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]));
}
/**

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}