Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c09e94a authored by Al Viro's avatar Al Viro
Browse files

fuse: use iov_iter_get_pages() for non-splice path



store reference to iter instead of that to iovec

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent fbdbacca
Loading
Loading
Loading
Loading
+17 −24
Original line number Diff line number Diff line
@@ -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)