diff options
author | Mike Sager <sager@netapp.com> | 2010-01-19 12:54:41 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-02-10 08:30:55 -0500 |
commit | 72ce2b3c064471fc511a9ca2fb6c38d90d2ab826 (patch) | |
tree | 5020b4040c1ead6521aef52933b39269fc955dfc /fs/nfs | |
parent | a7989c3e4702203baa5ddb3614f92bfc49a6e491 (diff) |
nfs41: Process callback's referring call list
If a CB_SEQUENCE referring call triple matches a slot table entry, the
client is still waiting for a response to the original request. In this
case, return NFS4ERR_DELAY as the response to the callback.
Signed-off-by: Mike Sager <sager@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/callback_proc.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 631b44c1439b..49c4b548b4d0 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -280,17 +280,12 @@ out: | |||
280 | return status; | 280 | return status; |
281 | } | 281 | } |
282 | 282 | ||
283 | /* FIXME: referring calls should be processed */ | ||
284 | unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, | 283 | unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, |
285 | struct cb_sequenceres *res) | 284 | struct cb_sequenceres *res) |
286 | { | 285 | { |
287 | struct nfs_client *clp; | 286 | struct nfs_client *clp; |
288 | int i, status; | 287 | int i, status; |
289 | 288 | ||
290 | for (i = 0; i < args->csa_nrclists; i++) | ||
291 | kfree(args->csa_rclists[i].rcl_refcalls); | ||
292 | kfree(args->csa_rclists); | ||
293 | |||
294 | status = htonl(NFS4ERR_BADSESSION); | 289 | status = htonl(NFS4ERR_BADSESSION); |
295 | clp = find_client_with_session(args->csa_addr, 4, &args->csa_sessionid); | 290 | clp = find_client_with_session(args->csa_addr, 4, &args->csa_sessionid); |
296 | if (clp == NULL) | 291 | if (clp == NULL) |
@@ -301,6 +296,16 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, | |||
301 | if (status) | 296 | if (status) |
302 | goto out_putclient; | 297 | goto out_putclient; |
303 | 298 | ||
299 | /* | ||
300 | * Check for pending referring calls. If a match is found, a | ||
301 | * related callback was received before the response to the original | ||
302 | * call. | ||
303 | */ | ||
304 | if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) { | ||
305 | status = htonl(NFS4ERR_DELAY); | ||
306 | goto out_putclient; | ||
307 | } | ||
308 | |||
304 | memcpy(&res->csr_sessionid, &args->csa_sessionid, | 309 | memcpy(&res->csr_sessionid, &args->csa_sessionid, |
305 | sizeof(res->csr_sessionid)); | 310 | sizeof(res->csr_sessionid)); |
306 | res->csr_sequenceid = args->csa_sequenceid; | 311 | res->csr_sequenceid = args->csa_sequenceid; |
@@ -311,6 +316,10 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, | |||
311 | out_putclient: | 316 | out_putclient: |
312 | nfs_put_client(clp); | 317 | nfs_put_client(clp); |
313 | out: | 318 | out: |
319 | for (i = 0; i < args->csa_nrclists; i++) | ||
320 | kfree(args->csa_rclists[i].rcl_refcalls); | ||
321 | kfree(args->csa_rclists); | ||
322 | |||
314 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); | 323 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); |
315 | res->csr_status = status; | 324 | res->csr_status = status; |
316 | return res->csr_status; | 325 | return res->csr_status; |