Commit d82718e3 authored by Al Viro's avatar Al Viro

fuse_dev_splice_read(): switch to add_to_pipe()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 25869262
...@@ -1342,9 +1342,8 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, ...@@ -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, ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment