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