mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-27 09:56:48 +08:00
ublk: split out ublk_copy_user_bvec() helper
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 <csander@purestorage.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
f82f0a16a8
commit
fc652d415c
@@ -993,6 +993,35 @@ static const struct block_device_operations ub_fops = {
|
||||
.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.
|
||||
@@ -1005,29 +1034,8 @@ static size_t ublk_copy_user_pages(const struct request *req,
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user