pandora: defconfig: update
[pandora-kernel.git] / fs / fuse / dev.c
index 5cb8614..8fe69e7 100644 (file)
@@ -148,8 +148,7 @@ static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
                if (ff->reserved_req) {
                        req = ff->reserved_req;
                        ff->reserved_req = NULL;
-                       get_file(file);
-                       req->stolen_file = file;
+                       req->stolen_file = get_file(file);
                }
                spin_unlock(&fc->lock);
        } while (!req);
@@ -717,8 +716,8 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
 
        newpage = buf->page;
 
-       if (WARN_ON(!PageUptodate(newpage)))
-               return -EIO;
+       if (!PageUptodate(newpage))
+               SetPageUptodate(newpage);
 
        ClearPageMappedToDisk(newpage);
 
@@ -1199,22 +1198,6 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
        return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
 }
 
-static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe,
-                                  struct pipe_buffer *buf)
-{
-       return 1;
-}
-
-static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = {
-       .can_merge = 0,
-       .map = generic_pipe_buf_map,
-       .unmap = generic_pipe_buf_unmap,
-       .confirm = generic_pipe_buf_confirm,
-       .release = generic_pipe_buf_release,
-       .steal = fuse_dev_pipe_buf_steal,
-       .get = generic_pipe_buf_get,
-};
-
 static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
                                    struct pipe_inode_info *pipe,
                                    size_t len, unsigned int flags)
@@ -1261,7 +1244,11 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
                buf->page = bufs[page_nr].page;
                buf->offset = bufs[page_nr].offset;
                buf->len = bufs[page_nr].len;
-               buf->ops = &fuse_dev_pipe_buf_ops;
+               /*
+                * 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++;
@@ -1512,7 +1499,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
        else if (outarg->offset + num > file_size)
                num = file_size - outarg->offset;
 
-       while (num) {
+       while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) {
                struct page *page;
                unsigned int this_num;
 
@@ -1524,8 +1511,10 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
                req->pages[req->num_pages] = page;
                req->num_pages++;
 
+               offset = 0;
                num -= this_num;
                total_len += this_num;
+               index++;
        }
        req->misc.retrieve_in.offset = outarg->offset;
        req->misc.retrieve_in.size = total_len;
@@ -1580,6 +1569,9 @@ copy_finish:
 static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
                       unsigned int size, struct fuse_copy_state *cs)
 {
+       /* Don't try to move pages (yet) */
+       cs->move_pages = 0;
+
        switch (code) {
        case FUSE_NOTIFY_POLL:
                return fuse_notify_poll(fc, size, cs);