diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:44 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:44 -0500 |
| commit | 3a649b884637c4fdff50a6beebc3dc0e6082e048 (patch) | |
| tree | 042455741f079fdbd4d33cd7da61c1c9e68db477 | |
| parent | d72b7a6b26b9009b7a05117fe2e04b3a73ae4a5c (diff) | |
NLM: Simplify client locks
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | fs/lockd/clntlock.c | 43 | ||||
| -rw-r--r-- | fs/lockd/clntproc.c | 39 | ||||
| -rw-r--r-- | include/linux/lockd/lockd.h | 7 |
3 files changed, 35 insertions, 54 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 7cf41c1e1a88..bce744468708 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
| @@ -44,32 +44,25 @@ static LIST_HEAD(nlm_blocked); | |||
| 44 | /* | 44 | /* |
| 45 | * Queue up a lock for blocking so that the GRANTED request can see it | 45 | * Queue up a lock for blocking so that the GRANTED request can see it |
| 46 | */ | 46 | */ |
| 47 | int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl) | 47 | struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl) |
| 48 | { | 48 | { |
| 49 | struct nlm_wait *block; | 49 | struct nlm_wait *block; |
| 50 | 50 | ||
| 51 | BUG_ON(req->a_block != NULL); | ||
| 52 | block = kmalloc(sizeof(*block), GFP_KERNEL); | 51 | block = kmalloc(sizeof(*block), GFP_KERNEL); |
| 53 | if (block == NULL) | 52 | if (block != NULL) { |
| 54 | return -ENOMEM; | 53 | block->b_host = host; |
| 55 | block->b_host = host; | 54 | block->b_lock = fl; |
| 56 | block->b_lock = fl; | 55 | init_waitqueue_head(&block->b_wait); |
| 57 | init_waitqueue_head(&block->b_wait); | 56 | block->b_status = NLM_LCK_BLOCKED; |
| 58 | block->b_status = NLM_LCK_BLOCKED; | 57 | list_add(&block->b_list, &nlm_blocked); |
| 59 | 58 | } | |
| 60 | list_add(&block->b_list, &nlm_blocked); | 59 | return block; |
| 61 | req->a_block = block; | ||
| 62 | |||
| 63 | return 0; | ||
| 64 | } | 60 | } |
| 65 | 61 | ||
| 66 | void nlmclnt_finish_block(struct nlm_rqst *req) | 62 | void nlmclnt_finish_block(struct nlm_wait *block) |
| 67 | { | 63 | { |
| 68 | struct nlm_wait *block = req->a_block; | ||
| 69 | |||
| 70 | if (block == NULL) | 64 | if (block == NULL) |
| 71 | return; | 65 | return; |
| 72 | req->a_block = NULL; | ||
| 73 | list_del(&block->b_list); | 66 | list_del(&block->b_list); |
| 74 | kfree(block); | 67 | kfree(block); |
| 75 | } | 68 | } |
| @@ -77,15 +70,14 @@ void nlmclnt_finish_block(struct nlm_rqst *req) | |||
| 77 | /* | 70 | /* |
| 78 | * Block on a lock | 71 | * Block on a lock |
| 79 | */ | 72 | */ |
| 80 | long nlmclnt_block(struct nlm_rqst *req, long timeout) | 73 | int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) |
| 81 | { | 74 | { |
| 82 | struct nlm_wait *block = req->a_block; | ||
| 83 | long ret; | 75 | long ret; |
| 84 | 76 | ||
| 85 | /* A borken server might ask us to block even if we didn't | 77 | /* A borken server might ask us to block even if we didn't |
| 86 | * request it. Just say no! | 78 | * request it. Just say no! |
| 87 | */ | 79 | */ |
| 88 | if (!req->a_args.block) | 80 | if (block == NULL) |
| 89 | return -EAGAIN; | 81 | return -EAGAIN; |
| 90 | 82 | ||
| 91 | /* Go to sleep waiting for GRANT callback. Some servers seem | 83 | /* Go to sleep waiting for GRANT callback. Some servers seem |
| @@ -99,13 +91,10 @@ long nlmclnt_block(struct nlm_rqst *req, long timeout) | |||
| 99 | ret = wait_event_interruptible_timeout(block->b_wait, | 91 | ret = wait_event_interruptible_timeout(block->b_wait, |
| 100 | block->b_status != NLM_LCK_BLOCKED, | 92 | block->b_status != NLM_LCK_BLOCKED, |
| 101 | timeout); | 93 | timeout); |
| 102 | 94 | if (ret < 0) | |
| 103 | if (block->b_status != NLM_LCK_BLOCKED) { | 95 | return -ERESTARTSYS; |
| 104 | req->a_res.status = block->b_status; | 96 | req->a_res.status = block->b_status; |
| 105 | block->b_status = NLM_LCK_BLOCKED; | 97 | return 0; |
| 106 | } | ||
| 107 | |||
| 108 | return ret; | ||
| 109 | } | 98 | } |
| 110 | 99 | ||
| 111 | /* | 100 | /* |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index c25044f3b660..8af017105854 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
| @@ -136,15 +136,14 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) | |||
| 136 | (unsigned int)fl->fl_u.nfs_fl.owner->pid, | 136 | (unsigned int)fl->fl_u.nfs_fl.owner->pid, |
| 137 | system_utsname.nodename); | 137 | system_utsname.nodename); |
| 138 | lock->svid = fl->fl_u.nfs_fl.owner->pid; | 138 | lock->svid = fl->fl_u.nfs_fl.owner->pid; |
| 139 | locks_copy_lock(&lock->fl, fl); | 139 | lock->fl.fl_start = fl->fl_start; |
| 140 | lock->fl.fl_end = fl->fl_end; | ||
| 141 | lock->fl.fl_type = fl->fl_type; | ||
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | static void nlmclnt_release_lockargs(struct nlm_rqst *req) | 144 | static void nlmclnt_release_lockargs(struct nlm_rqst *req) |
| 143 | { | 145 | { |
| 144 | struct file_lock *fl = &req->a_args.lock.fl; | 146 | BUG_ON(req->a_args.lock.fl.fl_ops != NULL); |
| 145 | |||
| 146 | if (fl->fl_ops && fl->fl_ops->fl_release_private) | ||
| 147 | fl->fl_ops->fl_release_private(fl); | ||
| 148 | } | 147 | } |
| 149 | 148 | ||
| 150 | /* | 149 | /* |
| @@ -455,7 +454,6 @@ static void nlmclnt_locks_release_private(struct file_lock *fl) | |||
| 455 | { | 454 | { |
| 456 | list_del(&fl->fl_u.nfs_fl.list); | 455 | list_del(&fl->fl_u.nfs_fl.list); |
| 457 | nlm_put_lockowner(fl->fl_u.nfs_fl.owner); | 456 | nlm_put_lockowner(fl->fl_u.nfs_fl.owner); |
| 458 | fl->fl_ops = NULL; | ||
| 459 | } | 457 | } |
| 460 | 458 | ||
| 461 | static struct file_lock_operations nlmclnt_lock_ops = { | 459 | static struct file_lock_operations nlmclnt_lock_ops = { |
| @@ -515,41 +513,36 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) | |||
| 515 | { | 513 | { |
| 516 | struct nlm_host *host = req->a_host; | 514 | struct nlm_host *host = req->a_host; |
| 517 | struct nlm_res *resp = &req->a_res; | 515 | struct nlm_res *resp = &req->a_res; |
| 518 | long timeout; | 516 | struct nlm_wait *block = NULL; |
| 519 | int status; | 517 | int status = -ENOLCK; |
| 520 | 518 | ||
| 521 | if (!host->h_monitored && nsm_monitor(host) < 0) { | 519 | if (!host->h_monitored && nsm_monitor(host) < 0) { |
| 522 | printk(KERN_NOTICE "lockd: failed to monitor %s\n", | 520 | printk(KERN_NOTICE "lockd: failed to monitor %s\n", |
| 523 | host->h_name); | 521 | host->h_name); |
| 524 | status = -ENOLCK; | ||
| 525 | goto out; | 522 | goto out; |
| 526 | } | 523 | } |
| 527 | 524 | ||
| 528 | if (req->a_args.block) { | 525 | block = nlmclnt_prepare_block(host, fl); |
| 529 | status = nlmclnt_prepare_block(req, host, fl); | ||
| 530 | if (status < 0) | ||
| 531 | goto out; | ||
| 532 | } | ||
| 533 | for(;;) { | 526 | for(;;) { |
| 534 | status = nlmclnt_call(req, NLMPROC_LOCK); | 527 | status = nlmclnt_call(req, NLMPROC_LOCK); |
| 535 | if (status < 0) | 528 | if (status < 0) |
| 536 | goto out_unblock; | 529 | goto out_unblock; |
| 537 | if (resp->status != NLM_LCK_BLOCKED) | 530 | if (!req->a_args.block) |
| 538 | break; | 531 | break; |
| 539 | /* Wait on an NLM blocking lock */ | ||
| 540 | timeout = nlmclnt_block(req, NLMCLNT_POLL_TIMEOUT); | ||
| 541 | /* Did a reclaimer thread notify us of a server reboot? */ | 532 | /* Did a reclaimer thread notify us of a server reboot? */ |
| 542 | if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) | 533 | if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) |
| 543 | continue; | 534 | continue; |
| 544 | if (resp->status != NLM_LCK_BLOCKED) | 535 | if (resp->status != NLM_LCK_BLOCKED) |
| 545 | break; | 536 | break; |
| 546 | if (timeout >= 0) | 537 | /* Wait on an NLM blocking lock */ |
| 547 | continue; | 538 | status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); |
| 548 | /* We were interrupted. Send a CANCEL request to the server | 539 | /* if we were interrupted. Send a CANCEL request to the server |
| 549 | * and exit | 540 | * and exit |
| 550 | */ | 541 | */ |
| 551 | status = (int)timeout; | 542 | if (status < 0) |
| 552 | goto out_unblock; | 543 | goto out_unblock; |
| 544 | if (resp->status != NLM_LCK_BLOCKED) | ||
| 545 | break; | ||
| 553 | } | 546 | } |
| 554 | 547 | ||
| 555 | if (resp->status == NLM_LCK_GRANTED) { | 548 | if (resp->status == NLM_LCK_GRANTED) { |
| @@ -560,7 +553,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) | |||
| 560 | } | 553 | } |
| 561 | status = nlm_stat_to_errno(resp->status); | 554 | status = nlm_stat_to_errno(resp->status); |
| 562 | out_unblock: | 555 | out_unblock: |
| 563 | nlmclnt_finish_block(req); | 556 | nlmclnt_finish_block(block); |
| 564 | /* Cancel the blocked request if it is still pending */ | 557 | /* Cancel the blocked request if it is still pending */ |
| 565 | if (resp->status == NLM_LCK_BLOCKED) | 558 | if (resp->status == NLM_LCK_BLOCKED) |
| 566 | nlmclnt_cancel(host, req->a_args.block, fl); | 559 | nlmclnt_cancel(host, req->a_args.block, fl); |
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index b0f63b6ab0d4..cb9933d04091 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
| @@ -86,7 +86,6 @@ struct nlm_rqst { | |||
| 86 | struct nlm_host * a_host; /* host handle */ | 86 | struct nlm_host * a_host; /* host handle */ |
| 87 | struct nlm_args a_args; /* arguments */ | 87 | struct nlm_args a_args; /* arguments */ |
| 88 | struct nlm_res a_res; /* result */ | 88 | struct nlm_res a_res; /* result */ |
| 89 | struct nlm_wait * a_block; | ||
| 90 | unsigned int a_retries; /* Retry count */ | 89 | unsigned int a_retries; /* Retry count */ |
| 91 | char a_owner[NLMCLNT_OHSIZE]; | 90 | char a_owner[NLMCLNT_OHSIZE]; |
| 92 | }; | 91 | }; |
| @@ -149,9 +148,9 @@ extern unsigned long nlmsvc_timeout; | |||
| 149 | * Lockd client functions | 148 | * Lockd client functions |
| 150 | */ | 149 | */ |
| 151 | struct nlm_rqst * nlmclnt_alloc_call(void); | 150 | struct nlm_rqst * nlmclnt_alloc_call(void); |
| 152 | int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl); | 151 | struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl); |
| 153 | void nlmclnt_finish_block(struct nlm_rqst *req); | 152 | void nlmclnt_finish_block(struct nlm_wait *block); |
| 154 | long nlmclnt_block(struct nlm_rqst *req, long timeout); | 153 | int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout); |
| 155 | u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); | 154 | u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); |
| 156 | void nlmclnt_recovery(struct nlm_host *, u32); | 155 | void nlmclnt_recovery(struct nlm_host *, u32); |
| 157 | int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); | 156 | int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); |
