On Mon, Jan 05, 2026 at 05:57:37PM -0700, Caleb Sander Mateos wrote:
> Factor a helper function ublk_copy_user_bvec() out of
> ublk_copy_user_pages(). It will be used for copying integrity data too.
> 
> Signed-off-by: Caleb Sander Mateos <[email protected]>
> ---
>  drivers/block/ublk_drv.c | 52 +++++++++++++++++++++++-----------------
>  1 file changed, 30 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index 2b0a9720921d..2ce9afdecc15 100644
> --- a/drivers/block/ublk_drv.c
> +++ b/drivers/block/ublk_drv.c
> @@ -1000,10 +1000,39 @@ static const struct block_device_operations ub_fops = 
> {
>       .open =         ublk_open,
>       .free_disk =    ublk_free_disk,
>       .report_zones = ublk_report_zones,
>  };
>  
> +static bool ublk_copy_user_bvec(const struct bio_vec *bv, unsigned *offset,
> +                             struct iov_iter *uiter, int dir, size_t *done)
> +{
> +     unsigned len;
> +     void *bv_buf;
> +     size_t copied;
> +
> +     if (*offset >= bv->bv_len) {
> +             *offset -= bv->bv_len;
> +             return true;
> +     }
> +
> +     len = bv->bv_len - *offset;
> +     bv_buf = kmap_local_page(bv->bv_page) + bv->bv_offset + *offset;
> +     if (dir == ITER_DEST)
> +             copied = copy_to_iter(bv_buf, len, uiter);
> +     else
> +             copied = copy_from_iter(bv_buf, len, uiter);
> +
> +     kunmap_local(bv_buf);
> +
> +     *done += copied;
> +     if (copied < len)
> +             return false;
> +
> +     *offset = 0;
> +     return true;
> +}
> +
>  /*
>   * Copy data between request pages and io_iter, and 'offset'
>   * is the start point of linear offset of request.
>   */
>  static size_t ublk_copy_user_pages(const struct request *req,
> @@ -1012,33 +1041,12 @@ static size_t ublk_copy_user_pages(const struct 
> request *req,
>       struct req_iterator iter;
>       struct bio_vec bv;
>       size_t done = 0;
>  
>       rq_for_each_segment(bv, req, iter) {
> -             unsigned len;
> -             void *bv_buf;
> -             size_t copied;
> -
> -             if (offset >= bv.bv_len) {
> -                     offset -= bv.bv_len;
> -                     continue;
> -             }
> -
> -             len = bv.bv_len - offset;
> -             bv_buf = kmap_local_page(bv.bv_page) + bv.bv_offset + offset;
> -             if (dir == ITER_DEST)
> -                     copied = copy_to_iter(bv_buf, len, uiter);
> -             else
> -                     copied = copy_from_iter(bv_buf, len, uiter);
> -
> -             kunmap_local(bv_buf);
> -
> -             done += copied;
> -             if (copied < len)
> +             if (!ublk_copy_user_bvec(&bv, &offset, uiter, dir, &done))
>                       break;
> -
> -             offset = 0;
>       }
>       return done;
>  }

Reviewed-by: Ming Lei <[email protected]>


Thanks, 
Ming


Reply via email to