aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/clntproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/clntproc.c')
-rw-r--r--fs/lockd/clntproc.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 145524039577..970b6a6aa337 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -22,12 +22,14 @@
22#define NLMDBG_FACILITY NLMDBG_CLIENT 22#define NLMDBG_FACILITY NLMDBG_CLIENT
23#define NLMCLNT_GRACE_WAIT (5*HZ) 23#define NLMCLNT_GRACE_WAIT (5*HZ)
24#define NLMCLNT_POLL_TIMEOUT (30*HZ) 24#define NLMCLNT_POLL_TIMEOUT (30*HZ)
25#define NLMCLNT_MAX_RETRIES 3
25 26
26static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); 27static int nlmclnt_test(struct nlm_rqst *, struct file_lock *);
27static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); 28static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
28static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); 29static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
29static int nlm_stat_to_errno(u32 stat); 30static int nlm_stat_to_errno(u32 stat);
30static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); 31static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
32static int nlmclnt_cancel(struct nlm_host *, int , struct file_lock *);
31 33
32static const struct rpc_call_ops nlmclnt_unlock_ops; 34static const struct rpc_call_ops nlmclnt_unlock_ops;
33static const struct rpc_call_ops nlmclnt_cancel_ops; 35static const struct rpc_call_ops nlmclnt_cancel_ops;
@@ -598,7 +600,7 @@ out_unblock:
598 nlmclnt_finish_block(req); 600 nlmclnt_finish_block(req);
599 /* Cancel the blocked request if it is still pending */ 601 /* Cancel the blocked request if it is still pending */
600 if (resp->status == NLM_LCK_BLOCKED) 602 if (resp->status == NLM_LCK_BLOCKED)
601 nlmclnt_cancel(host, fl); 603 nlmclnt_cancel(host, req->a_args.block, fl);
602out: 604out:
603 nlmclnt_release_lockargs(req); 605 nlmclnt_release_lockargs(req);
604 return status; 606 return status;
@@ -660,12 +662,18 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
660 * reclaimed while we're stuck in the unlock call. */ 662 * reclaimed while we're stuck in the unlock call. */
661 fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED; 663 fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED;
662 664
665 /*
666 * Note: the server is supposed to either grant us the unlock
667 * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either
668 * case, we want to unlock.
669 */
670 do_vfs_lock(fl);
671
663 if (req->a_flags & RPC_TASK_ASYNC) { 672 if (req->a_flags & RPC_TASK_ASYNC) {
664 status = nlmclnt_async_call(req, NLMPROC_UNLOCK, 673 status = nlmclnt_async_call(req, NLMPROC_UNLOCK,
665 &nlmclnt_unlock_ops); 674 &nlmclnt_unlock_ops);
666 /* Hrmf... Do the unlock early since locks_remove_posix() 675 /* Hrmf... Do the unlock early since locks_remove_posix()
667 * really expects us to free the lock synchronously */ 676 * really expects us to free the lock synchronously */
668 do_vfs_lock(fl);
669 if (status < 0) { 677 if (status < 0) {
670 nlmclnt_release_lockargs(req); 678 nlmclnt_release_lockargs(req);
671 kfree(req); 679 kfree(req);
@@ -678,7 +686,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
678 if (status < 0) 686 if (status < 0)
679 return status; 687 return status;
680 688
681 do_vfs_lock(fl);
682 if (resp->status == NLM_LCK_GRANTED) 689 if (resp->status == NLM_LCK_GRANTED)
683 return 0; 690 return 0;
684 691
@@ -728,8 +735,7 @@ static const struct rpc_call_ops nlmclnt_unlock_ops = {
728 * We always use an async RPC call for this in order not to hang a 735 * We always use an async RPC call for this in order not to hang a
729 * process that has been Ctrl-C'ed. 736 * process that has been Ctrl-C'ed.
730 */ 737 */
731int 738static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl)
732nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
733{ 739{
734 struct nlm_rqst *req; 740 struct nlm_rqst *req;
735 unsigned long flags; 741 unsigned long flags;
@@ -750,6 +756,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
750 req->a_flags = RPC_TASK_ASYNC; 756 req->a_flags = RPC_TASK_ASYNC;
751 757
752 nlmclnt_setlockargs(req, fl); 758 nlmclnt_setlockargs(req, fl);
759 req->a_args.block = block;
753 760
754 status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops); 761 status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops);
755 if (status < 0) { 762 if (status < 0) {
@@ -801,6 +808,9 @@ die:
801 return; 808 return;
802 809
803retry_cancel: 810retry_cancel:
811 /* Don't ever retry more than 3 times */
812 if (req->a_retries++ >= NLMCLNT_MAX_RETRIES)
813 goto die;
804 nlm_rebind_host(req->a_host); 814 nlm_rebind_host(req->a_host);
805 rpc_restart_call(task); 815 rpc_restart_call(task);
806 rpc_delay(task, 30 * HZ); 816 rpc_delay(task, 30 * HZ);