diff options
author | Alexandros Batsakis <batsakis@netapp.com> | 2010-02-05 06:45:04 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-02 12:44:07 -0500 |
commit | dc96aef96a75348b4d1b01c4c0429ab52780683e (patch) | |
tree | 1bd4755b97367a8db0e2ea949cb3a4fd84ec3a66 /fs/nfs/nfs4proc.c | |
parent | 888ef2e3f8b7b8daeb031bfb4ad1fd4fa817e193 (diff) |
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.c | 24 |
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 | |||
3147 | * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special | 3147 | * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special |
3148 | * standalone procedure for queueing an asynchronous RENEW. | 3148 | * standalone procedure for queueing an asynchronous RENEW. |
3149 | */ | 3149 | */ |
3150 | static void nfs4_renew_release(void *data) | ||
3151 | { | ||
3152 | struct nfs_client *clp = data; | ||
3153 | |||
3154 | nfs4_schedule_state_renewal(clp); | ||
3155 | } | ||
3156 | |||
3150 | static void nfs4_renew_done(struct rpc_task *task, void *data) | 3157 | static void nfs4_renew_done(struct rpc_task *task, void *data) |
3151 | { | 3158 | { |
3152 | struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp; | 3159 | struct nfs_client *clp = data; |
3153 | unsigned long timestamp = (unsigned long)data; | 3160 | unsigned long timestamp = task->tk_start; |
3154 | 3161 | ||
3155 | if (task->tk_status < 0) { | 3162 | if (task->tk_status < 0) { |
3156 | /* Unless we're shutting down, schedule state recovery! */ | 3163 | /* Unless we're shutting down, schedule state recovery! */ |
@@ -3166,6 +3173,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data) | |||
3166 | 3173 | ||
3167 | static const struct rpc_call_ops nfs4_renew_ops = { | 3174 | static const struct rpc_call_ops nfs4_renew_ops = { |
3168 | .rpc_call_done = nfs4_renew_done, | 3175 | .rpc_call_done = nfs4_renew_done, |
3176 | .rpc_release = nfs4_renew_release, | ||
3169 | }; | 3177 | }; |
3170 | 3178 | ||
3171 | int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred) | 3179 | 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) | |||
3177 | }; | 3185 | }; |
3178 | 3186 | ||
3179 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, | 3187 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, |
3180 | &nfs4_renew_ops, (void *)jiffies); | 3188 | &nfs4_renew_ops, clp); |
3181 | } | 3189 | } |
3182 | 3190 | ||
3183 | int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) | 3191 | 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) | |||
5023 | &res, args.sa_cache_this, 1); | 5031 | &res, args.sa_cache_this, 1); |
5024 | } | 5032 | } |
5025 | 5033 | ||
5026 | void nfs41_sequence_call_done(struct rpc_task *task, void *data) | 5034 | static void nfs41_sequence_release(void *data) |
5035 | { | ||
5036 | struct nfs_client *clp = (struct nfs_client *)data; | ||
5037 | |||
5038 | nfs4_schedule_state_renewal(clp); | ||
5039 | } | ||
5040 | |||
5041 | static void nfs41_sequence_call_done(struct rpc_task *task, void *data) | ||
5027 | { | 5042 | { |
5028 | struct nfs_client *clp = (struct nfs_client *)data; | 5043 | struct nfs_client *clp = (struct nfs_client *)data; |
5029 | 5044 | ||
@@ -5064,6 +5079,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data) | |||
5064 | static const struct rpc_call_ops nfs41_sequence_ops = { | 5079 | static const struct rpc_call_ops nfs41_sequence_ops = { |
5065 | .rpc_call_done = nfs41_sequence_call_done, | 5080 | .rpc_call_done = nfs41_sequence_call_done, |
5066 | .rpc_call_prepare = nfs41_sequence_prepare, | 5081 | .rpc_call_prepare = nfs41_sequence_prepare, |
5082 | .rpc_release = nfs41_sequence_release, | ||
5067 | }; | 5083 | }; |
5068 | 5084 | ||
5069 | static int nfs41_proc_async_sequence(struct nfs_client *clp, | 5085 | static int nfs41_proc_async_sequence(struct nfs_client *clp, |