fuse_dev_splice_read(): switch to add_to_pipe()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 18 Sep 2016 02:56:25 +0000 (22:56 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 4 Oct 2016 00:40:56 +0000 (20:40 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/fuse/dev.c

index eaf56c6..0a6a808 100644 (file)
@@ -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);