aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd')
-rw-r--r--fs/lockd/mon.c10
-rw-r--r--fs/lockd/svc4proc.c6
-rw-r--r--fs/lockd/svclock.c275
-rw-r--r--fs/lockd/svcproc.c7
-rw-r--r--fs/lockd/svcsubs.c2
-rw-r--r--fs/lockd/xdr.c20
-rw-r--r--fs/lockd/xdr4.c24
7 files changed, 268 insertions, 76 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index eb243edf8932..2102e2d0134d 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -225,16 +225,13 @@ xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp)
225#define SM_monres_sz 2 225#define SM_monres_sz 2
226#define SM_unmonres_sz 1 226#define SM_unmonres_sz 1
227 227
228#ifndef MAX
229# define MAX(a, b) (((a) > (b))? (a) : (b))
230#endif
231
232static struct rpc_procinfo nsm_procedures[] = { 228static struct rpc_procinfo nsm_procedures[] = {
233[SM_MON] = { 229[SM_MON] = {
234 .p_proc = SM_MON, 230 .p_proc = SM_MON,
235 .p_encode = (kxdrproc_t) xdr_encode_mon, 231 .p_encode = (kxdrproc_t) xdr_encode_mon,
236 .p_decode = (kxdrproc_t) xdr_decode_stat_res, 232 .p_decode = (kxdrproc_t) xdr_decode_stat_res,
237 .p_bufsiz = MAX(SM_mon_sz, SM_monres_sz) << 2, 233 .p_arglen = SM_mon_sz,
234 .p_replen = SM_monres_sz,
238 .p_statidx = SM_MON, 235 .p_statidx = SM_MON,
239 .p_name = "MONITOR", 236 .p_name = "MONITOR",
240 }, 237 },
@@ -242,7 +239,8 @@ static struct rpc_procinfo nsm_procedures[] = {
242 .p_proc = SM_UNMON, 239 .p_proc = SM_UNMON,
243 .p_encode = (kxdrproc_t) xdr_encode_unmon, 240 .p_encode = (kxdrproc_t) xdr_encode_unmon,
244 .p_decode = (kxdrproc_t) xdr_decode_stat, 241 .p_decode = (kxdrproc_t) xdr_decode_stat,
245 .p_bufsiz = MAX(SM_mon_id_sz, SM_unmonres_sz) << 2, 242 .p_arglen = SM_mon_id_sz,
243 .p_replen = SM_unmonres_sz,
246 .p_statidx = SM_UNMON, 244 .p_statidx = SM_UNMON,
247 .p_name = "UNMONITOR", 245 .p_name = "UNMONITOR",
248 }, 246 },
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 47a66aa5d55b..bf27b6c6cb6b 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -99,7 +99,9 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
99 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 99 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
100 100
101 /* Now check for conflicting locks */ 101 /* Now check for conflicting locks */
102 resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock); 102 resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie);
103 if (resp->status == nlm_drop_reply)
104 return rpc_drop_reply;
103 105
104 dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); 106 dprintk("lockd: TEST4 status %d\n", ntohl(resp->status));
105 nlm_release_host(host); 107 nlm_release_host(host);
@@ -143,6 +145,8 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
143 /* Now try to lock the file */ 145 /* Now try to lock the file */
144 resp->status = nlmsvc_lock(rqstp, file, &argp->lock, 146 resp->status = nlmsvc_lock(rqstp, file, &argp->lock,
145 argp->block, &argp->cookie); 147 argp->block, &argp->cookie);
148 if (resp->status == nlm_drop_reply)
149 return rpc_drop_reply;
146 150
147 dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); 151 dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
148 nlm_release_host(host); 152 nlm_release_host(host);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index cf51f849e76c..b3efa4536cc5 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -173,7 +173,7 @@ found:
173 */ 173 */
174static inline struct nlm_block * 174static inline struct nlm_block *
175nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, 175nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
176 struct nlm_lock *lock, struct nlm_cookie *cookie) 176 struct nlm_lock *lock, struct nlm_cookie *cookie)
177{ 177{
178 struct nlm_block *block; 178 struct nlm_block *block;
179 struct nlm_host *host; 179 struct nlm_host *host;
@@ -210,6 +210,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
210 block->b_daemon = rqstp->rq_server; 210 block->b_daemon = rqstp->rq_server;
211 block->b_host = host; 211 block->b_host = host;
212 block->b_file = file; 212 block->b_file = file;
213 block->b_fl = NULL;
213 file->f_count++; 214 file->f_count++;
214 215
215 /* Add to file's list of blocks */ 216 /* Add to file's list of blocks */
@@ -261,6 +262,7 @@ static void nlmsvc_free_block(struct kref *kref)
261 nlmsvc_freegrantargs(block->b_call); 262 nlmsvc_freegrantargs(block->b_call);
262 nlm_release_call(block->b_call); 263 nlm_release_call(block->b_call);
263 nlm_release_file(block->b_file); 264 nlm_release_file(block->b_file);
265 kfree(block->b_fl);
264 kfree(block); 266 kfree(block);
265} 267}
266 268
@@ -331,6 +333,31 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call)
331} 333}
332 334
333/* 335/*
336 * Deferred lock request handling for non-blocking lock
337 */
338static u32
339nlmsvc_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/*
334 * Attempt to establish a lock, and if it can't be granted, block it 361 * Attempt to establish a lock, and if it can't be granted, block it
335 * if required. 362 * if required.
336 */ 363 */
@@ -338,7 +365,7 @@ __be32
338nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, 365nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
339 struct nlm_lock *lock, int wait, struct nlm_cookie *cookie) 366 struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
340{ 367{
341 struct nlm_block *block, *newblock = NULL; 368 struct nlm_block *block = NULL;
342 int error; 369 int error;
343 __be32 ret; 370 __be32 ret;
344 371
@@ -351,29 +378,58 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
351 wait); 378 wait);
352 379
353 380
354 lock->fl.fl_flags &= ~FL_SLEEP;
355again:
356 /* Lock file against concurrent access */ 381 /* Lock file against concurrent access */
357 mutex_lock(&file->f_mutex); 382 mutex_lock(&file->f_mutex);
358 /* Get existing block (in case client is busy-waiting) */ 383 /* Get existing block (in case client is busy-waiting)
384 * or create new block
385 */
359 block = nlmsvc_lookup_block(file, lock); 386 block = nlmsvc_lookup_block(file, lock);
360 if (block == NULL) { 387 if (block == NULL) {
361 if (newblock != NULL) 388 block = nlmsvc_create_block(rqstp, file, lock, cookie);
362 lock = &newblock->b_call->a_args.lock; 389 ret = nlm_lck_denied_nolocks;
363 } else 390 if (block == NULL)
391 goto out;
364 lock = &block->b_call->a_args.lock; 392 lock = &block->b_call->a_args.lock;
393 } else
394 lock->fl.fl_flags &= ~FL_SLEEP;
365 395
366 error = posix_lock_file(file->f_file, &lock->fl); 396 if (block->b_flags & B_QUEUED) {
367 lock->fl.fl_flags &= ~FL_SLEEP; 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 }
368 412
369 dprintk("lockd: posix_lock_file returned %d\n", error); 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;
370 417
418 dprintk("lockd: vfs_lock_file returned %d\n", error);
371 switch(error) { 419 switch(error) {
372 case 0: 420 case 0:
373 ret = nlm_granted; 421 ret = nlm_granted;
374 goto out; 422 goto out;
375 case -EAGAIN: 423 case -EAGAIN:
424 ret = nlm_lck_denied;
376 break; 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;
377 case -EDEADLK: 433 case -EDEADLK:
378 ret = nlm_deadlock; 434 ret = nlm_deadlock;
379 goto out; 435 goto out;
@@ -387,26 +443,11 @@ again:
387 goto out; 443 goto out;
388 444
389 ret = nlm_lck_blocked; 445 ret = nlm_lck_blocked;
390 if (block != NULL)
391 goto out;
392
393 /* If we don't have a block, create and initialize it. Then
394 * retry because we may have slept in kmalloc. */
395 /* We have to release f_mutex as nlmsvc_create_block may try to
396 * to claim it while doing host garbage collection */
397 if (newblock == NULL) {
398 mutex_unlock(&file->f_mutex);
399 dprintk("lockd: blocking on this lock (allocating).\n");
400 if (!(newblock = nlmsvc_create_block(rqstp, file, lock, cookie)))
401 return nlm_lck_denied_nolocks;
402 goto again;
403 }
404 446
405 /* Append to list of blocked */ 447 /* Append to list of blocked */
406 nlmsvc_insert_block(newblock, NLM_NEVER); 448 nlmsvc_insert_block(block, NLM_NEVER);
407out: 449out:
408 mutex_unlock(&file->f_mutex); 450 mutex_unlock(&file->f_mutex);
409 nlmsvc_release_block(newblock);
410 nlmsvc_release_block(block); 451 nlmsvc_release_block(block);
411 dprintk("lockd: nlmsvc_lock returned %u\n", ret); 452 dprintk("lockd: nlmsvc_lock returned %u\n", ret);
412 return ret; 453 return ret;
@@ -416,9 +457,14 @@ out:
416 * Test for presence of a conflicting lock. 457 * Test for presence of a conflicting lock.
417 */ 458 */
418__be32 459__be32
419nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock, 460nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
420 struct nlm_lock *conflock) 461 struct nlm_lock *lock, struct nlm_lock *conflock,
462 struct nlm_cookie *cookie)
421{ 463{
464 struct nlm_block *block = NULL;
465 int error;
466 __be32 ret;
467
422 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", 468 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
423 file->f_file->f_path.dentry->d_inode->i_sb->s_id, 469 file->f_file->f_path.dentry->d_inode->i_sb->s_id,
424 file->f_file->f_path.dentry->d_inode->i_ino, 470 file->f_file->f_path.dentry->d_inode->i_ino,
@@ -426,19 +472,70 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
426 (long long)lock->fl.fl_start, 472 (long long)lock->fl.fl_start,
427 (long long)lock->fl.fl_end); 473 (long long)lock->fl.fl_end);
428 474
429 if (posix_test_lock(file->f_file, &lock->fl, &conflock->fl)) { 475 /* Get existing block (in case client is busy-waiting) */
430 dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n", 476 block = nlmsvc_lookup_block(file, lock);
431 conflock->fl.fl_type, 477
432 (long long)conflock->fl.fl_start, 478 if (block == NULL) {
433 (long long)conflock->fl.fl_end); 479 struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
434 conflock->caller = "somehost"; /* FIXME */ 480
435 conflock->len = strlen(conflock->caller); 481 if (conf == NULL)
436 conflock->oh.len = 0; /* don't return OH info */ 482 return nlm_granted;
437 conflock->svid = conflock->fl.fl_pid; 483 block = nlmsvc_create_block(rqstp, file, lock, cookie);
438 return nlm_lck_denied; 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;
439 } 509 }
440 510
441 return nlm_granted; 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
523conf_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;
535out:
536 if (block)
537 nlmsvc_release_block(block);
538 return ret;
442} 539}
443 540
444/* 541/*
@@ -464,7 +561,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
464 nlmsvc_cancel_blocked(file, lock); 561 nlmsvc_cancel_blocked(file, lock);
465 562
466 lock->fl.fl_type = F_UNLCK; 563 lock->fl.fl_type = F_UNLCK;
467 error = posix_lock_file(file->f_file, &lock->fl); 564 error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
468 565
469 return (error < 0)? nlm_lck_denied_nolocks : nlm_granted; 566 return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
470} 567}
@@ -493,6 +590,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
493 block = nlmsvc_lookup_block(file, lock); 590 block = nlmsvc_lookup_block(file, lock);
494 mutex_unlock(&file->f_mutex); 591 mutex_unlock(&file->f_mutex);
495 if (block != NULL) { 592 if (block != NULL) {
593 vfs_cancel_lock(block->b_file->f_file,
594 &block->b_call->a_args.lock.fl);
496 status = nlmsvc_unlink_block(block); 595 status = nlmsvc_unlink_block(block);
497 nlmsvc_release_block(block); 596 nlmsvc_release_block(block);
498 } 597 }
@@ -500,6 +599,63 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
500} 599}
501 600
502/* 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 */
611static void
612nlmsvc_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
626static 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/*
503 * Unblock a blocked lock request. This is a callback invoked from the 659 * Unblock a blocked lock request. This is a callback invoked from the
504 * VFS layer when a lock on which we blocked is removed. 660 * VFS layer when a lock on which we blocked is removed.
505 * 661 *
@@ -531,6 +687,7 @@ static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
531struct lock_manager_operations nlmsvc_lock_operations = { 687struct lock_manager_operations nlmsvc_lock_operations = {
532 .fl_compare_owner = nlmsvc_same_owner, 688 .fl_compare_owner = nlmsvc_same_owner,
533 .fl_notify = nlmsvc_notify_blocked, 689 .fl_notify = nlmsvc_notify_blocked,
690 .fl_grant = nlmsvc_grant_deferred,
534}; 691};
535 692
536/* 693/*
@@ -553,6 +710,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
553 710
554 dprintk("lockd: grant blocked lock %p\n", block); 711 dprintk("lockd: grant blocked lock %p\n", block);
555 712
713 kref_get(&block->b_count);
714
556 /* Unlink block request from list */ 715 /* Unlink block request from list */
557 nlmsvc_unlink_block(block); 716 nlmsvc_unlink_block(block);
558 717
@@ -566,20 +725,23 @@ nlmsvc_grant_blocked(struct nlm_block *block)
566 725
567 /* Try the lock operation again */ 726 /* Try the lock operation again */
568 lock->fl.fl_flags |= FL_SLEEP; 727 lock->fl.fl_flags |= FL_SLEEP;
569 error = posix_lock_file(file->f_file, &lock->fl); 728 error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
570 lock->fl.fl_flags &= ~FL_SLEEP; 729 lock->fl.fl_flags &= ~FL_SLEEP;
571 730
572 switch (error) { 731 switch (error) {
573 case 0: 732 case 0:
574 break; 733 break;
575 case -EAGAIN: 734 case -EAGAIN:
576 dprintk("lockd: lock still blocked\n"); 735 case -EINPROGRESS:
736 dprintk("lockd: lock still blocked error %d\n", error);
577 nlmsvc_insert_block(block, NLM_NEVER); 737 nlmsvc_insert_block(block, NLM_NEVER);
738 nlmsvc_release_block(block);
578 return; 739 return;
579 default: 740 default:
580 printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", 741 printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
581 -error, __FUNCTION__); 742 -error, __FUNCTION__);
582 nlmsvc_insert_block(block, 10 * HZ); 743 nlmsvc_insert_block(block, 10 * HZ);
744 nlmsvc_release_block(block);
583 return; 745 return;
584 } 746 }
585 747
@@ -592,7 +754,6 @@ callback:
592 nlmsvc_insert_block(block, 30 * HZ); 754 nlmsvc_insert_block(block, 30 * HZ);
593 755
594 /* Call the client */ 756 /* Call the client */
595 kref_get(&block->b_count);
596 nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops); 757 nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops);
597} 758}
598 759
@@ -665,6 +826,23 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
665 nlmsvc_release_block(block); 826 nlmsvc_release_block(block);
666} 827}
667 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 */
833static void
834retry_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
668/* 846/*
669 * Retry all blocked locks that have been notified. This is where lockd 847 * Retry all blocked locks that have been notified. This is where lockd
670 * picks up locks that can be granted, or grant notifications that must 848 * picks up locks that can be granted, or grant notifications that must
@@ -688,9 +866,12 @@ nlmsvc_retry_blocked(void)
688 866
689 dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", 867 dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
690 block, block->b_when); 868 block, block->b_when);
691 kref_get(&block->b_count); 869 if (block->b_flags & B_QUEUED) {
692 nlmsvc_grant_blocked(block); 870 dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
693 nlmsvc_release_block(block); 871 block, block->b_granted, block->b_flags);
872 retry_deferred_block(block);
873 } else
874 nlmsvc_grant_blocked(block);
694 } 875 }
695 876
696 return timeout; 877 return timeout;
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 31cb48425733..9cd5c8b37593 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -33,6 +33,7 @@ cast_to_nlm(__be32 status, u32 vers)
33 case nlm_lck_denied_nolocks: 33 case nlm_lck_denied_nolocks:
34 case nlm_lck_blocked: 34 case nlm_lck_blocked:
35 case nlm_lck_denied_grace_period: 35 case nlm_lck_denied_grace_period:
36 case nlm_drop_reply:
36 break; 37 break;
37 case nlm4_deadlock: 38 case nlm4_deadlock:
38 status = nlm_lck_denied; 39 status = nlm_lck_denied;
@@ -127,7 +128,9 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
127 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 128 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
128 129
129 /* Now check for conflicting locks */ 130 /* Now check for conflicting locks */
130 resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock)); 131 resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
132 if (resp->status == nlm_drop_reply)
133 return rpc_drop_reply;
131 134
132 dprintk("lockd: TEST status %d vers %d\n", 135 dprintk("lockd: TEST status %d vers %d\n",
133 ntohl(resp->status), rqstp->rq_vers); 136 ntohl(resp->status), rqstp->rq_vers);
@@ -172,6 +175,8 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
172 /* Now try to lock the file */ 175 /* Now try to lock the file */
173 resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock, 176 resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock,
174 argp->block, &argp->cookie)); 177 argp->block, &argp->cookie));
178 if (resp->status == nlm_drop_reply)
179 return rpc_drop_reply;
175 180
176 dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); 181 dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
177 nlm_release_host(host); 182 nlm_release_host(host);
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index c0df00c74ce3..84ebba33b98d 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -182,7 +182,7 @@ again:
182 lock.fl_type = F_UNLCK; 182 lock.fl_type = F_UNLCK;
183 lock.fl_start = 0; 183 lock.fl_start = 0;
184 lock.fl_end = OFFSET_MAX; 184 lock.fl_end = OFFSET_MAX;
185 if (posix_lock_file(file->f_file, &lock) < 0) { 185 if (vfs_lock_file(file->f_file, F_SETLK, &lock, NULL) < 0) {
186 printk("lockd: unlock failure in %s:%d\n", 186 printk("lockd: unlock failure in %s:%d\n",
187 __FILE__, __LINE__); 187 __FILE__, __LINE__);
188 return 1; 188 return 1;
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 34dae5d70738..9702956d206c 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -510,17 +510,20 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
510 return 0; 510 return 0;
511} 511}
512 512
513#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
514# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
515#endif
516
513/* 517/*
514 * Buffer requirements for NLM 518 * Buffer requirements for NLM
515 */ 519 */
516#define NLM_void_sz 0 520#define NLM_void_sz 0
517#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) 521#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
518#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(utsname()->nodename)) 522#define NLM_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
519#define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) 523#define NLM_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
520/* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */
521#define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE) 524#define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE)
522#define NLM_lock_sz 3+NLM_caller_sz+NLM_netobj_sz+NLM_fhandle_sz 525#define NLM_lock_sz 3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz
523#define NLM_holder_sz 4+NLM_netobj_sz 526#define NLM_holder_sz 4+NLM_owner_sz
524 527
525#define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz 528#define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz
526#define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz 529#define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz
@@ -531,10 +534,6 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
531#define NLM_res_sz NLM_cookie_sz+1 534#define NLM_res_sz NLM_cookie_sz+1
532#define NLM_norep_sz 0 535#define NLM_norep_sz 0
533 536
534#ifndef MAX
535# define MAX(a, b) (((a) > (b))? (a) : (b))
536#endif
537
538/* 537/*
539 * For NLM, a void procedure really returns nothing 538 * For NLM, a void procedure really returns nothing
540 */ 539 */
@@ -545,7 +544,8 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
545 .p_proc = NLMPROC_##proc, \ 544 .p_proc = NLMPROC_##proc, \
546 .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \ 545 .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \
547 .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \ 546 .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \
548 .p_bufsiz = MAX(NLM_##argtype##_sz, NLM_##restype##_sz) << 2, \ 547 .p_arglen = NLM_##argtype##_sz, \
548 .p_replen = NLM_##restype##_sz, \
549 .p_statidx = NLMPROC_##proc, \ 549 .p_statidx = NLMPROC_##proc, \
550 .p_name = #proc, \ 550 .p_name = #proc, \
551 } 551 }
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index a78240551219..ce1efdbe1b3a 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -516,17 +516,24 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
516 return 0; 516 return 0;
517} 517}
518 518
519#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
520# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
521#endif
522
523#if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN)
524# error "NLM host name cannot be larger than NLM's maximum string length!"
525#endif
526
519/* 527/*
520 * Buffer requirements for NLM 528 * Buffer requirements for NLM
521 */ 529 */
522#define NLM4_void_sz 0 530#define NLM4_void_sz 0
523#define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) 531#define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
524#define NLM4_caller_sz 1+XDR_QUADLEN(NLM_MAXSTRLEN) 532#define NLM4_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
525#define NLM4_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) 533#define NLM4_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
526/* #define NLM4_owner_sz 1+XDR_QUADLEN(NLM4_MAXOWNER) */
527#define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE) 534#define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE)
528#define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_netobj_sz+NLM4_fhandle_sz 535#define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz
529#define NLM4_holder_sz 6+NLM4_netobj_sz 536#define NLM4_holder_sz 6+NLM4_owner_sz
530 537
531#define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz 538#define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz
532#define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz 539#define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz
@@ -537,10 +544,6 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
537#define NLM4_res_sz NLM4_cookie_sz+1 544#define NLM4_res_sz NLM4_cookie_sz+1
538#define NLM4_norep_sz 0 545#define NLM4_norep_sz 0
539 546
540#ifndef MAX
541# define MAX(a,b) (((a) > (b))? (a) : (b))
542#endif
543
544/* 547/*
545 * For NLM, a void procedure really returns nothing 548 * For NLM, a void procedure really returns nothing
546 */ 549 */
@@ -551,7 +554,8 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
551 .p_proc = NLMPROC_##proc, \ 554 .p_proc = NLMPROC_##proc, \
552 .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \ 555 .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \
553 .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \ 556 .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \
554 .p_bufsiz = MAX(NLM4_##argtype##_sz, NLM4_##restype##_sz) << 2, \ 557 .p_arglen = NLM4_##argtype##_sz, \
558 .p_replen = NLM4_##restype##_sz, \
555 .p_statidx = NLMPROC_##proc, \ 559 .p_statidx = NLMPROC_##proc, \
556 .p_name = #proc, \ 560 .p_name = #proc, \
557 } 561 }