Re: [PATCH v2 6/7] block: unpin all pages of a bvec in bio_iov_iter_align_down()
From: Tal Zussman
Date: Mon Sep 07 2026 - 20:12:09 EST
On 9/7/26 10:13 AM, Christoph Hellwig wrote:
> 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?
>
Of course :)
I can wire that up to blktests too if desired.
>> > @@ -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.
>