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 | |
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>
-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 { struct fuse_conn *fc; int write; struct fuse_req *req; - const struct iovec *iov; + struct iov_iter *iter; struct pipe_buffer *pipebufs; struct pipe_buffer *currbuf; struct pipe_inode_info *pipe; unsigned long nr_segs; - unsigned long seglen; - unsigned long addr; struct page *pg; unsigned len; unsigned offset; unsigned move_pages:1; }; -static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, +static void fuse_copy_init(struct fuse_copy_state *cs, + struct fuse_conn *fc, int write, - const struct iovec *iov, unsigned long nr_segs) + struct iov_iter *iter) { memset(cs, 0, sizeof(*cs)); cs->fc = fc; cs->write = write; - cs->iov = iov; - cs->nr_segs = nr_segs; + cs->iter = iter; } /* Unmap and put previous page of userspace buffer */ @@ -799,22 +797,16 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) cs->nr_segs++; } } else { - if (!cs->seglen) { - BUG_ON(!cs->nr_segs); - cs->seglen = cs->iov[0].iov_len; - cs->addr = (unsigned long) cs->iov[0].iov_base; - cs->iov++; - cs->nr_segs--; - } - err = get_user_pages_fast(cs->addr, 1, cs->write, &page); + size_t off; + err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off); if (err < 0) return err; - BUG_ON(err != 1); + BUG_ON(!err); + cs->len = err; + cs->offset = off; cs->pg = page; - cs->offset = cs->addr % PAGE_SIZE; - cs->len = min(PAGE_SIZE - cs->offset, cs->seglen); - cs->seglen -= cs->len; - cs->addr += cs->len; + cs->offset = off; + iov_iter_advance(cs->iter, err); } return lock_request(cs->fc, cs->req); @@ -1374,7 +1366,7 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to) if (!iter_is_iovec(to)) return -EINVAL; - fuse_copy_init(&cs, fc, 1, to->iov, to->nr_segs); + fuse_copy_init(&cs, fc, 1, to); return fuse_dev_do_read(fc, file, &cs, iov_iter_count(to)); } @@ -1396,7 +1388,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, if (!bufs) return -ENOMEM; - fuse_copy_init(&cs, fc, 1, NULL, 0); + fuse_copy_init(&cs, fc, 1, NULL); cs.pipebufs = bufs; cs.pipe = pipe; 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) if (!iter_is_iovec(from)) return -EINVAL; - fuse_copy_init(&cs, fc, 0, from->iov, from->nr_segs); + fuse_copy_init(&cs, fc, 0, from); return fuse_dev_do_write(fc, &cs, iov_iter_count(from)); } @@ -2047,8 +2039,9 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, } pipe_unlock(pipe); - fuse_copy_init(&cs, fc, 0, NULL, nbuf); + fuse_copy_init(&cs, fc, 0, NULL); cs.pipebufs = bufs; + cs.nr_segs = nbuf; cs.pipe = pipe; if (flags & SPLICE_F_MOVE) |