> -
> -             if (page == bv->bv_page && off == bv->bv_offset + bv->bv_len) {
> -                     bv->bv_len += len;
> -                     bio->bi_iter.bi_size += len;
> -                     return true;
> -             }
> +             struct request_queue *q = NULL;
> +
> +             if (page == bv->bv_page && off == (bv->bv_offset + bv->bv_len)
> +                             && (off + len) <= PAGE_SIZE)

How could the page struct be the same, but the range beyond PAGE_SIZE
(at least with the existing callers)?

Also no need for the inner btraces, and the && always goes on the
first line.

> +             if (bio->bi_disk)
> +                     q = bio->bi_disk->queue;
> +
> +             /* disable multi-page bvec too if cluster isn't enabled */
> +             if (!q || !blk_queue_cluster(q) ||
> +                 ((page_to_phys(bv->bv_page) + bv->bv_offset + bv->bv_len) !=
> +                  (page_to_phys(page) + off)))
> +                     return false;
> + merge:
> +             bv->bv_len += len;
> +             bio->bi_iter.bi_size += len;
> +             return true;

Ok, this is scary, as it will give differen results depending on when
bi_disk is assigned.  But then again we shouldn't really do the cluster
check here, but rather when splitting the bio for the actual low-level
driver.

(and eventually we should kill this clustering setting off in favor
of our normal segment limits).

Reply via email to