NFSv4.1: rearrange nfs_write_rpcsetup
[pandora-kernel.git] / fs / nfs / write.c
index c8278f4..ae03599 100644 (file)
@@ -28,6 +28,7 @@
 #include "iostat.h"
 #include "nfs4_fs.h"
 #include "fscache.h"
+#include "pnfs.h"
 
 #define NFSDBG_FACILITY                NFSDBG_PAGECACHE
 
@@ -781,25 +782,21 @@ static int flush_task_priority(int how)
        return RPC_PRIORITY_NORMAL;
 }
 
-/*
- * Set up the argument/result storage required for the RPC call.
- */
-static int nfs_write_rpcsetup(struct nfs_page *req,
-               struct nfs_write_data *data,
-               const struct rpc_call_ops *call_ops,
-               unsigned int count, unsigned int offset,
-               int how)
+static int nfs_initiate_write(struct nfs_write_data *data,
+                      struct rpc_clnt *clnt,
+                      const struct rpc_call_ops *call_ops,
+                      int how)
 {
-       struct inode *inode = req->wb_context->path.dentry->d_inode;
+       struct inode *inode = data->inode;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
                .rpc_argp = &data->args,
                .rpc_resp = &data->res,
-               .rpc_cred = req->wb_context->cred,
+               .rpc_cred = data->cred,
        };
        struct rpc_task_setup task_setup_data = {
-               .rpc_client = NFS_CLIENT(inode),
+               .rpc_client = clnt,
                .task = &data->task,
                .rpc_message = &msg,
                .callback_ops = call_ops,
@@ -810,12 +807,49 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
        };
        int ret = 0;
 
+       /* Set up the initial task struct.  */
+       NFS_PROTO(inode)->write_setup(data, &msg);
+
+       dprintk("NFS: %5u initiated write call "
+               "(req %s/%lld, %u bytes @ offset %llu)\n",
+               data->task.tk_pid,
+               inode->i_sb->s_id,
+               (long long)NFS_FILEID(inode),
+               data->args.count,
+               (unsigned long long)data->args.offset);
+
+       task = rpc_run_task(&task_setup_data);
+       if (IS_ERR(task)) {
+               ret = PTR_ERR(task);
+               goto out;
+       }
+       if (how & FLUSH_SYNC) {
+               ret = rpc_wait_for_completion_task(task);
+               if (ret == 0)
+                       ret = task->tk_status;
+       }
+       rpc_put_task(task);
+out:
+       return ret;
+}
+
+/*
+ * Set up the argument/result storage required for the RPC call.
+ */
+static int nfs_write_rpcsetup(struct nfs_page *req,
+               struct nfs_write_data *data,
+               const struct rpc_call_ops *call_ops,
+               unsigned int count, unsigned int offset,
+               int how)
+{
+       struct inode *inode = req->wb_context->path.dentry->d_inode;
+
        /* Set up the RPC argument and reply structs
         * NB: take care not to mess about with data->commit et al. */
 
        data->req = req;
        data->inode = inode = req->wb_context->path.dentry->d_inode;
-       data->cred = msg.rpc_cred;
+       data->cred = req->wb_context->cred;
 
        data->args.fh     = NFS_FH(inode);
        data->args.offset = req_offset(req) + offset;
@@ -836,30 +870,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
        data->res.verf    = &data->verf;
        nfs_fattr_init(&data->fattr);
 
-       /* Set up the initial task struct.  */
-       NFS_PROTO(inode)->write_setup(data, &msg);
-
-       dprintk("NFS: %5u initiated write call "
-               "(req %s/%lld, %u bytes @ offset %llu)\n",
-               data->task.tk_pid,
-               inode->i_sb->s_id,
-               (long long)NFS_FILEID(inode),
-               count,
-               (unsigned long long)data->args.offset);
-
-       task = rpc_run_task(&task_setup_data);
-       if (IS_ERR(task)) {
-               ret = PTR_ERR(task);
-               goto out;
-       }
-       if (how & FLUSH_SYNC) {
-               ret = rpc_wait_for_completion_task(task);
-               if (ret == 0)
-                       ret = task->tk_status;
-       }
-       rpc_put_task(task);
-out:
-       return ret;
+       return nfs_initiate_write(data, NFS_CLIENT(inode), call_ops, how);
 }
 
 /* If a nfs_flush_* function fails, it should remove reqs from @head and
@@ -879,7 +890,7 @@ static void nfs_redirty_request(struct nfs_page *req)
  * Generate multiple small requests to write out a single
  * contiguous dirty area on one page.
  */
-static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how)
+static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how, struct pnfs_layout_segment *lseg)
 {
        struct nfs_page *req = nfs_list_entry(head->next);
        struct page *page = req->wb_page;
@@ -946,7 +957,7 @@ out_bad:
  * This is the case if nfs_updatepage detects a conflicting request
  * that has been written but not committed.
  */
-static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how)
+static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how, struct pnfs_layout_segment *lseg)
 {
        struct nfs_page         *req;
        struct page             **pages;
@@ -982,6 +993,8 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
 {
        size_t wsize = NFS_SERVER(inode)->wsize;
 
+       pgio->pg_test = NULL;
+
        if (wsize < PAGE_CACHE_SIZE)
                nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags);
        else
@@ -1132,7 +1145,7 @@ static const struct rpc_call_ops nfs_write_full_ops = {
 /*
  * This function is called when the WRITE call is complete.
  */
-int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
+void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 {
        struct nfs_writeargs    *argp = &data->args;
        struct nfs_writeres     *resp = &data->res;
@@ -1151,7 +1164,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
         */
        status = NFS_PROTO(data->inode)->write_done(task, data);
        if (status != 0)
-               return status;
+               return;
        nfs_add_stats(data->inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -1196,7 +1209,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
                                argp->stable = NFS_FILE_SYNC;
                        }
                        nfs_restart_rpc(task, server->nfs_client);
-                       return -EAGAIN;
+                       return;
                }
                if (time_before(complain, jiffies)) {
                        printk(KERN_WARNING
@@ -1207,7 +1220,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
                /* Can't do anything about it except throw an error. */
                task->tk_status = -EIO;
        }
-       return 0;
+       return;
 }
 
 
@@ -1292,6 +1305,8 @@ static int nfs_commit_rpcsetup(struct list_head *head,
        task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task))
                return PTR_ERR(task);
+       if (how & FLUSH_SYNC)
+               rpc_wait_for_completion_task(task);
        rpc_put_task(task);
        return 0;
 }