aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-07-03 01:05:02 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-07-12 18:23:17 -0400
commit039b756a2d347bfbcdeb36dde25b6c472f0c4bb6 (patch)
treea242926c84a284e0447eaa9e15eaeca134dbc99d
parentfe08c54691f26cbdaf8c88c9c946a3e07d6feb00 (diff)
nfs41: layout return on close in delegation return
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>
-rw-r--r--fs/nfs/nfs4proc.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 734f7da10241..0a6fdc036915 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5030,6 +5030,9 @@ struct nfs4_delegreturndata {
5030 unsigned long timestamp; 5030 unsigned long timestamp;
5031 struct nfs_fattr fattr; 5031 struct nfs_fattr fattr;
5032 int rpc_status; 5032 int rpc_status;
5033 struct inode *inode;
5034 bool roc;
5035 u32 roc_barrier;
5033}; 5036};
5034 5037
5035static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) 5038static 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)
5043 switch (task->tk_status) { 5046 switch (task->tk_status) {
5044 case 0: 5047 case 0:
5045 renew_lease(data->res.server, data->timestamp); 5048 renew_lease(data->res.server, data->timestamp);
5046 break;
5047 case -NFS4ERR_ADMIN_REVOKED: 5049 case -NFS4ERR_ADMIN_REVOKED:
5048 case -NFS4ERR_DELEG_REVOKED: 5050 case -NFS4ERR_DELEG_REVOKED:
5049 case -NFS4ERR_BAD_STATEID: 5051 case -NFS4ERR_BAD_STATEID:
@@ -5051,6 +5053,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
5051 case -NFS4ERR_STALE_STATEID: 5053 case -NFS4ERR_STALE_STATEID:
5052 case -NFS4ERR_EXPIRED: 5054 case -NFS4ERR_EXPIRED:
5053 task->tk_status = 0; 5055 task->tk_status = 0;
5056 if (data->roc)
5057 pnfs_roc_set_barrier(data->inode, data->roc_barrier);
5054 break; 5058 break;
5055 default: 5059 default:
5056 if (nfs4_async_handle_error(task, data->res.server, NULL) == 5060 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)
5064 5068
5065static void nfs4_delegreturn_release(void *calldata) 5069static void nfs4_delegreturn_release(void *calldata)
5066{ 5070{
5071 struct nfs4_delegreturndata *data = calldata;
5072
5073 if (data->roc)
5074 pnfs_roc_release(data->inode);
5067 kfree(calldata); 5075 kfree(calldata);
5068} 5076}
5069 5077
@@ -5073,6 +5081,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
5073 5081
5074 d_data = (struct nfs4_delegreturndata *)data; 5082 d_data = (struct nfs4_delegreturndata *)data;
5075 5083
5084 if (d_data->roc &&
5085 pnfs_roc_drain(d_data->inode, &d_data->roc_barrier, task))
5086 return;
5087
5076 nfs4_setup_sequence(d_data->res.server, 5088 nfs4_setup_sequence(d_data->res.server,
5077 &d_data->args.seq_args, 5089 &d_data->args.seq_args,
5078 &d_data->res.seq_res, 5090 &d_data->res.seq_res,
@@ -5116,6 +5128,9 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
5116 nfs_fattr_init(data->res.fattr); 5128 nfs_fattr_init(data->res.fattr);
5117 data->timestamp = jiffies; 5129 data->timestamp = jiffies;
5118 data->rpc_status = 0; 5130 data->rpc_status = 0;
5131 data->inode = inode;
5132 data->roc = list_empty(&NFS_I(inode)->open_files) ?
5133 pnfs_roc(inode) : false;
5119 5134
5120 task_setup_data.callback_data = data; 5135 task_setup_data.callback_data = data;
5121 msg.rpc_argp = &data->args; 5136 msg.rpc_argp = &data->args;