aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svclock.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/svclock.c')
-rw-r--r--fs/lockd/svclock.c68
1 files changed, 10 insertions, 58 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index ab798a88ec1d..13db95f54176 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -245,7 +245,6 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
245 block->b_daemon = rqstp->rq_server; 245 block->b_daemon = rqstp->rq_server;
246 block->b_host = host; 246 block->b_host = host;
247 block->b_file = file; 247 block->b_file = file;
248 block->b_fl = NULL;
249 file->f_count++; 248 file->f_count++;
250 249
251 /* Add to file's list of blocks */ 250 /* Add to file's list of blocks */
@@ -295,7 +294,6 @@ static void nlmsvc_free_block(struct kref *kref)
295 nlmsvc_freegrantargs(block->b_call); 294 nlmsvc_freegrantargs(block->b_call);
296 nlmsvc_release_call(block->b_call); 295 nlmsvc_release_call(block->b_call);
297 nlm_release_file(block->b_file); 296 nlm_release_file(block->b_file);
298 kfree(block->b_fl);
299 kfree(block); 297 kfree(block);
300} 298}
301 299
@@ -508,7 +506,6 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
508 struct nlm_host *host, struct nlm_lock *lock, 506 struct nlm_host *host, struct nlm_lock *lock,
509 struct nlm_lock *conflock, struct nlm_cookie *cookie) 507 struct nlm_lock *conflock, struct nlm_cookie *cookie)
510{ 508{
511 struct nlm_block *block = NULL;
512 int error; 509 int error;
513 __be32 ret; 510 __be32 ret;
514 511
@@ -519,63 +516,26 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
519 (long long)lock->fl.fl_start, 516 (long long)lock->fl.fl_start,
520 (long long)lock->fl.fl_end); 517 (long long)lock->fl.fl_end);
521 518
522 /* Get existing block (in case client is busy-waiting) */
523 block = nlmsvc_lookup_block(file, lock);
524
525 if (block == NULL) {
526 struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
527
528 if (conf == NULL)
529 return nlm_granted;
530 block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
531 if (block == NULL) {
532 kfree(conf);
533 return nlm_granted;
534 }
535 block->b_fl = conf;
536 }
537 if (block->b_flags & B_QUEUED) {
538 dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
539 block, block->b_flags, block->b_fl);
540 if (block->b_flags & B_TIMED_OUT) {
541 nlmsvc_unlink_block(block);
542 ret = nlm_lck_denied;
543 goto out;
544 }
545 if (block->b_flags & B_GOT_CALLBACK) {
546 nlmsvc_unlink_block(block);
547 if (block->b_fl != NULL
548 && block->b_fl->fl_type != F_UNLCK) {
549 lock->fl = *block->b_fl;
550 goto conf_lock;
551 } else {
552 ret = nlm_granted;
553 goto out;
554 }
555 }
556 ret = nlm_drop_reply;
557 goto out;
558 }
559
560 if (locks_in_grace(SVC_NET(rqstp))) { 519 if (locks_in_grace(SVC_NET(rqstp))) {
561 ret = nlm_lck_denied_grace_period; 520 ret = nlm_lck_denied_grace_period;
562 goto out; 521 goto out;
563 } 522 }
523
564 error = vfs_test_lock(file->f_file, &lock->fl); 524 error = vfs_test_lock(file->f_file, &lock->fl);
565 if (error == FILE_LOCK_DEFERRED) {
566 ret = nlmsvc_defer_lock_rqst(rqstp, block);
567 goto out;
568 }
569 if (error) { 525 if (error) {
526 /* We can't currently deal with deferred test requests */
527 if (error == FILE_LOCK_DEFERRED)
528 WARN_ON_ONCE(1);
529
570 ret = nlm_lck_denied_nolocks; 530 ret = nlm_lck_denied_nolocks;
571 goto out; 531 goto out;
572 } 532 }
533
573 if (lock->fl.fl_type == F_UNLCK) { 534 if (lock->fl.fl_type == F_UNLCK) {
574 ret = nlm_granted; 535 ret = nlm_granted;
575 goto out; 536 goto out;
576 } 537 }
577 538
578conf_lock:
579 dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n", 539 dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
580 lock->fl.fl_type, (long long)lock->fl.fl_start, 540 lock->fl.fl_type, (long long)lock->fl.fl_start,
581 (long long)lock->fl.fl_end); 541 (long long)lock->fl.fl_end);
@@ -586,10 +546,9 @@ conf_lock:
586 conflock->fl.fl_type = lock->fl.fl_type; 546 conflock->fl.fl_type = lock->fl.fl_type;
587 conflock->fl.fl_start = lock->fl.fl_start; 547 conflock->fl.fl_start = lock->fl.fl_start;
588 conflock->fl.fl_end = lock->fl.fl_end; 548 conflock->fl.fl_end = lock->fl.fl_end;
549 locks_release_private(&lock->fl);
589 ret = nlm_lck_denied; 550 ret = nlm_lck_denied;
590out: 551out:
591 if (block)
592 nlmsvc_release_block(block);
593 return ret; 552 return ret;
594} 553}
595 554
@@ -660,29 +619,22 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
660 * This is a callback from the filesystem for VFS file lock requests. 619 * This is a callback from the filesystem for VFS file lock requests.
661 * It will be used if lm_grant is defined and the filesystem can not 620 * It will be used if lm_grant is defined and the filesystem can not
662 * respond to the request immediately. 621 * respond to the request immediately.
663 * For GETLK request it will copy the reply to the nlm_block.
664 * For SETLK or SETLKW request it will get the local posix lock. 622 * For SETLK or SETLKW request it will get the local posix lock.
665 * In all cases it will move the block to the head of nlm_blocked q where 623 * In all cases it will move the block to the head of nlm_blocked q where
666 * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the 624 * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
667 * deferred rpc for GETLK and SETLK. 625 * deferred rpc for GETLK and SETLK.
668 */ 626 */
669static void 627static void
670nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, 628nlmsvc_update_deferred_block(struct nlm_block *block, int result)
671 int result)
672{ 629{
673 block->b_flags |= B_GOT_CALLBACK; 630 block->b_flags |= B_GOT_CALLBACK;
674 if (result == 0) 631 if (result == 0)
675 block->b_granted = 1; 632 block->b_granted = 1;
676 else 633 else
677 block->b_flags |= B_TIMED_OUT; 634 block->b_flags |= B_TIMED_OUT;
678 if (conf) {
679 if (block->b_fl)
680 __locks_copy_lock(block->b_fl, conf);
681 }
682} 635}
683 636
684static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, 637static int nlmsvc_grant_deferred(struct file_lock *fl, int result)
685 int result)
686{ 638{
687 struct nlm_block *block; 639 struct nlm_block *block;
688 int rc = -ENOENT; 640 int rc = -ENOENT;
@@ -697,7 +649,7 @@ static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf,
697 rc = -ENOLCK; 649 rc = -ENOLCK;
698 break; 650 break;
699 } 651 }
700 nlmsvc_update_deferred_block(block, conf, result); 652 nlmsvc_update_deferred_block(block, result);
701 } else if (result == 0) 653 } else if (result == 0)
702 block->b_granted = 1; 654 block->b_granted = 1;
703 655