summaryrefslogtreecommitdiff
path: root/fs/fuse
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-09-17 22:56:25 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-10-03 20:40:56 -0400
commitd82718e348fee15dbce8f578ff2588982b7cc7ca (patch)
treed9628878f9a140bef13a2e1e3c974aeb63451758 /fs/fuse
parent25869262ef7af24ccde988867ac3eb1c3d4b88d4 (diff)
downloadlwn-d82718e348fee15dbce8f578ff2588982b7cc7ca.tar.gz
lwn-d82718e348fee15dbce8f578ff2588982b7cc7ca.zip
fuse_dev_splice_read(): switch to add_to_pipe()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c46
1 files changed, 9 insertions, 37 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index eaf56c6e9123..0a6a808d561c 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1342,9 +1342,8 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe,
size_t len, unsigned int flags)
{
- int ret;
+ int total, ret;
int page_nr = 0;
- int do_wakeup = 0;
struct pipe_buffer *bufs;
struct fuse_copy_state cs;
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)
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) {
ret = -EIO;
- goto out_unlock;
+ goto out;
}
- while (page_nr < cs.nr_segs) {
- 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;
+ for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
/*
* Need to be careful about this. Having buf->ops in module
* code can Oops if the buffer persists after module unload.
*/
- buf->ops = &nosteal_pipe_buf_ops;
-
- pipe->nrbufs++;
- page_nr++;
- 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);
+ bufs[page_nr].ops = &nosteal_pipe_buf_ops;
+ ret = add_to_pipe(pipe, &bufs[page_nr++]);
+ if (unlikely(ret < 0))
+ break;
}
-
+ if (total)
+ ret = total;
out:
for (; page_nr < cs.nr_segs; page_nr++)
put_page(bufs[page_nr].page);