]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfs/read.c
vm audit: add VM_DONTEXPAND to mmap for drivers that need it
[linux-2.6-omap-h63xx.git] / fs / nfs / read.c
index 7bd7cb95c034d8bbcdbcdb05fbba5f46a291e68c..8fd6dfbe1bc3b8c248595a85fc5d3f3b86779ee3 100644 (file)
@@ -145,8 +145,8 @@ static void nfs_readpage_release(struct nfs_page *req)
        unlock_page(req->wb_page);
 
        dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
-                       req->wb_context->dentry->d_inode->i_sb->s_id,
-                       (long long)NFS_FILEID(req->wb_context->dentry->d_inode),
+                       req->wb_context->path.dentry->d_inode->i_sb->s_id,
+                       (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
                        req->wb_bytes,
                        (long long)req_offset(req));
        nfs_clear_request(req);
@@ -160,12 +160,26 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
                const struct rpc_call_ops *call_ops,
                unsigned int count, unsigned int offset)
 {
-       struct inode            *inode;
-       int flags;
+       struct inode *inode = req->wb_context->path.dentry->d_inode;
+       int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0;
+       struct rpc_task *task;
+       struct rpc_message msg = {
+               .rpc_argp = &data->args,
+               .rpc_resp = &data->res,
+               .rpc_cred = req->wb_context->cred,
+       };
+       struct rpc_task_setup task_setup_data = {
+               .task = &data->task,
+               .rpc_client = NFS_CLIENT(inode),
+               .rpc_message = &msg,
+               .callback_ops = call_ops,
+               .callback_data = data,
+               .flags = RPC_TASK_ASYNC | swap_flags,
+       };
 
        data->req         = req;
-       data->inode       = inode = req->wb_context->dentry->d_inode;
-       data->cred        = req->wb_context->cred;
+       data->inode       = inode;
+       data->cred        = msg.rpc_cred;
 
        data->args.fh     = NFS_FH(inode);
        data->args.offset = req_offset(req) + offset;
@@ -180,11 +194,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
        nfs_fattr_init(&data->fattr);
 
        /* Set up the initial task struct. */
-       flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
-       rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data);
-       NFS_PROTO(inode)->read_setup(data);
-
-       data->task.tk_cookie = (unsigned long)inode;
+       NFS_PROTO(inode)->read_setup(data, &msg);
 
        dprintk("NFS: %5u initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
                        data->task.tk_pid,
@@ -192,6 +202,10 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
                        (long long)NFS_FILEID(inode),
                        count,
                        (unsigned long long)data->args.offset);
+
+       task = rpc_run_task(&task_setup_data);
+       if (!IS_ERR(task))
+               rpc_put_task(task);
 }
 
 static void
@@ -207,19 +221,6 @@ nfs_async_read_error(struct list_head *head)
        }
 }
 
-/*
- * Start an async read operation
- */
-static void nfs_execute_read(struct nfs_read_data *data)
-{
-       struct rpc_clnt *clnt = NFS_CLIENT(data->inode);
-       sigset_t oldset;
-
-       rpc_clnt_sigmask(clnt, &oldset);
-       rpc_execute(&data->task);
-       rpc_clnt_sigunmask(clnt, &oldset);
-}
-
 /*
  * Generate multiple requests to fill a single page.
  *
@@ -274,7 +275,6 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
                                  rsize, offset);
                offset += rsize;
                nbytes -= rsize;
-               nfs_execute_read(data);
        } while (nbytes != 0);
 
        return 0;
@@ -312,8 +312,6 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
        req = nfs_list_entry(data->pages.next);
 
        nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0);
-
-       nfs_execute_read(data);
        return 0;
 out_bad:
        nfs_async_read_error(head);
@@ -338,12 +336,9 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data)
        nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, data->res.count);
 
        if (task->tk_status == -ESTALE) {
-               set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode));
+               set_bit(NFS_INO_STALE, &NFS_I(data->inode)->flags);
                nfs_mark_for_revalidate(data->inode);
        }
-       spin_lock(&data->inode->i_lock);
-       NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME;
-       spin_unlock(&data->inode->i_lock);
        return 0;
 }
 
@@ -483,27 +478,27 @@ int nfs_readpage(struct file *file, struct page *page)
         */
        error = nfs_wb_page(inode, page);
        if (error)
-               goto out_error;
+               goto out_unlock;
+       if (PageUptodate(page))
+               goto out_unlock;
 
        error = -ESTALE;
        if (NFS_STALE(inode))
-               goto out_error;
+               goto out_unlock;
 
        if (file == NULL) {
                error = -EBADF;
                ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
                if (ctx == NULL)
-                       goto out_error;
+                       goto out_unlock;
        } else
-               ctx = get_nfs_open_context((struct nfs_open_context *)
-                               file->private_data);
+               ctx = get_nfs_open_context(nfs_file_open_context(file));
 
        error = nfs_readpage_async(ctx, inode, page);
 
        put_nfs_open_context(ctx);
        return error;
-
-out_error:
+out_unlock:
        unlock_page(page);
        return error;
 }
@@ -520,21 +515,32 @@ readpage_async_filler(void *data, struct page *page)
        struct inode *inode = page->mapping->host;
        struct nfs_page *new;
        unsigned int len;
+       int error;
+
+       error = nfs_wb_page(inode, page);
+       if (error)
+               goto out_unlock;
+       if (PageUptodate(page))
+               goto out_unlock;
 
-       nfs_wb_page(inode, page);
        len = nfs_page_length(page);
        if (len == 0)
                return nfs_return_empty_page(page);
+
        new = nfs_create_request(desc->ctx, inode, page, 0, len);
-       if (IS_ERR(new)) {
-                       SetPageError(page);
-                       unlock_page(page);
-                       return PTR_ERR(new);
-       }
+       if (IS_ERR(new))
+               goto out_error;
+
        if (len < PAGE_CACHE_SIZE)
                zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0);
        nfs_pageio_add_request(desc->pgio, new);
        return 0;
+out_error:
+       error = PTR_ERR(new);
+       SetPageError(page);
+out_unlock:
+       unlock_page(page);
+       return error;
 }
 
 int nfs_readpages(struct file *filp, struct address_space *mapping,
@@ -564,8 +570,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
                if (desc.ctx == NULL)
                        return -EBADF;
        } else
-               desc.ctx = get_nfs_open_context((struct nfs_open_context *)
-                               filp->private_data);
+               desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
        if (rsize < PAGE_CACHE_SIZE)
                nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
        else
@@ -586,7 +591,7 @@ int __init nfs_init_readpagecache(void)
        nfs_rdata_cachep = kmem_cache_create("nfs_read_data",
                                             sizeof(struct nfs_read_data),
                                             0, SLAB_HWCACHE_ALIGN,
-                                            NULL, NULL);
+                                            NULL);
        if (nfs_rdata_cachep == NULL)
                return -ENOMEM;