diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 18:22:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 18:22:57 -0500 |
commit | 47853e7fa588bef826c9799a87b33904b32bd905 (patch) | |
tree | bd7681d1aedf28125b86fb0218e64297f4d71ac9 /fs/lockd/svclock.c | |
parent | 221fc10ec89834329e5613e3cab4569ba22da410 (diff) | |
parent | 9e56904e41e242169007e69d9916059dab995d90 (diff) |
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
Diffstat (limited to 'fs/lockd/svclock.c')
-rw-r--r-- | fs/lockd/svclock.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 49f959796b66..9cfced65d4a2 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -41,7 +41,8 @@ | |||
41 | 41 | ||
42 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); | 42 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); |
43 | static int nlmsvc_remove_block(struct nlm_block *block); | 43 | static int nlmsvc_remove_block(struct nlm_block *block); |
44 | static void nlmsvc_grant_callback(struct rpc_task *task); | 44 | |
45 | static const struct rpc_call_ops nlmsvc_grant_ops; | ||
45 | 46 | ||
46 | /* | 47 | /* |
47 | * The list of blocked locks to retry | 48 | * The list of blocked locks to retry |
@@ -226,31 +227,27 @@ failed: | |||
226 | * It is the caller's responsibility to check whether the file | 227 | * It is the caller's responsibility to check whether the file |
227 | * can be closed hereafter. | 228 | * can be closed hereafter. |
228 | */ | 229 | */ |
229 | static void | 230 | static int |
230 | nlmsvc_delete_block(struct nlm_block *block, int unlock) | 231 | nlmsvc_delete_block(struct nlm_block *block, int unlock) |
231 | { | 232 | { |
232 | struct file_lock *fl = &block->b_call.a_args.lock.fl; | 233 | struct file_lock *fl = &block->b_call.a_args.lock.fl; |
233 | struct nlm_file *file = block->b_file; | 234 | struct nlm_file *file = block->b_file; |
234 | struct nlm_block **bp; | 235 | struct nlm_block **bp; |
236 | int status = 0; | ||
235 | 237 | ||
236 | dprintk("lockd: deleting block %p...\n", block); | 238 | dprintk("lockd: deleting block %p...\n", block); |
237 | 239 | ||
238 | /* Remove block from list */ | 240 | /* Remove block from list */ |
239 | nlmsvc_remove_block(block); | 241 | nlmsvc_remove_block(block); |
240 | if (fl->fl_next) | 242 | if (unlock) |
241 | posix_unblock_lock(file->f_file, fl); | 243 | status = posix_unblock_lock(file->f_file, fl); |
242 | if (unlock) { | ||
243 | fl->fl_type = F_UNLCK; | ||
244 | posix_lock_file(file->f_file, fl); | ||
245 | block->b_granted = 0; | ||
246 | } | ||
247 | 244 | ||
248 | /* If the block is in the middle of a GRANT callback, | 245 | /* If the block is in the middle of a GRANT callback, |
249 | * don't kill it yet. */ | 246 | * don't kill it yet. */ |
250 | if (block->b_incall) { | 247 | if (block->b_incall) { |
251 | nlmsvc_insert_block(block, NLM_NEVER); | 248 | nlmsvc_insert_block(block, NLM_NEVER); |
252 | block->b_done = 1; | 249 | block->b_done = 1; |
253 | return; | 250 | return status; |
254 | } | 251 | } |
255 | 252 | ||
256 | /* Remove block from file's list of blocks */ | 253 | /* Remove block from file's list of blocks */ |
@@ -265,6 +262,7 @@ nlmsvc_delete_block(struct nlm_block *block, int unlock) | |||
265 | nlm_release_host(block->b_host); | 262 | nlm_release_host(block->b_host); |
266 | nlmclnt_freegrantargs(&block->b_call); | 263 | nlmclnt_freegrantargs(&block->b_call); |
267 | kfree(block); | 264 | kfree(block); |
265 | return status; | ||
268 | } | 266 | } |
269 | 267 | ||
270 | /* | 268 | /* |
@@ -275,6 +273,7 @@ int | |||
275 | nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) | 273 | nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) |
276 | { | 274 | { |
277 | struct nlm_block *block, *next; | 275 | struct nlm_block *block, *next; |
276 | /* XXX: Will everything get cleaned up if we don't unlock here? */ | ||
278 | 277 | ||
279 | down(&file->f_sema); | 278 | down(&file->f_sema); |
280 | for (block = file->f_blocks; block; block = next) { | 279 | for (block = file->f_blocks; block; block = next) { |
@@ -444,6 +443,7 @@ u32 | |||
444 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | 443 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) |
445 | { | 444 | { |
446 | struct nlm_block *block; | 445 | struct nlm_block *block; |
446 | int status = 0; | ||
447 | 447 | ||
448 | dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", | 448 | dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", |
449 | file->f_file->f_dentry->d_inode->i_sb->s_id, | 449 | file->f_file->f_dentry->d_inode->i_sb->s_id, |
@@ -454,9 +454,9 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | |||
454 | 454 | ||
455 | down(&file->f_sema); | 455 | down(&file->f_sema); |
456 | if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL) | 456 | if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL) |
457 | nlmsvc_delete_block(block, 1); | 457 | status = nlmsvc_delete_block(block, 1); |
458 | up(&file->f_sema); | 458 | up(&file->f_sema); |
459 | return nlm_granted; | 459 | return status ? nlm_lck_denied : nlm_granted; |
460 | } | 460 | } |
461 | 461 | ||
462 | /* | 462 | /* |
@@ -562,7 +562,7 @@ callback: | |||
562 | /* Call the client */ | 562 | /* Call the client */ |
563 | nlm_get_host(block->b_call.a_host); | 563 | nlm_get_host(block->b_call.a_host); |
564 | if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG, | 564 | if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG, |
565 | nlmsvc_grant_callback) < 0) | 565 | &nlmsvc_grant_ops) < 0) |
566 | nlm_release_host(block->b_call.a_host); | 566 | nlm_release_host(block->b_call.a_host); |
567 | up(&file->f_sema); | 567 | up(&file->f_sema); |
568 | } | 568 | } |
@@ -575,10 +575,9 @@ callback: | |||
575 | * chain once more in order to have it removed by lockd itself (which can | 575 | * chain once more in order to have it removed by lockd itself (which can |
576 | * then sleep on the file semaphore without disrupting e.g. the nfs client). | 576 | * then sleep on the file semaphore without disrupting e.g. the nfs client). |
577 | */ | 577 | */ |
578 | static void | 578 | static void nlmsvc_grant_callback(struct rpc_task *task, void *data) |
579 | nlmsvc_grant_callback(struct rpc_task *task) | ||
580 | { | 579 | { |
581 | struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; | 580 | struct nlm_rqst *call = data; |
582 | struct nlm_block *block; | 581 | struct nlm_block *block; |
583 | unsigned long timeout; | 582 | unsigned long timeout; |
584 | struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); | 583 | struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); |
@@ -614,6 +613,10 @@ nlmsvc_grant_callback(struct rpc_task *task) | |||
614 | nlm_release_host(call->a_host); | 613 | nlm_release_host(call->a_host); |
615 | } | 614 | } |
616 | 615 | ||
616 | static const struct rpc_call_ops nlmsvc_grant_ops = { | ||
617 | .rpc_call_done = nlmsvc_grant_callback, | ||
618 | }; | ||
619 | |||
617 | /* | 620 | /* |
618 | * We received a GRANT_RES callback. Try to find the corresponding | 621 | * We received a GRANT_RES callback. Try to find the corresponding |
619 | * block. | 622 | * block. |
@@ -633,11 +636,12 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status | |||
633 | 636 | ||
634 | file->f_count++; | 637 | file->f_count++; |
635 | down(&file->f_sema); | 638 | down(&file->f_sema); |
636 | if ((block = nlmsvc_find_block(cookie,&rqstp->rq_addr)) != NULL) { | 639 | block = nlmsvc_find_block(cookie, &rqstp->rq_addr); |
640 | if (block) { | ||
637 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { | 641 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { |
638 | /* Try again in a couple of seconds */ | 642 | /* Try again in a couple of seconds */ |
639 | nlmsvc_insert_block(block, 10 * HZ); | 643 | nlmsvc_insert_block(block, 10 * HZ); |
640 | block = NULL; | 644 | up(&file->f_sema); |
641 | } else { | 645 | } else { |
642 | /* Lock is now held by client, or has been rejected. | 646 | /* Lock is now held by client, or has been rejected. |
643 | * In both cases, the block should be removed. */ | 647 | * In both cases, the block should be removed. */ |
@@ -648,8 +652,6 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status | |||
648 | nlmsvc_delete_block(block, 1); | 652 | nlmsvc_delete_block(block, 1); |
649 | } | 653 | } |
650 | } | 654 | } |
651 | if (!block) | ||
652 | up(&file->f_sema); | ||
653 | nlm_release_file(file); | 655 | nlm_release_file(file); |
654 | } | 656 | } |
655 | 657 | ||