> struct bio_vec *prev = &bio->bi_io_vec[bio->bi_vcnt - 1];
>
> + /* segment size is always >= PAGE_SIZE */
I don't think that actually is true. We have various drivers with 4k
segment size, for which this would not be true with a 64k page size
system.
> if (page == prev->bv_page &&
> offset == prev->bv_offset + prev->bv_len) {
> if (put_same_page)
> put_page(page);
> + bvec_merge:
> prev->bv_len += len;
> bio->bi_iter.bi_size += len;
Please throw in a cleanup patch that removes prev and and always uses
bvec, then we can just move the done label up by two lines and handle
the increment of bv_len and bi_size in a common branch.
> done:
> + bio->bi_phys_segments = bio->bi_vcnt;
> + if (!bio_flagged(bio, BIO_SEG_VALID))
> + bio_set_flag(bio, BIO_SEG_VALID);
How would BIO_SEG_VALID get set previously? And even if it did
we wouldn't optimize much here, I'd just do it unconditionally.
Btw, there are various comments in this function that either already
were or have become out of data, like talking about REQ_PC or
file system I/O - I think they could use some love.