]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
nfs41: layout return on close in delegation return
authorPeng Tao <tao.peng@primarydata.com>
Thu, 3 Jul 2014 05:05:02 +0000 (13:05 +0800)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Sat, 12 Jul 2014 22:23:17 +0000 (18:23 -0400)
If file is not opened by anyone, we do layout return on close
in delegation return.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/nfs4proc.c

index 734f7da1024142da16676f2834ab168924882859..0a6fdc036915458c6c904e47a30e62f4a2468f9b 100644 (file)
@@ -5030,6 +5030,9 @@ struct nfs4_delegreturndata {
        unsigned long timestamp;
        struct nfs_fattr fattr;
        int rpc_status;
+       struct inode *inode;
+       bool roc;
+       u32 roc_barrier;
 };
 
 static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
@@ -5043,7 +5046,6 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
        switch (task->tk_status) {
        case 0:
                renew_lease(data->res.server, data->timestamp);
-               break;
        case -NFS4ERR_ADMIN_REVOKED:
        case -NFS4ERR_DELEG_REVOKED:
        case -NFS4ERR_BAD_STATEID:
@@ -5051,6 +5053,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
        case -NFS4ERR_STALE_STATEID:
        case -NFS4ERR_EXPIRED:
                task->tk_status = 0;
+               if (data->roc)
+                       pnfs_roc_set_barrier(data->inode, data->roc_barrier);
                break;
        default:
                if (nfs4_async_handle_error(task, data->res.server, NULL) ==
@@ -5064,6 +5068,10 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
 
 static void nfs4_delegreturn_release(void *calldata)
 {
+       struct nfs4_delegreturndata *data = calldata;
+
+       if (data->roc)
+               pnfs_roc_release(data->inode);
        kfree(calldata);
 }
 
@@ -5073,6 +5081,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
 
        d_data = (struct nfs4_delegreturndata *)data;
 
+       if (d_data->roc &&
+           pnfs_roc_drain(d_data->inode, &d_data->roc_barrier, task))
+               return;
+
        nfs4_setup_sequence(d_data->res.server,
                        &d_data->args.seq_args,
                        &d_data->res.seq_res,
@@ -5116,6 +5128,9 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
        nfs_fattr_init(data->res.fattr);
        data->timestamp = jiffies;
        data->rpc_status = 0;
+       data->inode = inode;
+       data->roc = list_empty(&NFS_I(inode)->open_files) ?
+                   pnfs_roc(inode) : false;
 
        task_setup_data.callback_data = data;
        msg.rpc_argp = &data->args;