lockd: handle test_lock deferrals
Rewrite nlmsvc_testlock() to use the new asynchronous interface: instead of immediately doing a posix_test_lock(), we first look for a matching block. If the subsequent test_lock returns anything other than -EINPROGRESS, we then remove the block we've found and return the results. If it returns -EINPROGRESS, then we defer the lock request. In the case where the block we find in the first step has B_QUEUED set, we bypass the vfs_test_lock entirely, instead using the block to decide how to respond: with nlm_lck_denied if B_TIMED_OUT is set. with nlm_granted if B_GOT_CALLBACK is set. by dropping if neither B_TIMED_OUT nor B_GOT_CALLBACK is set Signed-off-by: Marc Eshel <eshel@almaden.ibm.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
committed by
J. Bruce Fields
parent
85f3f1b3f7
commit
5ea0d75037
@@ -33,6 +33,7 @@ cast_to_nlm(__be32 status, u32 vers)
|
||||
case nlm_lck_denied_nolocks:
|
||||
case nlm_lck_blocked:
|
||||
case nlm_lck_denied_grace_period:
|
||||
case nlm_drop_reply:
|
||||
break;
|
||||
case nlm4_deadlock:
|
||||
status = nlm_lck_denied;
|
||||
@@ -128,6 +129,8 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
|
||||
|
||||
/* Now check for conflicting locks */
|
||||
resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
|
||||
if (resp->status == nlm_drop_reply)
|
||||
return rpc_drop_reply;
|
||||
|
||||
dprintk("lockd: TEST status %d vers %d\n",
|
||||
ntohl(resp->status), rqstp->rq_vers);
|
||||
|
Reference in New Issue
Block a user