Commit acbe5fda authored by Miklos Szeredi's avatar Miklos Szeredi

fuse: don't use fuse_ioctl_copy_user() helper

The two invocations share little code.
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 3daa9c51
...@@ -2326,33 +2326,6 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence) ...@@ -2326,33 +2326,6 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence)
return retval; return retval;
} }
static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
unsigned int nr_segs, size_t bytes, bool to_user)
{
struct iov_iter ii;
int page_idx = 0;
if (!bytes)
return 0;
iov_iter_init(&ii, to_user ? READ : WRITE, iov, nr_segs, bytes);
while (iov_iter_count(&ii)) {
struct page *page = pages[page_idx++];
size_t copied;
if (!to_user)
copied = copy_page_from_iter(page, 0, PAGE_SIZE, &ii);
else
copied = copy_page_to_iter(page, 0, PAGE_SIZE, &ii);
if (unlikely(copied != PAGE_SIZE && iov_iter_count(&ii)))
return -EFAULT;
}
return 0;
}
/* /*
* CUSE servers compiled on 32bit broke on 64bit kernels because the * CUSE servers compiled on 32bit broke on 64bit kernels because the
* ABI was defined to be 'struct iovec' which is different on 32bit * ABI was defined to be 'struct iovec' which is different on 32bit
...@@ -2504,8 +2477,9 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, ...@@ -2504,8 +2477,9 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
struct iovec *iov_page = NULL; struct iovec *iov_page = NULL;
struct iovec *in_iov = NULL, *out_iov = NULL; struct iovec *in_iov = NULL, *out_iov = NULL;
unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages;
size_t in_size, out_size, transferred; size_t in_size, out_size, transferred, c;
int err; int err, i;
struct iov_iter ii;
#if BITS_PER_LONG == 32 #if BITS_PER_LONG == 32
inarg.flags |= FUSE_IOCTL_32BIT; inarg.flags |= FUSE_IOCTL_32BIT;
...@@ -2587,11 +2561,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, ...@@ -2587,11 +2561,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
req->in.args[1].size = in_size; req->in.args[1].size = in_size;
req->in.argpages = 1; req->in.argpages = 1;
err = fuse_ioctl_copy_user(pages, in_iov, in_iovs, in_size, err = -EFAULT;
false); iov_iter_init(&ii, WRITE, in_iov, in_iovs, in_size);
if (err) for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= num_pages); i++) {
c = copy_page_from_iter(pages[i], 0, PAGE_SIZE, &ii);
if (c != PAGE_SIZE && iov_iter_count(&ii))
goto out; goto out;
} }
}
req->out.numargs = 2; req->out.numargs = 2;
req->out.args[0].size = sizeof(outarg); req->out.args[0].size = sizeof(outarg);
...@@ -2656,7 +2633,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, ...@@ -2656,7 +2633,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
if (transferred > inarg.out_size) if (transferred > inarg.out_size)
goto out; goto out;
err = fuse_ioctl_copy_user(pages, out_iov, out_iovs, transferred, true); err = -EFAULT;
iov_iter_init(&ii, READ, out_iov, out_iovs, transferred);
for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= num_pages); i++) {
c = copy_page_to_iter(pages[i], 0, PAGE_SIZE, &ii);
if (c != PAGE_SIZE && iov_iter_count(&ii))
goto out;
}
err = 0;
out: out:
if (req) if (req)
fuse_put_request(fc, req); fuse_put_request(fc, req);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment