diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-10-01 01:32:33 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2016-10-01 01:32:33 -0400 |
commit | acbe5fda1fc05dc2e1e179b90c0879a5cfbf87b0 (patch) | |
tree | 4330ac667145090676c1d6512accc644280e66d9 /fs/fuse | |
parent | 3daa9c51651f2631be373840db0f82a8efb1c63d (diff) |
fuse: don't use fuse_ioctl_copy_user() helper
The two invocations share little code.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/file.c | 52 |
1 files changed, 18 insertions, 34 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 4c1db6ce7c48..b7beb67bf005 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -2326,33 +2326,6 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence) | |||
2326 | return retval; | 2326 | return retval; |
2327 | } | 2327 | } |
2328 | 2328 | ||
2329 | static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, | ||
2330 | unsigned int nr_segs, size_t bytes, bool to_user) | ||
2331 | { | ||
2332 | struct iov_iter ii; | ||
2333 | int page_idx = 0; | ||
2334 | |||
2335 | if (!bytes) | ||
2336 | return 0; | ||
2337 | |||
2338 | iov_iter_init(&ii, to_user ? READ : WRITE, iov, nr_segs, bytes); | ||
2339 | |||
2340 | while (iov_iter_count(&ii)) { | ||
2341 | struct page *page = pages[page_idx++]; | ||
2342 | size_t copied; | ||
2343 | |||
2344 | if (!to_user) | ||
2345 | copied = copy_page_from_iter(page, 0, PAGE_SIZE, &ii); | ||
2346 | else | ||
2347 | copied = copy_page_to_iter(page, 0, PAGE_SIZE, &ii); | ||
2348 | |||
2349 | if (unlikely(copied != PAGE_SIZE && iov_iter_count(&ii))) | ||
2350 | return -EFAULT; | ||
2351 | } | ||
2352 | |||
2353 | return 0; | ||
2354 | } | ||
2355 | |||
2356 | /* | 2329 | /* |
2357 | * CUSE servers compiled on 32bit broke on 64bit kernels because the | 2330 | * CUSE servers compiled on 32bit broke on 64bit kernels because the |
2358 | * ABI was defined to be 'struct iovec' which is different on 32bit | 2331 | * 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 | struct iovec *iov_page = NULL; | 2477 | struct iovec *iov_page = NULL; |
2505 | struct iovec *in_iov = NULL, *out_iov = NULL; | 2478 | struct iovec *in_iov = NULL, *out_iov = NULL; |
2506 | unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; | 2479 | unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; |
2507 | size_t in_size, out_size, transferred; | 2480 | size_t in_size, out_size, transferred, c; |
2508 | int err; | 2481 | int err, i; |
2482 | struct iov_iter ii; | ||
2509 | 2483 | ||
2510 | #if BITS_PER_LONG == 32 | 2484 | #if BITS_PER_LONG == 32 |
2511 | inarg.flags |= FUSE_IOCTL_32BIT; | 2485 | inarg.flags |= FUSE_IOCTL_32BIT; |
@@ -2587,10 +2561,13 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
2587 | req->in.args[1].size = in_size; | 2561 | req->in.args[1].size = in_size; |
2588 | req->in.argpages = 1; | 2562 | req->in.argpages = 1; |
2589 | 2563 | ||
2590 | err = fuse_ioctl_copy_user(pages, in_iov, in_iovs, in_size, | 2564 | err = -EFAULT; |
2591 | false); | 2565 | iov_iter_init(&ii, WRITE, in_iov, in_iovs, in_size); |
2592 | if (err) | 2566 | for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= num_pages); i++) { |
2593 | goto out; | 2567 | c = copy_page_from_iter(pages[i], 0, PAGE_SIZE, &ii); |
2568 | if (c != PAGE_SIZE && iov_iter_count(&ii)) | ||
2569 | goto out; | ||
2570 | } | ||
2594 | } | 2571 | } |
2595 | 2572 | ||
2596 | req->out.numargs = 2; | 2573 | req->out.numargs = 2; |
@@ -2656,7 +2633,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
2656 | if (transferred > inarg.out_size) | 2633 | if (transferred > inarg.out_size) |
2657 | goto out; | 2634 | goto out; |
2658 | 2635 | ||
2659 | err = fuse_ioctl_copy_user(pages, out_iov, out_iovs, transferred, true); | 2636 | err = -EFAULT; |
2637 | iov_iter_init(&ii, READ, out_iov, out_iovs, transferred); | ||
2638 | for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= num_pages); i++) { | ||
2639 | c = copy_page_to_iter(pages[i], 0, PAGE_SIZE, &ii); | ||
2640 | if (c != PAGE_SIZE && iov_iter_count(&ii)) | ||
2641 | goto out; | ||
2642 | } | ||
2643 | err = 0; | ||
2660 | out: | 2644 | out: |
2661 | if (req) | 2645 | if (req) |
2662 | fuse_put_request(fc, req); | 2646 | fuse_put_request(fc, req); |