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

From: Tal Zussman

Date: Sat Sep 19 2026 - 01:14:03 EST


On 9/18/26 4:43 AM, Christoph Hellwig wrote:
>> +
>> + /*
>> + * __bio_release_pages() only unpins the pages still covered by
>> + * bv_len, so drop the pins for the pages trimmed off here.
>> + */
>> + npages = bvec_nr_pages(bv);
>> bv->bv_len -= nbytes;
>> + npages -= bvec_nr_pages(bv);
>
> Wouldn't it make more sense to calculate npages once after the
> decrement here, or am I missing something?
>

The first bvec_nr_pages() computes the number of pages originally in the
bvec. Then we subtract the number of bytes trimmed off, and subtract
the number of pages still left in the bvec from the original page count,
giving us the number of pages trimmed off, which is then how many pins
we need to drop.

If we just calculate after the decrement we would only know how many pages
are currently in the bvec, and wouldn't know how many were dropped.
We could open-code this calculation as:

size_t old_end = bv->bv_offset + bv->bv_len;

bv->bv_len -= nbytes;
npages = (old_end - 1) / PAGE_SIZE -
(bv->bv_offset + bv->bv_len - 1) / PAGE_SIZE;

but both expressions end up compiling to the same thing in my testing.

But maybe I'm missing something... Perhaps this needs a bit of a
longer comment?