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

Commit d82718e3 authored by Al Viro's avatar Al Viro
Browse files

fuse_dev_splice_read(): switch to add_to_pipe()



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 25869262
Loading
Loading
Loading
Loading
+9 −37
Original line number Original line Diff line number Diff line
@@ -1342,9 +1342,8 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
				    struct pipe_inode_info *pipe,
				    struct pipe_inode_info *pipe,
				    size_t len, unsigned int flags)
				    size_t len, unsigned int flags)
{
{
	int ret;
	int total, ret;
	int page_nr = 0;
	int page_nr = 0;
	int do_wakeup = 0;
	struct pipe_buffer *bufs;
	struct pipe_buffer *bufs;
	struct fuse_copy_state cs;
	struct fuse_copy_state cs;
	struct fuse_dev *fud = fuse_get_dev(in);
	struct fuse_dev *fud = fuse_get_dev(in);
@@ -1363,50 +1362,23 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
	if (ret < 0)
	if (ret < 0)
		goto out;
		goto out;


	ret = 0;

	if (!pipe->readers) {
		send_sig(SIGPIPE, current, 0);
		if (!ret)
			ret = -EPIPE;
		goto out_unlock;
	}

	if (pipe->nrbufs + cs.nr_segs > pipe->buffers) {
	if (pipe->nrbufs + cs.nr_segs > pipe->buffers) {
		ret = -EIO;
		ret = -EIO;
		goto out_unlock;
		goto out;
	}
	}


	while (page_nr < cs.nr_segs) {
	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
		int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
		struct pipe_buffer *buf = pipe->bufs + newbuf;

		buf->page = bufs[page_nr].page;
		buf->offset = bufs[page_nr].offset;
		buf->len = bufs[page_nr].len;
		/*
		/*
		 * Need to be careful about this.  Having buf->ops in module
		 * Need to be careful about this.  Having buf->ops in module
		 * code can Oops if the buffer persists after module unload.
		 * code can Oops if the buffer persists after module unload.
		 */
		 */
		buf->ops = &nosteal_pipe_buf_ops;
		bufs[page_nr].ops = &nosteal_pipe_buf_ops;

		ret = add_to_pipe(pipe, &bufs[page_nr++]);
		pipe->nrbufs++;
		if (unlikely(ret < 0))
		page_nr++;
			break;
		ret += buf->len;

		if (pipe->files)
			do_wakeup = 1;
	}

out_unlock:

	if (do_wakeup) {
		smp_mb();
		if (waitqueue_active(&pipe->wait))
			wake_up_interruptible(&pipe->wait);
		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
	}
	}

	if (total)
		ret = total;
out:
out:
	for (; page_nr < cs.nr_segs; page_nr++)
	for (; page_nr < cs.nr_segs; page_nr++)
		put_page(bufs[page_nr].page);
		put_page(bufs[page_nr].page);