diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-03 22:06:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:29:41 -0400 |
commit | 6c09e94a32e1094983d39879b9e8ccf9ffdcfa36 (patch) | |
tree | e28a1af97e199de9ec835a0cce22f8c35f841c24 /fs/fuse | |
parent | fbdbacca6153101f85cbc4ad8eb19bf0dde6a5cc (diff) |
fuse: use iov_iter_get_pages() for non-splice path
store reference to iter instead of that to iovec
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/dev.c | 41 |
1 files changed, 17 insertions, 24 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 89bf9df2d7ff..c8b68ab2e574 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -710,28 +710,26 @@ struct fuse_copy_state { | |||
710 | struct fuse_conn *fc; | 710 | struct fuse_conn *fc; |
711 | int write; | 711 | int write; |
712 | struct fuse_req *req; | 712 | struct fuse_req *req; |
713 | const struct iovec *iov; | 713 | struct iov_iter *iter; |
714 | struct pipe_buffer *pipebufs; | 714 | struct pipe_buffer *pipebufs; |
715 | struct pipe_buffer *currbuf; | 715 | struct pipe_buffer *currbuf; |
716 | struct pipe_inode_info *pipe; | 716 | struct pipe_inode_info *pipe; |
717 | unsigned long nr_segs; | 717 | unsigned long nr_segs; |
718 | unsigned long seglen; | ||
719 | unsigned long addr; | ||
720 | struct page *pg; | 718 | struct page *pg; |
721 | unsigned len; | 719 | unsigned len; |
722 | unsigned offset; | 720 | unsigned offset; |
723 | unsigned move_pages:1; | 721 | unsigned move_pages:1; |
724 | }; | 722 | }; |
725 | 723 | ||
726 | static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, | 724 | static void fuse_copy_init(struct fuse_copy_state *cs, |
725 | struct fuse_conn *fc, | ||
727 | int write, | 726 | int write, |
728 | const struct iovec *iov, unsigned long nr_segs) | 727 | struct iov_iter *iter) |
729 | { | 728 | { |
730 | memset(cs, 0, sizeof(*cs)); | 729 | memset(cs, 0, sizeof(*cs)); |
731 | cs->fc = fc; | 730 | cs->fc = fc; |
732 | cs->write = write; | 731 | cs->write = write; |
733 | cs->iov = iov; | 732 | cs->iter = iter; |
734 | cs->nr_segs = nr_segs; | ||
735 | } | 733 | } |
736 | 734 | ||
737 | /* Unmap and put previous page of userspace buffer */ | 735 | /* Unmap and put previous page of userspace buffer */ |
@@ -799,22 +797,16 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
799 | cs->nr_segs++; | 797 | cs->nr_segs++; |
800 | } | 798 | } |
801 | } else { | 799 | } else { |
802 | if (!cs->seglen) { | 800 | size_t off; |
803 | BUG_ON(!cs->nr_segs); | 801 | err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off); |
804 | cs->seglen = cs->iov[0].iov_len; | ||
805 | cs->addr = (unsigned long) cs->iov[0].iov_base; | ||
806 | cs->iov++; | ||
807 | cs->nr_segs--; | ||
808 | } | ||
809 | err = get_user_pages_fast(cs->addr, 1, cs->write, &page); | ||
810 | if (err < 0) | 802 | if (err < 0) |
811 | return err; | 803 | return err; |
812 | BUG_ON(err != 1); | 804 | BUG_ON(!err); |
805 | cs->len = err; | ||
806 | cs->offset = off; | ||
813 | cs->pg = page; | 807 | cs->pg = page; |
814 | cs->offset = cs->addr % PAGE_SIZE; | 808 | cs->offset = off; |
815 | cs->len = min(PAGE_SIZE - cs->offset, cs->seglen); | 809 | iov_iter_advance(cs->iter, err); |
816 | cs->seglen -= cs->len; | ||
817 | cs->addr += cs->len; | ||
818 | } | 810 | } |
819 | 811 | ||
820 | return lock_request(cs->fc, cs->req); | 812 | return lock_request(cs->fc, cs->req); |
@@ -1374,7 +1366,7 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to) | |||
1374 | if (!iter_is_iovec(to)) | 1366 | if (!iter_is_iovec(to)) |
1375 | return -EINVAL; | 1367 | return -EINVAL; |
1376 | 1368 | ||
1377 | fuse_copy_init(&cs, fc, 1, to->iov, to->nr_segs); | 1369 | fuse_copy_init(&cs, fc, 1, to); |
1378 | 1370 | ||
1379 | return fuse_dev_do_read(fc, file, &cs, iov_iter_count(to)); | 1371 | return fuse_dev_do_read(fc, file, &cs, iov_iter_count(to)); |
1380 | } | 1372 | } |
@@ -1396,7 +1388,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, | |||
1396 | if (!bufs) | 1388 | if (!bufs) |
1397 | return -ENOMEM; | 1389 | return -ENOMEM; |
1398 | 1390 | ||
1399 | fuse_copy_init(&cs, fc, 1, NULL, 0); | 1391 | fuse_copy_init(&cs, fc, 1, NULL); |
1400 | cs.pipebufs = bufs; | 1392 | cs.pipebufs = bufs; |
1401 | cs.pipe = pipe; | 1393 | cs.pipe = pipe; |
1402 | ret = fuse_dev_do_read(fc, in, &cs, len); | 1394 | ret = fuse_dev_do_read(fc, in, &cs, len); |
@@ -1982,7 +1974,7 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from) | |||
1982 | if (!iter_is_iovec(from)) | 1974 | if (!iter_is_iovec(from)) |
1983 | return -EINVAL; | 1975 | return -EINVAL; |
1984 | 1976 | ||
1985 | fuse_copy_init(&cs, fc, 0, from->iov, from->nr_segs); | 1977 | fuse_copy_init(&cs, fc, 0, from); |
1986 | 1978 | ||
1987 | return fuse_dev_do_write(fc, &cs, iov_iter_count(from)); | 1979 | return fuse_dev_do_write(fc, &cs, iov_iter_count(from)); |
1988 | } | 1980 | } |
@@ -2047,8 +2039,9 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | |||
2047 | } | 2039 | } |
2048 | pipe_unlock(pipe); | 2040 | pipe_unlock(pipe); |
2049 | 2041 | ||
2050 | fuse_copy_init(&cs, fc, 0, NULL, nbuf); | 2042 | fuse_copy_init(&cs, fc, 0, NULL); |
2051 | cs.pipebufs = bufs; | 2043 | cs.pipebufs = bufs; |
2044 | cs.nr_segs = nbuf; | ||
2052 | cs.pipe = pipe; | 2045 | cs.pipe = pipe; |
2053 | 2046 | ||
2054 | if (flags & SPLICE_F_MOVE) | 2047 | if (flags & SPLICE_F_MOVE) |