summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorAlexandros Batsakis <batsakis@netapp.com>2010-02-05 03:45:04 -0800
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-03-02 12:44:07 -0500
commitdc96aef96a75348b4d1b01c4c0429ab52780683e (patch)
tree1bd4755b97367a8db0e2ea949cb3a4fd84ec3a66 /fs/nfs/nfs4proc.c
parent888ef2e3f8b7b8daeb031bfb4ad1fd4fa817e193 (diff)
downloadlinux-dc96aef96a75348b4d1b01c4c0429ab52780683e.tar.gz
linux-dc96aef96a75348b4d1b01c4c0429ab52780683e.tar.bz2
linux-dc96aef96a75348b4d1b01c4c0429ab52780683e.zip
nfs: prevent backlogging of renewd requests
If the renewd send queue gets backlogged (e.g., if the server goes down), we will keep filling the queue with periodic RENEW/SEQUENCE requests. This patch schedules a new renewd request if and only if the previous one returns (either success or failure) Signed-off-by: Alexandros Batsakis <batsakis@netapp.com> [Trond.Myklebust@netapp.com: moved nfs4_schedule_state_renewal() into separate nfs4_renew_release() and nfs41_sequence_release() callbacks to ensure correct behaviour on call setup failure] Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 84b53d38f50b..726bc195039d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3147,10 +3147,17 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
* nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
* standalone procedure for queueing an asynchronous RENEW.
*/
+static void nfs4_renew_release(void *data)
+{
+ struct nfs_client *clp = data;
+
+ nfs4_schedule_state_renewal(clp);
+}
+
static void nfs4_renew_done(struct rpc_task *task, void *data)
{
- struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp;
- unsigned long timestamp = (unsigned long)data;
+ struct nfs_client *clp = data;
+ unsigned long timestamp = task->tk_start;
if (task->tk_status < 0) {
/* Unless we're shutting down, schedule state recovery! */
@@ -3166,6 +3173,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
static const struct rpc_call_ops nfs4_renew_ops = {
.rpc_call_done = nfs4_renew_done,
+ .rpc_release = nfs4_renew_release,
};
int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3177,7 +3185,7 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
};
return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
- &nfs4_renew_ops, (void *)jiffies);
+ &nfs4_renew_ops, clp);
}
int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -5023,7 +5031,14 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
&res, args.sa_cache_this, 1);
}
-void nfs41_sequence_call_done(struct rpc_task *task, void *data)
+static void nfs41_sequence_release(void *data)
+{
+ struct nfs_client *clp = (struct nfs_client *)data;
+
+ nfs4_schedule_state_renewal(clp);
+}
+
+static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
{
struct nfs_client *clp = (struct nfs_client *)data;
@@ -5064,6 +5079,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
static const struct rpc_call_ops nfs41_sequence_ops = {
.rpc_call_done = nfs41_sequence_call_done,
.rpc_call_prepare = nfs41_sequence_prepare,
+ .rpc_release = nfs41_sequence_release,
};
static int nfs41_proc_async_sequence(struct nfs_client *clp,