]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/fuse/dev.c
Merge tag 'drm/panel/for-4.11-rc1' of git://anongit.freedesktop.org/tegra/linux into...
[karo-tx-linux.git] / fs / fuse / dev.c
index a94d2ed81ab4af4bf7cc8316d5f7517a9902c3a2..4e06a27ed7f80d4d0472e3d6c9e9fe3f0f1d7da5 100644 (file)
@@ -728,7 +728,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
                struct pipe_buffer *buf = cs->pipebufs;
 
                if (!cs->write) {
-                       err = buf->ops->confirm(cs->pipe, buf);
+                       err = pipe_buf_confirm(cs->pipe, buf);
                        if (err)
                                return err;
 
@@ -767,7 +767,6 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
                cs->len = err;
                cs->offset = off;
                cs->pg = page;
-               cs->offset = off;
                iov_iter_advance(cs->iter, err);
        }
 
@@ -828,7 +827,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
 
        fuse_copy_finish(cs);
 
-       err = buf->ops->confirm(cs->pipe, buf);
+       err = pipe_buf_confirm(cs->pipe, buf);
        if (err)
                return err;
 
@@ -841,7 +840,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
        if (cs->len != PAGE_SIZE)
                goto out_fallback;
 
-       if (buf->ops->steal(cs->pipe, buf) != 0)
+       if (pipe_buf_steal(cs->pipe, buf) != 0)
                goto out_fallback;
 
        newpage = buf->page;
@@ -1342,9 +1341,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,52 +1361,23 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
        if (ret < 0)
                goto out;
 
-       ret = 0;
-       pipe_lock(pipe);
-
-       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:
-       pipe_unlock(pipe);
-
-       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);
@@ -1993,7 +1962,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
                        pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1);
                        pipe->nrbufs--;
                } else {
-                       ibuf->ops->get(pipe, ibuf);
+                       pipe_buf_get(pipe, ibuf);
                        *obuf = *ibuf;
                        obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
                        obuf->len = rem;
@@ -2015,10 +1984,9 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
 
        ret = fuse_dev_do_write(fud, &cs, len);
 
-       for (idx = 0; idx < nbuf; idx++) {
-               struct pipe_buffer *buf = &bufs[idx];
-               buf->ops->release(pipe, buf);
-       }
+       for (idx = 0; idx < nbuf; idx++)
+               pipe_buf_release(pipe, &bufs[idx]);
+
 out:
        kfree(bufs);
        return ret;
@@ -2057,7 +2025,6 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head)
                struct fuse_req *req;
                req = list_entry(head->next, struct fuse_req, list);
                req->out.h.error = -ECONNABORTED;
-               clear_bit(FR_PENDING, &req->flags);
                clear_bit(FR_SENT, &req->flags);
                list_del_init(&req->list);
                request_end(fc, req);
@@ -2135,6 +2102,8 @@ void fuse_abort_conn(struct fuse_conn *fc)
                spin_lock(&fiq->waitq.lock);
                fiq->connected = 0;
                list_splice_init(&fiq->pending, &to_end2);
+               list_for_each_entry(req, &to_end2, list)
+                       clear_bit(FR_PENDING, &req->flags);
                while (forget_pending(fiq))
                        kfree(dequeue_forget(fiq, 1, NULL));
                wake_up_all_locked(&fiq->waitq);