aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svclock.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 18:22:57 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 18:22:57 -0500
commit47853e7fa588bef826c9799a87b33904b32bd905 (patch)
treebd7681d1aedf28125b86fb0218e64297f4d71ac9 /fs/lockd/svclock.c
parent221fc10ec89834329e5613e3cab4569ba22da410 (diff)
parent9e56904e41e242169007e69d9916059dab995d90 (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.c42
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
42static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); 42static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
43static int nlmsvc_remove_block(struct nlm_block *block); 43static int nlmsvc_remove_block(struct nlm_block *block);
44static void nlmsvc_grant_callback(struct rpc_task *task); 44
45static 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 */
229static void 230static int
230nlmsvc_delete_block(struct nlm_block *block, int unlock) 231nlmsvc_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
275nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) 273nlmsvc_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
444nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) 443nlmsvc_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 */
578static void 578static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
579nlmsvc_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
616static 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