Re: [PATCH v3 6/7] block: unpin all pages of a bvec in bio_iov_iter_align_down()

From: Shin'ichiro Kawasaki

Date: Thu Sep 17 2026 - 23:27:16 EST


On Sep 09, 2026 / 18:05, Tal Zussman wrote:
> bio_iov_iter_align_down() drops trailing bvecs with unpin_user_page(),
> but a bvec built by iov_iter_extract_bvecs() can span several pages of
> one folio, each with its own pin. All but the first pin leak.
>
> The partially trimmed bvec has the same problem. Shrinking bv_len does
> not release the pins for the pages cut off by the trim, and
> __bio_release_pages() only unpins the pages bv_len still covers at
> completion.
>
> 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.
>
> Unpin all pages of a dropped bvec with bvec_unpin(), and unpin the
> pages trimmed off the last bvec as well. Move bvec_unpin() up and split
> its page count into a helper so both sites share it.
>
> Fixes: 20a0e6276edb ("block: align the bio after building it")
> Assisted-by: Claude:claude-fable-5
> Reviewed-by: Hannes Reinecke <hare@xxxxxxxxxx>
> Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>

I confirmed that this patch avoids the failure of the corresponding
blktests test case [*].

Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx>

[*] https://lore.kernel.org/linux-block/20260909-blkdev-fixes-tests-v1-3-1f8af8665d16@xxxxxxxxxxxx/