Re: [PATCH v2 6/7] block: unpin all pages of a bvec in bio_iov_iter_align_down()
From: Christoph Hellwig
Date: Mon Sep 07 2026 - 03:24:59 EST
On Fri, Aug 28, 2026 at 05:36:24PM +0300, Tal Zussman wrote:
> > Both issues occur only with a logical block size above PAGE_SIZE and a
> > large folio backing the user buffer. On a device with a 64K logical
> > block size, an O_DIRECT pwritev() from a hugetlb mapping that ends 16K
> > past a block boundary leaks one huge page per call, whether the
> > remainder is its own bvec or the tail of a larger one.
Do you have a reproducer for that?
> > @@ -1213,14 +1219,24 @@ static int bio_iov_iter_align_down(struct bio *bio, struct iov_iter *iter,
> > bio->bi_iter.bi_size -= nbytes;
> > while (nbytes >= bv->bv_len) {
> > if (bio_flagged(bio, BIO_PAGE_PINNED))
> > - unpin_user_page(bv->bv_page);
> > + unpin_user_folio(bvec_folio(bv),
> > + bvec_nr_pages(bv));
>
> And right after sending this, I noticed bvec_unpin()...
>
> I think a cleaner solution is to move bvec_unpin() up, make bvec_nr_pages()
> handle bv_offset > PAGE_SIZE, use bvec_nr_pages() in bvec_unpin(), and then
> use bvec_unpin() here.
Yes, that sounds better.