Loading drivers/vhost/scsi.c +20 −48 Original line number Original line Diff line number Diff line Loading @@ -210,12 +210,6 @@ static struct workqueue_struct *vhost_scsi_workqueue; static DEFINE_MUTEX(vhost_scsi_mutex); static DEFINE_MUTEX(vhost_scsi_mutex); static LIST_HEAD(vhost_scsi_list); static LIST_HEAD(vhost_scsi_list); static int iov_num_pages(void __user *iov_base, size_t iov_len) { return (PAGE_ALIGN((unsigned long)iov_base + iov_len) - ((unsigned long)iov_base & PAGE_MASK)) >> PAGE_SHIFT; } static void vhost_scsi_done_inflight(struct kref *kref) static void vhost_scsi_done_inflight(struct kref *kref) { { struct vhost_scsi_inflight *inflight; struct vhost_scsi_inflight *inflight; Loading Loading @@ -618,48 +612,31 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, */ */ static int static int vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd, vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd, void __user *ptr, struct iov_iter *iter, size_t len, struct scatterlist *sgl, struct scatterlist *sgl, bool write) bool write) { { unsigned int npages = 0, offset, nbytes; unsigned int pages_nr = iov_num_pages(ptr, len); struct scatterlist *sg = sgl; struct page **pages = cmd->tvc_upages; struct page **pages = cmd->tvc_upages; int ret, i; struct scatterlist *sg = sgl; ssize_t bytes; if (pages_nr > VHOST_SCSI_PREALLOC_UPAGES) { size_t offset; pr_err("vhost_scsi_map_to_sgl() pages_nr: %u greater than" unsigned int npages = 0; " preallocated VHOST_SCSI_PREALLOC_UPAGES: %u\n", pages_nr, VHOST_SCSI_PREALLOC_UPAGES); return -ENOBUFS; } ret = get_user_pages_fast((unsigned long)ptr, pages_nr, write, pages); bytes = iov_iter_get_pages(iter, pages, LONG_MAX, VHOST_SCSI_PREALLOC_UPAGES, &offset); /* No pages were pinned */ /* No pages were pinned */ if (ret < 0) if (bytes <= 0) goto out; return bytes < 0 ? bytes : -EFAULT; /* Less pages pinned than wanted */ if (ret != pages_nr) { for (i = 0; i < ret; i++) put_page(pages[i]); ret = -EFAULT; goto out; } while (len > 0) { iov_iter_advance(iter, bytes); offset = (uintptr_t)ptr & ~PAGE_MASK; nbytes = min_t(unsigned int, PAGE_SIZE - offset, len); sg_set_page(sg, pages[npages], nbytes, offset); ptr += nbytes; len -= nbytes; sg++; npages++; } out: while (bytes) { return ret; unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes); sg_set_page(sg++, pages[npages++], n, offset); bytes -= n; offset = 0; } return npages; } } static int static int Loading Loading @@ -687,15 +664,11 @@ vhost_scsi_iov_to_sgl(struct vhost_scsi_cmd *cmd, bool write, struct iov_iter *iter, struct iov_iter *iter, struct scatterlist *sg, int sg_count) struct scatterlist *sg, int sg_count) { { size_t off = iter->iov_offset; struct scatterlist *p = sg; struct scatterlist *p = sg; int i, ret; int ret; for (i = 0; i < iter->nr_segs; i++) { void __user *base = iter->iov[i].iov_base + off; size_t len = iter->iov[i].iov_len - off; ret = vhost_scsi_map_to_sgl(cmd, base, len, sg, write); while (iov_iter_count(iter)) { ret = vhost_scsi_map_to_sgl(cmd, iter, sg, write); if (ret < 0) { if (ret < 0) { while (p < sg) { while (p < sg) { struct page *page = sg_page(p++); struct page *page = sg_page(p++); Loading @@ -705,7 +678,6 @@ vhost_scsi_iov_to_sgl(struct vhost_scsi_cmd *cmd, bool write, return ret; return ret; } } sg += ret; sg += ret; off = 0; } } return 0; return 0; } } Loading Loading
drivers/vhost/scsi.c +20 −48 Original line number Original line Diff line number Diff line Loading @@ -210,12 +210,6 @@ static struct workqueue_struct *vhost_scsi_workqueue; static DEFINE_MUTEX(vhost_scsi_mutex); static DEFINE_MUTEX(vhost_scsi_mutex); static LIST_HEAD(vhost_scsi_list); static LIST_HEAD(vhost_scsi_list); static int iov_num_pages(void __user *iov_base, size_t iov_len) { return (PAGE_ALIGN((unsigned long)iov_base + iov_len) - ((unsigned long)iov_base & PAGE_MASK)) >> PAGE_SHIFT; } static void vhost_scsi_done_inflight(struct kref *kref) static void vhost_scsi_done_inflight(struct kref *kref) { { struct vhost_scsi_inflight *inflight; struct vhost_scsi_inflight *inflight; Loading Loading @@ -618,48 +612,31 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, */ */ static int static int vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd, vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd, void __user *ptr, struct iov_iter *iter, size_t len, struct scatterlist *sgl, struct scatterlist *sgl, bool write) bool write) { { unsigned int npages = 0, offset, nbytes; unsigned int pages_nr = iov_num_pages(ptr, len); struct scatterlist *sg = sgl; struct page **pages = cmd->tvc_upages; struct page **pages = cmd->tvc_upages; int ret, i; struct scatterlist *sg = sgl; ssize_t bytes; if (pages_nr > VHOST_SCSI_PREALLOC_UPAGES) { size_t offset; pr_err("vhost_scsi_map_to_sgl() pages_nr: %u greater than" unsigned int npages = 0; " preallocated VHOST_SCSI_PREALLOC_UPAGES: %u\n", pages_nr, VHOST_SCSI_PREALLOC_UPAGES); return -ENOBUFS; } ret = get_user_pages_fast((unsigned long)ptr, pages_nr, write, pages); bytes = iov_iter_get_pages(iter, pages, LONG_MAX, VHOST_SCSI_PREALLOC_UPAGES, &offset); /* No pages were pinned */ /* No pages were pinned */ if (ret < 0) if (bytes <= 0) goto out; return bytes < 0 ? bytes : -EFAULT; /* Less pages pinned than wanted */ if (ret != pages_nr) { for (i = 0; i < ret; i++) put_page(pages[i]); ret = -EFAULT; goto out; } while (len > 0) { iov_iter_advance(iter, bytes); offset = (uintptr_t)ptr & ~PAGE_MASK; nbytes = min_t(unsigned int, PAGE_SIZE - offset, len); sg_set_page(sg, pages[npages], nbytes, offset); ptr += nbytes; len -= nbytes; sg++; npages++; } out: while (bytes) { return ret; unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes); sg_set_page(sg++, pages[npages++], n, offset); bytes -= n; offset = 0; } return npages; } } static int static int Loading Loading @@ -687,15 +664,11 @@ vhost_scsi_iov_to_sgl(struct vhost_scsi_cmd *cmd, bool write, struct iov_iter *iter, struct iov_iter *iter, struct scatterlist *sg, int sg_count) struct scatterlist *sg, int sg_count) { { size_t off = iter->iov_offset; struct scatterlist *p = sg; struct scatterlist *p = sg; int i, ret; int ret; for (i = 0; i < iter->nr_segs; i++) { void __user *base = iter->iov[i].iov_base + off; size_t len = iter->iov[i].iov_len - off; ret = vhost_scsi_map_to_sgl(cmd, base, len, sg, write); while (iov_iter_count(iter)) { ret = vhost_scsi_map_to_sgl(cmd, iter, sg, write); if (ret < 0) { if (ret < 0) { while (p < sg) { while (p < sg) { struct page *page = sg_page(p++); struct page *page = sg_page(p++); Loading @@ -705,7 +678,6 @@ vhost_scsi_iov_to_sgl(struct vhost_scsi_cmd *cmd, bool write, return ret; return ret; } } sg += ret; sg += ret; off = 0; } } return 0; return 0; } } Loading