1 /* 2 * linux/fs/lockd/svclock.c 3 * 4 * Handling of server-side locks, mostly of the blocked variety. 5 * This is the ugliest part of lockd because we tread on very thin ice. 6 * GRANT and CANCEL calls may get stuck, meet in mid-flight, etc. 7 * IMNSHO introducing the grant callback into the NLM protocol was one 8 * of the worst ideas Sun ever had. Except maybe for the idea of doing 9 * NFS file locking at all. 10 * 11 * I'm trying hard to avoid race conditions by protecting most accesses 12 * to a file's list of blocked locks through a semaphore. The global 13 * list of blocked locks is not protected in this fashion however. 14 * Therefore, some functions (such as the RPC callback for the async grant 15 * call) move blocked locks towards the head of the list *while some other 16 * process might be traversing it*. This should not be a problem in 17 * practice, because this will only cause functions traversing the list 18 * to visit some blocks twice. 19 * 20 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 21 */ 22 23 #include <linux/types.h> 24 #include <linux/errno.h> 25 #include <linux/kernel.h> 26 #include <linux/sched.h> 27 #include <linux/smp_lock.h> 28 #include <linux/sunrpc/clnt.h> 29 #include <linux/sunrpc/svc.h> 30 #include <linux/lockd/nlm.h> 31 #include <linux/lockd/lockd.h> 32 33 #define NLMDBG_FACILITY NLMDBG_SVCLOCK 34 35 #ifdef CONFIG_LOCKD_V4 36 #define nlm_deadlock nlm4_deadlock 37 #else 38 #define nlm_deadlock nlm_lck_denied 39 #endif 40 41 static void nlmsvc_release_block(struct nlm_block *block); 42 static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); 43 static void nlmsvc_remove_block(struct nlm_block *block); 44 45 static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); 46 static void nlmsvc_freegrantargs(struct nlm_rqst *call); 47 static const struct rpc_call_ops nlmsvc_grant_ops; 48 49 /* 50 * The list of blocked locks to retry 51 */ 52 static LIST_HEAD(nlm_blocked); 53 54 /* 55 * Insert a blocked lock into the global list 56 */ 57 static void 58 nlmsvc_insert_block(struct nlm_block *block, unsigned long when) 59 { 60 struct nlm_block *b; 61 struct list_head *pos; 62 63 dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); 64 if (list_empty(&block->b_list)) { 65 kref_get(&block->b_count); 66 } else { 67 list_del_init(&block->b_list); 68 } 69 70 pos = &nlm_blocked; 71 if (when != NLM_NEVER) { 72 if ((when += jiffies) == NLM_NEVER) 73 when ++; 74 list_for_each(pos, &nlm_blocked) { 75 b = list_entry(pos, struct nlm_block, b_list); 76 if (time_after(b->b_when,when) || b->b_when == NLM_NEVER) 77 break; 78 } 79 /* On normal exit from the loop, pos == &nlm_blocked, 80 * so we will be adding to the end of the list - good 81 */ 82 } 83 84 list_add_tail(&block->b_list, pos); 85 block->b_when = when; 86 } 87 88 /* 89 * Remove a block from the global list 90 */ 91 static inline void 92 nlmsvc_remove_block(struct nlm_block *block) 93 { 94 if (!list_empty(&block->b_list)) { 95 list_del_init(&block->b_list); 96 nlmsvc_release_block(block); 97 } 98 } 99 100 /* 101 * Find a block for a given lock 102 */ 103 static struct nlm_block * 104 nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock) 105 { 106 struct nlm_block *block; 107 struct file_lock *fl; 108 109 dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n", 110 file, lock->fl.fl_pid, 111 (long long)lock->fl.fl_start, 112 (long long)lock->fl.fl_end, lock->fl.fl_type); 113 list_for_each_entry(block, &nlm_blocked, b_list) { 114 fl = &block->b_call->a_args.lock.fl; 115 dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n", 116 block->b_file, fl->fl_pid, 117 (long long)fl->fl_start, 118 (long long)fl->fl_end, fl->fl_type, 119 nlmdbg_cookie2a(&block->b_call->a_args.cookie)); 120 if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { 121 kref_get(&block->b_count); 122 return block; 123 } 124 } 125 126 return NULL; 127 } 128 129 static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b) 130 { 131 if(a->len != b->len) 132 return 0; 133 if(memcmp(a->data,b->data,a->len)) 134 return 0; 135 return 1; 136 } 137 138 /* 139 * Find a block with a given NLM cookie. 140 */ 141 static inline struct nlm_block * 142 nlmsvc_find_block(struct nlm_cookie *cookie) 143 { 144 struct nlm_block *block; 145 146 list_for_each_entry(block, &nlm_blocked, b_list) { 147 if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie)) 148 goto found; 149 } 150 151 return NULL; 152 153 found: 154 dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block); 155 kref_get(&block->b_count); 156 return block; 157 } 158 159 /* 160 * Create a block and initialize it. 161 * 162 * Note: we explicitly set the cookie of the grant reply to that of 163 * the blocked lock request. The spec explicitly mentions that the client 164 * should _not_ rely on the callback containing the same cookie as the 165 * request, but (as I found out later) that's because some implementations 166 * do just this. Never mind the standards comittees, they support our 167 * logging industries. 168 * 169 * 10 years later: I hope we can safely ignore these old and broken 170 * clients by now. Let's fix this so we can uniquely identify an incoming 171 * GRANTED_RES message by cookie, without having to rely on the client's IP 172 * address. --okir 173 */ 174 static inline struct nlm_block * 175 nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, 176 struct nlm_lock *lock, struct nlm_cookie *cookie) 177 { 178 struct nlm_block *block; 179 struct nlm_host *host; 180 struct nlm_rqst *call = NULL; 181 182 /* Create host handle for callback */ 183 host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len); 184 if (host == NULL) 185 return NULL; 186 187 call = nlm_alloc_call(host); 188 if (call == NULL) 189 return NULL; 190 191 /* Allocate memory for block, and initialize arguments */ 192 block = kzalloc(sizeof(*block), GFP_KERNEL); 193 if (block == NULL) 194 goto failed; 195 kref_init(&block->b_count); 196 INIT_LIST_HEAD(&block->b_list); 197 INIT_LIST_HEAD(&block->b_flist); 198 199 if (!nlmsvc_setgrantargs(call, lock)) 200 goto failed_free; 201 202 /* Set notifier function for VFS, and init args */ 203 call->a_args.lock.fl.fl_flags |= FL_SLEEP; 204 call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations; 205 nlmclnt_next_cookie(&call->a_args.cookie); 206 207 dprintk("lockd: created block %p...\n", block); 208 209 /* Create and initialize the block */ 210 block->b_daemon = rqstp->rq_server; 211 block->b_host = host; 212 block->b_file = file; 213 block->b_fl = NULL; 214 file->f_count++; 215 216 /* Add to file's list of blocks */ 217 list_add(&block->b_flist, &file->f_blocks); 218 219 /* Set up RPC arguments for callback */ 220 block->b_call = call; 221 call->a_flags = RPC_TASK_ASYNC; 222 call->a_block = block; 223 224 return block; 225 226 failed_free: 227 kfree(block); 228 failed: 229 nlm_release_call(call); 230 return NULL; 231 } 232 233 /* 234 * Delete a block. If the lock was cancelled or the grant callback 235 * failed, unlock is set to 1. 236 * It is the caller's responsibility to check whether the file 237 * can be closed hereafter. 238 */ 239 static int nlmsvc_unlink_block(struct nlm_block *block) 240 { 241 int status; 242 dprintk("lockd: unlinking block %p...\n", block); 243 244 /* Remove block from list */ 245 status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); 246 nlmsvc_remove_block(block); 247 return status; 248 } 249 250 static void nlmsvc_free_block(struct kref *kref) 251 { 252 struct nlm_block *block = container_of(kref, struct nlm_block, b_count); 253 struct nlm_file *file = block->b_file; 254 255 dprintk("lockd: freeing block %p...\n", block); 256 257 /* Remove block from file's list of blocks */ 258 mutex_lock(&file->f_mutex); 259 list_del_init(&block->b_flist); 260 mutex_unlock(&file->f_mutex); 261 262 nlmsvc_freegrantargs(block->b_call); 263 nlm_release_call(block->b_call); 264 nlm_release_file(block->b_file); 265 kfree(block->b_fl); 266 kfree(block); 267 } 268 269 static void nlmsvc_release_block(struct nlm_block *block) 270 { 271 if (block != NULL) 272 kref_put(&block->b_count, nlmsvc_free_block); 273 } 274 275 /* 276 * Loop over all blocks and delete blocks held by 277 * a matching host. 278 */ 279 void nlmsvc_traverse_blocks(struct nlm_host *host, 280 struct nlm_file *file, 281 nlm_host_match_fn_t match) 282 { 283 struct nlm_block *block, *next; 284 285 restart: 286 mutex_lock(&file->f_mutex); 287 list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) { 288 if (!match(block->b_host, host)) 289 continue; 290 /* Do not destroy blocks that are not on 291 * the global retry list - why? */ 292 if (list_empty(&block->b_list)) 293 continue; 294 kref_get(&block->b_count); 295 mutex_unlock(&file->f_mutex); 296 nlmsvc_unlink_block(block); 297 nlmsvc_release_block(block); 298 goto restart; 299 } 300 mutex_unlock(&file->f_mutex); 301 } 302 303 /* 304 * Initialize arguments for GRANTED call. The nlm_rqst structure 305 * has been cleared already. 306 */ 307 static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) 308 { 309 locks_copy_lock(&call->a_args.lock.fl, &lock->fl); 310 memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); 311 call->a_args.lock.caller = utsname()->nodename; 312 call->a_args.lock.oh.len = lock->oh.len; 313 314 /* set default data area */ 315 call->a_args.lock.oh.data = call->a_owner; 316 call->a_args.lock.svid = lock->fl.fl_pid; 317 318 if (lock->oh.len > NLMCLNT_OHSIZE) { 319 void *data = kmalloc(lock->oh.len, GFP_KERNEL); 320 if (!data) 321 return 0; 322 call->a_args.lock.oh.data = (u8 *) data; 323 } 324 325 memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len); 326 return 1; 327 } 328 329 static void nlmsvc_freegrantargs(struct nlm_rqst *call) 330 { 331 if (call->a_args.lock.oh.data != call->a_owner) 332 kfree(call->a_args.lock.oh.data); 333 } 334 335 /* 336 * Deferred lock request handling for non-blocking lock 337 */ 338 static u32 339 nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block) 340 { 341 u32 status = nlm_lck_denied_nolocks; 342 343 block->b_flags |= B_QUEUED; 344 345 nlmsvc_insert_block(block, NLM_TIMEOUT); 346 347 block->b_cache_req = &rqstp->rq_chandle; 348 if (rqstp->rq_chandle.defer) { 349 block->b_deferred_req = 350 rqstp->rq_chandle.defer(block->b_cache_req); 351 if (block->b_deferred_req != NULL) 352 status = nlm_drop_reply; 353 } 354 dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n", 355 block, block->b_flags, status); 356 357 return status; 358 } 359 360 /* 361 * Attempt to establish a lock, and if it can't be granted, block it 362 * if required. 363 */ 364 __be32 365 nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, 366 struct nlm_lock *lock, int wait, struct nlm_cookie *cookie) 367 { 368 struct nlm_block *block = NULL; 369 int error; 370 __be32 ret; 371 372 dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n", 373 file->f_file->f_path.dentry->d_inode->i_sb->s_id, 374 file->f_file->f_path.dentry->d_inode->i_ino, 375 lock->fl.fl_type, lock->fl.fl_pid, 376 (long long)lock->fl.fl_start, 377 (long long)lock->fl.fl_end, 378 wait); 379 380 381 /* Lock file against concurrent access */ 382 mutex_lock(&file->f_mutex); 383 /* Get existing block (in case client is busy-waiting) 384 * or create new block 385 */ 386 block = nlmsvc_lookup_block(file, lock); 387 if (block == NULL) { 388 block = nlmsvc_create_block(rqstp, file, lock, cookie); 389 ret = nlm_lck_denied_nolocks; 390 if (block == NULL) 391 goto out; 392 lock = &block->b_call->a_args.lock; 393 } else 394 lock->fl.fl_flags &= ~FL_SLEEP; 395 396 if (block->b_flags & B_QUEUED) { 397 dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n", 398 block, block->b_flags); 399 if (block->b_granted) { 400 nlmsvc_unlink_block(block); 401 ret = nlm_granted; 402 goto out; 403 } 404 if (block->b_flags & B_TIMED_OUT) { 405 nlmsvc_unlink_block(block); 406 ret = nlm_lck_denied; 407 goto out; 408 } 409 ret = nlm_drop_reply; 410 goto out; 411 } 412 413 if (!wait) 414 lock->fl.fl_flags &= ~FL_SLEEP; 415 error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); 416 lock->fl.fl_flags &= ~FL_SLEEP; 417 418 dprintk("lockd: vfs_lock_file returned %d\n", error); 419 switch(error) { 420 case 0: 421 ret = nlm_granted; 422 goto out; 423 case -EAGAIN: 424 ret = nlm_lck_denied; 425 break; 426 case -EINPROGRESS: 427 if (wait) 428 break; 429 /* Filesystem lock operation is in progress 430 Add it to the queue waiting for callback */ 431 ret = nlmsvc_defer_lock_rqst(rqstp, block); 432 goto out; 433 case -EDEADLK: 434 ret = nlm_deadlock; 435 goto out; 436 default: /* includes ENOLCK */ 437 ret = nlm_lck_denied_nolocks; 438 goto out; 439 } 440 441 ret = nlm_lck_denied; 442 if (!wait) 443 goto out; 444 445 ret = nlm_lck_blocked; 446 447 /* Append to list of blocked */ 448 nlmsvc_insert_block(block, NLM_NEVER); 449 out: 450 mutex_unlock(&file->f_mutex); 451 nlmsvc_release_block(block); 452 dprintk("lockd: nlmsvc_lock returned %u\n", ret); 453 return ret; 454 } 455 456 /* 457 * Test for presence of a conflicting lock. 458 */ 459 __be32 460 nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, 461 struct nlm_lock *lock, struct nlm_lock *conflock, 462 struct nlm_cookie *cookie) 463 { 464 struct nlm_block *block = NULL; 465 int error; 466 __be32 ret; 467 468 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", 469 file->f_file->f_path.dentry->d_inode->i_sb->s_id, 470 file->f_file->f_path.dentry->d_inode->i_ino, 471 lock->fl.fl_type, 472 (long long)lock->fl.fl_start, 473 (long long)lock->fl.fl_end); 474 475 /* Get existing block (in case client is busy-waiting) */ 476 block = nlmsvc_lookup_block(file, lock); 477 478 if (block == NULL) { 479 struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL); 480 481 if (conf == NULL) 482 return nlm_granted; 483 block = nlmsvc_create_block(rqstp, file, lock, cookie); 484 if (block == NULL) { 485 kfree(conf); 486 return nlm_granted; 487 } 488 block->b_fl = conf; 489 } 490 if (block->b_flags & B_QUEUED) { 491 dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n", 492 block, block->b_flags, block->b_fl); 493 if (block->b_flags & B_TIMED_OUT) { 494 nlmsvc_unlink_block(block); 495 return nlm_lck_denied; 496 } 497 if (block->b_flags & B_GOT_CALLBACK) { 498 if (block->b_fl != NULL 499 && block->b_fl->fl_type != F_UNLCK) { 500 lock->fl = *block->b_fl; 501 goto conf_lock; 502 } 503 else { 504 nlmsvc_unlink_block(block); 505 return nlm_granted; 506 } 507 } 508 return nlm_drop_reply; 509 } 510 511 error = vfs_test_lock(file->f_file, &lock->fl); 512 if (error == -EINPROGRESS) 513 return nlmsvc_defer_lock_rqst(rqstp, block); 514 if (error) { 515 ret = nlm_lck_denied_nolocks; 516 goto out; 517 } 518 if (lock->fl.fl_type == F_UNLCK) { 519 ret = nlm_granted; 520 goto out; 521 } 522 523 conf_lock: 524 dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n", 525 lock->fl.fl_type, (long long)lock->fl.fl_start, 526 (long long)lock->fl.fl_end); 527 conflock->caller = "somehost"; /* FIXME */ 528 conflock->len = strlen(conflock->caller); 529 conflock->oh.len = 0; /* don't return OH info */ 530 conflock->svid = lock->fl.fl_pid; 531 conflock->fl.fl_type = lock->fl.fl_type; 532 conflock->fl.fl_start = lock->fl.fl_start; 533 conflock->fl.fl_end = lock->fl.fl_end; 534 ret = nlm_lck_denied; 535 out: 536 if (block) 537 nlmsvc_release_block(block); 538 return ret; 539 } 540 541 /* 542 * Remove a lock. 543 * This implies a CANCEL call: We send a GRANT_MSG, the client replies 544 * with a GRANT_RES call which gets lost, and calls UNLOCK immediately 545 * afterwards. In this case the block will still be there, and hence 546 * must be removed. 547 */ 548 __be32 549 nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) 550 { 551 int error; 552 553 dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n", 554 file->f_file->f_path.dentry->d_inode->i_sb->s_id, 555 file->f_file->f_path.dentry->d_inode->i_ino, 556 lock->fl.fl_pid, 557 (long long)lock->fl.fl_start, 558 (long long)lock->fl.fl_end); 559 560 /* First, cancel any lock that might be there */ 561 nlmsvc_cancel_blocked(file, lock); 562 563 lock->fl.fl_type = F_UNLCK; 564 error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); 565 566 return (error < 0)? nlm_lck_denied_nolocks : nlm_granted; 567 } 568 569 /* 570 * Cancel a previously blocked request. 571 * 572 * A cancel request always overrides any grant that may currently 573 * be in progress. 574 * The calling procedure must check whether the file can be closed. 575 */ 576 __be32 577 nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) 578 { 579 struct nlm_block *block; 580 int status = 0; 581 582 dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", 583 file->f_file->f_path.dentry->d_inode->i_sb->s_id, 584 file->f_file->f_path.dentry->d_inode->i_ino, 585 lock->fl.fl_pid, 586 (long long)lock->fl.fl_start, 587 (long long)lock->fl.fl_end); 588 589 mutex_lock(&file->f_mutex); 590 block = nlmsvc_lookup_block(file, lock); 591 mutex_unlock(&file->f_mutex); 592 if (block != NULL) { 593 vfs_cancel_lock(block->b_file->f_file, 594 &block->b_call->a_args.lock.fl); 595 status = nlmsvc_unlink_block(block); 596 nlmsvc_release_block(block); 597 } 598 return status ? nlm_lck_denied : nlm_granted; 599 } 600 601 /* 602 * This is a callback from the filesystem for VFS file lock requests. 603 * It will be used if fl_grant is defined and the filesystem can not 604 * respond to the request immediately. 605 * For GETLK request it will copy the reply to the nlm_block. 606 * For SETLK or SETLKW request it will get the local posix lock. 607 * In all cases it will move the block to the head of nlm_blocked q where 608 * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the 609 * deferred rpc for GETLK and SETLK. 610 */ 611 static void 612 nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, 613 int result) 614 { 615 block->b_flags |= B_GOT_CALLBACK; 616 if (result == 0) 617 block->b_granted = 1; 618 else 619 block->b_flags |= B_TIMED_OUT; 620 if (conf) { 621 if (block->b_fl) 622 locks_copy_lock(block->b_fl, conf); 623 } 624 } 625 626 static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, 627 int result) 628 { 629 struct nlm_block *block; 630 int rc = -ENOENT; 631 632 lock_kernel(); 633 list_for_each_entry(block, &nlm_blocked, b_list) { 634 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { 635 dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n", 636 block, block->b_flags); 637 if (block->b_flags & B_QUEUED) { 638 if (block->b_flags & B_TIMED_OUT) { 639 rc = -ENOLCK; 640 break; 641 } 642 nlmsvc_update_deferred_block(block, conf, result); 643 } else if (result == 0) 644 block->b_granted = 1; 645 646 nlmsvc_insert_block(block, 0); 647 svc_wake_up(block->b_daemon); 648 rc = 0; 649 break; 650 } 651 } 652 unlock_kernel(); 653 if (rc == -ENOENT) 654 printk(KERN_WARNING "lockd: grant for unknown block\n"); 655 return rc; 656 } 657 658 /* 659 * Unblock a blocked lock request. This is a callback invoked from the 660 * VFS layer when a lock on which we blocked is removed. 661 * 662 * This function doesn't grant the blocked lock instantly, but rather moves 663 * the block to the head of nlm_blocked where it can be picked up by lockd. 664 */ 665 static void 666 nlmsvc_notify_blocked(struct file_lock *fl) 667 { 668 struct nlm_block *block; 669 670 dprintk("lockd: VFS unblock notification for block %p\n", fl); 671 list_for_each_entry(block, &nlm_blocked, b_list) { 672 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { 673 nlmsvc_insert_block(block, 0); 674 svc_wake_up(block->b_daemon); 675 return; 676 } 677 } 678 679 printk(KERN_WARNING "lockd: notification for unknown block!\n"); 680 } 681 682 static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2) 683 { 684 return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; 685 } 686 687 struct lock_manager_operations nlmsvc_lock_operations = { 688 .fl_compare_owner = nlmsvc_same_owner, 689 .fl_notify = nlmsvc_notify_blocked, 690 .fl_grant = nlmsvc_grant_deferred, 691 }; 692 693 /* 694 * Try to claim a lock that was previously blocked. 695 * 696 * Note that we use both the RPC_GRANTED_MSG call _and_ an async 697 * RPC thread when notifying the client. This seems like overkill... 698 * Here's why: 699 * - we don't want to use a synchronous RPC thread, otherwise 700 * we might find ourselves hanging on a dead portmapper. 701 * - Some lockd implementations (e.g. HP) don't react to 702 * RPC_GRANTED calls; they seem to insist on RPC_GRANTED_MSG calls. 703 */ 704 static void 705 nlmsvc_grant_blocked(struct nlm_block *block) 706 { 707 struct nlm_file *file = block->b_file; 708 struct nlm_lock *lock = &block->b_call->a_args.lock; 709 int error; 710 711 dprintk("lockd: grant blocked lock %p\n", block); 712 713 kref_get(&block->b_count); 714 715 /* Unlink block request from list */ 716 nlmsvc_unlink_block(block); 717 718 /* If b_granted is true this means we've been here before. 719 * Just retry the grant callback, possibly refreshing the RPC 720 * binding */ 721 if (block->b_granted) { 722 nlm_rebind_host(block->b_host); 723 goto callback; 724 } 725 726 /* Try the lock operation again */ 727 lock->fl.fl_flags |= FL_SLEEP; 728 error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); 729 lock->fl.fl_flags &= ~FL_SLEEP; 730 731 switch (error) { 732 case 0: 733 break; 734 case -EAGAIN: 735 case -EINPROGRESS: 736 dprintk("lockd: lock still blocked error %d\n", error); 737 nlmsvc_insert_block(block, NLM_NEVER); 738 nlmsvc_release_block(block); 739 return; 740 default: 741 printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", 742 -error, __FUNCTION__); 743 nlmsvc_insert_block(block, 10 * HZ); 744 nlmsvc_release_block(block); 745 return; 746 } 747 748 callback: 749 /* Lock was granted by VFS. */ 750 dprintk("lockd: GRANTing blocked lock.\n"); 751 block->b_granted = 1; 752 753 /* Schedule next grant callback in 30 seconds */ 754 nlmsvc_insert_block(block, 30 * HZ); 755 756 /* Call the client */ 757 nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops); 758 } 759 760 /* 761 * This is the callback from the RPC layer when the NLM_GRANTED_MSG 762 * RPC call has succeeded or timed out. 763 * Like all RPC callbacks, it is invoked by the rpciod process, so it 764 * better not sleep. Therefore, we put the blocked lock on the nlm_blocked 765 * chain once more in order to have it removed by lockd itself (which can 766 * then sleep on the file semaphore without disrupting e.g. the nfs client). 767 */ 768 static void nlmsvc_grant_callback(struct rpc_task *task, void *data) 769 { 770 struct nlm_rqst *call = data; 771 struct nlm_block *block = call->a_block; 772 unsigned long timeout; 773 774 dprintk("lockd: GRANT_MSG RPC callback\n"); 775 776 /* Technically, we should down the file semaphore here. Since we 777 * move the block towards the head of the queue only, no harm 778 * can be done, though. */ 779 if (task->tk_status < 0) { 780 /* RPC error: Re-insert for retransmission */ 781 timeout = 10 * HZ; 782 } else { 783 /* Call was successful, now wait for client callback */ 784 timeout = 60 * HZ; 785 } 786 nlmsvc_insert_block(block, timeout); 787 svc_wake_up(block->b_daemon); 788 } 789 790 static void nlmsvc_grant_release(void *data) 791 { 792 struct nlm_rqst *call = data; 793 794 nlmsvc_release_block(call->a_block); 795 } 796 797 static const struct rpc_call_ops nlmsvc_grant_ops = { 798 .rpc_call_done = nlmsvc_grant_callback, 799 .rpc_release = nlmsvc_grant_release, 800 }; 801 802 /* 803 * We received a GRANT_RES callback. Try to find the corresponding 804 * block. 805 */ 806 void 807 nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status) 808 { 809 struct nlm_block *block; 810 811 dprintk("grant_reply: looking for cookie %x, s=%d \n", 812 *(unsigned int *)(cookie->data), status); 813 if (!(block = nlmsvc_find_block(cookie))) 814 return; 815 816 if (block) { 817 if (status == nlm_lck_denied_grace_period) { 818 /* Try again in a couple of seconds */ 819 nlmsvc_insert_block(block, 10 * HZ); 820 } else { 821 /* Lock is now held by client, or has been rejected. 822 * In both cases, the block should be removed. */ 823 nlmsvc_unlink_block(block); 824 } 825 } 826 nlmsvc_release_block(block); 827 } 828 829 /* Helper function to handle retry of a deferred block. 830 * If it is a blocking lock, call grant_blocked. 831 * For a non-blocking lock or test lock, revisit the request. 832 */ 833 static void 834 retry_deferred_block(struct nlm_block *block) 835 { 836 if (!(block->b_flags & B_GOT_CALLBACK)) 837 block->b_flags |= B_TIMED_OUT; 838 nlmsvc_insert_block(block, NLM_TIMEOUT); 839 dprintk("revisit block %p flags %d\n", block, block->b_flags); 840 if (block->b_deferred_req) { 841 block->b_deferred_req->revisit(block->b_deferred_req, 0); 842 block->b_deferred_req = NULL; 843 } 844 } 845 846 /* 847 * Retry all blocked locks that have been notified. This is where lockd 848 * picks up locks that can be granted, or grant notifications that must 849 * be retransmitted. 850 */ 851 unsigned long 852 nlmsvc_retry_blocked(void) 853 { 854 unsigned long timeout = MAX_SCHEDULE_TIMEOUT; 855 struct nlm_block *block; 856 857 while (!list_empty(&nlm_blocked)) { 858 block = list_entry(nlm_blocked.next, struct nlm_block, b_list); 859 860 if (block->b_when == NLM_NEVER) 861 break; 862 if (time_after(block->b_when,jiffies)) { 863 timeout = block->b_when - jiffies; 864 break; 865 } 866 867 dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", 868 block, block->b_when); 869 if (block->b_flags & B_QUEUED) { 870 dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n", 871 block, block->b_granted, block->b_flags); 872 retry_deferred_block(block); 873 } else 874 nlmsvc_grant_blocked(block); 875 } 876 877 return timeout; 878 } 879