Commit 26e976a8 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: OPEN/LOCK/LOCKU/CLOSE will automatically renew the NFSv4 lease

 Cut down on the number of unnecessary RENEW requests on the wire.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 2bd61579
...@@ -174,8 +174,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry, ...@@ -174,8 +174,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
kunmap_atomic(start, KM_USER0); kunmap_atomic(start, KM_USER0);
} }
static void static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
renew_lease(struct nfs_server *server, unsigned long timestamp)
{ {
struct nfs4_client *clp = server->nfs4_state; struct nfs4_client *clp = server->nfs4_state;
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
...@@ -207,6 +206,7 @@ struct nfs4_opendata { ...@@ -207,6 +206,7 @@ struct nfs4_opendata {
struct dentry *dir; struct dentry *dir;
struct nfs4_state_owner *owner; struct nfs4_state_owner *owner;
struct iattr attrs; struct iattr attrs;
unsigned long timestamp;
int rpc_status; int rpc_status;
int cancelled; int cancelled;
}; };
...@@ -548,6 +548,7 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata) ...@@ -548,6 +548,7 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
.rpc_resp = &data->c_res, .rpc_resp = &data->c_res,
.rpc_cred = data->owner->so_cred, .rpc_cred = data->owner->so_cred,
}; };
data->timestamp = jiffies;
rpc_call_setup(task, &msg, 0); rpc_call_setup(task, &msg, 0);
} }
...@@ -558,9 +559,11 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) ...@@ -558,9 +559,11 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
data->rpc_status = task->tk_status; data->rpc_status = task->tk_status;
if (RPC_ASSASSINATED(task)) if (RPC_ASSASSINATED(task))
return; return;
if (data->rpc_status == 0) if (data->rpc_status == 0) {
memcpy(data->o_res.stateid.data, data->c_res.stateid.data, memcpy(data->o_res.stateid.data, data->c_res.stateid.data,
sizeof(data->o_res.stateid.data)); sizeof(data->o_res.stateid.data));
renew_lease(data->o_res.server, data->timestamp);
}
nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid); nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status); nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status);
} }
...@@ -633,6 +636,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) ...@@ -633,6 +636,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
data->o_arg.clientid = sp->so_client->cl_clientid; data->o_arg.clientid = sp->so_client->cl_clientid;
if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
data->timestamp = jiffies;
rpc_call_setup(task, &msg, 0); rpc_call_setup(task, &msg, 0);
} }
...@@ -656,6 +660,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata) ...@@ -656,6 +660,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
default: default:
data->rpc_status = -ENOTDIR; data->rpc_status = -ENOTDIR;
} }
renew_lease(data->o_res.server, data->timestamp);
} }
nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid); nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
} }
...@@ -1014,6 +1019,7 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr, ...@@ -1014,6 +1019,7 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
.rpc_argp = &arg, .rpc_argp = &arg,
.rpc_resp = &res, .rpc_resp = &res,
}; };
unsigned long timestamp = jiffies;
int status; int status;
nfs_fattr_init(fattr); nfs_fattr_init(fattr);
...@@ -1025,6 +1031,8 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr, ...@@ -1025,6 +1031,8 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, 0);
if (status == 0 && state != NULL)
renew_lease(server, timestamp);
return status; return status;
} }
...@@ -1049,6 +1057,7 @@ struct nfs4_closedata { ...@@ -1049,6 +1057,7 @@ struct nfs4_closedata {
struct nfs_closeargs arg; struct nfs_closeargs arg;
struct nfs_closeres res; struct nfs_closeres res;
struct nfs_fattr fattr; struct nfs_fattr fattr;
unsigned long timestamp;
}; };
static void nfs4_free_closedata(void *data) static void nfs4_free_closedata(void *data)
...@@ -1078,6 +1087,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) ...@@ -1078,6 +1087,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
case 0: case 0:
memcpy(&state->stateid, &calldata->res.stateid, memcpy(&state->stateid, &calldata->res.stateid,
sizeof(state->stateid)); sizeof(state->stateid));
renew_lease(server, calldata->timestamp);
break; break;
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED:
...@@ -1130,6 +1140,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) ...@@ -1130,6 +1140,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
if (mode != 0) if (mode != 0)
msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
calldata->arg.open_flags = mode; calldata->arg.open_flags = mode;
calldata->timestamp = jiffies;
rpc_call_setup(task, &msg, 0); rpc_call_setup(task, &msg, 0);
} }
...@@ -1694,11 +1705,13 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata) ...@@ -1694,11 +1705,13 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata)
wdata->args.bitmask = server->attr_bitmask; wdata->args.bitmask = server->attr_bitmask;
wdata->res.server = server; wdata->res.server = server;
wdata->timestamp = jiffies;
nfs_fattr_init(fattr); nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, rpcflags); status = rpc_call_sync(server->client, &msg, rpcflags);
dprintk("NFS reply write: %d\n", status); dprintk("NFS reply write: %d\n", status);
if (status < 0) if (status < 0)
return status; return status;
renew_lease(server, wdata->timestamp);
nfs_post_op_update_inode(inode, fattr); nfs_post_op_update_inode(inode, fattr);
return wdata->res.count; return wdata->res.count;
} }
...@@ -1733,8 +1746,11 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata) ...@@ -1733,8 +1746,11 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata)
cdata->args.bitmask = server->attr_bitmask; cdata->args.bitmask = server->attr_bitmask;
cdata->res.server = server; cdata->res.server = server;
cdata->timestamp = jiffies;
nfs_fattr_init(fattr); nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, 0);
if (status >= 0)
renew_lease(server, cdata->timestamp);
dprintk("NFS reply commit: %d\n", status); dprintk("NFS reply commit: %d\n", status);
if (status >= 0) if (status >= 0)
nfs_post_op_update_inode(inode, fattr); nfs_post_op_update_inode(inode, fattr);
...@@ -2890,6 +2906,8 @@ struct nfs4_delegreturndata { ...@@ -2890,6 +2906,8 @@ struct nfs4_delegreturndata {
struct nfs_fh fh; struct nfs_fh fh;
nfs4_stateid stateid; nfs4_stateid stateid;
struct rpc_cred *cred; struct rpc_cred *cred;
unsigned long timestamp;
const struct nfs_server *server;
int rpc_status; int rpc_status;
}; };
...@@ -2908,6 +2926,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) ...@@ -2908,6 +2926,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
{ {
struct nfs4_delegreturndata *data = calldata; struct nfs4_delegreturndata *data = calldata;
data->rpc_status = task->tk_status; data->rpc_status = task->tk_status;
if (data->rpc_status == 0)
renew_lease(data->server, data->timestamp);
} }
static void nfs4_delegreturn_release(void *calldata) static void nfs4_delegreturn_release(void *calldata)
...@@ -2938,6 +2958,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co ...@@ -2938,6 +2958,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
nfs_copy_fh(&data->fh, NFS_FH(inode)); nfs_copy_fh(&data->fh, NFS_FH(inode));
memcpy(&data->stateid, stateid, sizeof(data->stateid)); memcpy(&data->stateid, stateid, sizeof(data->stateid));
data->cred = get_rpccred(cred); data->cred = get_rpccred(cred);
data->timestamp = jiffies;
data->server = NFS_SERVER(inode);
data->rpc_status = 0; data->rpc_status = 0;
task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data);
...@@ -3067,6 +3089,7 @@ struct nfs4_unlockdata { ...@@ -3067,6 +3089,7 @@ struct nfs4_unlockdata {
struct nfs_open_context *ctx; struct nfs_open_context *ctx;
struct file_lock fl; struct file_lock fl;
const struct nfs_server *server; const struct nfs_server *server;
unsigned long timestamp;
}; };
static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
...@@ -3114,6 +3137,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) ...@@ -3114,6 +3137,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
memcpy(calldata->lsp->ls_stateid.data, memcpy(calldata->lsp->ls_stateid.data,
calldata->res.stateid.data, calldata->res.stateid.data,
sizeof(calldata->lsp->ls_stateid.data)); sizeof(calldata->lsp->ls_stateid.data));
renew_lease(calldata->server, calldata->timestamp);
break; break;
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED:
...@@ -3143,6 +3167,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) ...@@ -3143,6 +3167,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
task->tk_action = NULL; task->tk_action = NULL;
return; return;
} }
calldata->timestamp = jiffies;
rpc_call_setup(task, &msg, 0); rpc_call_setup(task, &msg, 0);
} }
...@@ -3214,6 +3239,7 @@ struct nfs4_lockdata { ...@@ -3214,6 +3239,7 @@ struct nfs4_lockdata {
struct nfs4_lock_state *lsp; struct nfs4_lock_state *lsp;
struct nfs_open_context *ctx; struct nfs_open_context *ctx;
struct file_lock fl; struct file_lock fl;
unsigned long timestamp;
int rpc_status; int rpc_status;
int cancelled; int cancelled;
}; };
...@@ -3273,6 +3299,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) ...@@ -3273,6 +3299,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
data->arg.open_stateid = &state->stateid; data->arg.open_stateid = &state->stateid;
data->arg.new_lock_owner = 1; data->arg.new_lock_owner = 1;
} }
data->timestamp = jiffies;
rpc_call_setup(task, &msg, 0); rpc_call_setup(task, &msg, 0);
out: out:
dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status);
...@@ -3298,6 +3325,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) ...@@ -3298,6 +3325,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
memcpy(data->lsp->ls_stateid.data, data->res.stateid.data, memcpy(data->lsp->ls_stateid.data, data->res.stateid.data,
sizeof(data->lsp->ls_stateid.data)); sizeof(data->lsp->ls_stateid.data));
data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
} }
nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid); nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment