clntproc.c (6b4b3a752b3464f2fd9fe2837fb19270c23c1d6b) clntproc.c (5f50c0c6d644d6c8180d9079c13c5d9de3adeb34)
1/*
2 * linux/fs/lockd/clntproc.c
3 *
4 * RPC procedures for the client side NLM implementation
5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8

--- 496 unchanged lines hidden (view full) ---

505 */
506static int
507nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
508{
509 struct nlm_host *host = req->a_host;
510 struct nlm_res *resp = &req->a_res;
511 struct nlm_wait *block = NULL;
512 unsigned char fl_flags = fl->fl_flags;
1/*
2 * linux/fs/lockd/clntproc.c
3 *
4 * RPC procedures for the client side NLM implementation
5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8

--- 496 unchanged lines hidden (view full) ---

505 */
506static int
507nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
508{
509 struct nlm_host *host = req->a_host;
510 struct nlm_res *resp = &req->a_res;
511 struct nlm_wait *block = NULL;
512 unsigned char fl_flags = fl->fl_flags;
513 unsigned char fl_type;
513 int status = -ENOLCK;
514
515 if (nsm_monitor(host) < 0) {
516 printk(KERN_NOTICE "lockd: failed to monitor %s\n",
517 host->h_name);
518 goto out;
519 }
520 fl->fl_flags |= FL_ACCESS;
521 status = do_vfs_lock(fl);
522 fl->fl_flags = fl_flags;
523 if (status < 0)
524 goto out;
525
526 block = nlmclnt_prepare_block(host, fl);
527again:
514 int status = -ENOLCK;
515
516 if (nsm_monitor(host) < 0) {
517 printk(KERN_NOTICE "lockd: failed to monitor %s\n",
518 host->h_name);
519 goto out;
520 }
521 fl->fl_flags |= FL_ACCESS;
522 status = do_vfs_lock(fl);
523 fl->fl_flags = fl_flags;
524 if (status < 0)
525 goto out;
526
527 block = nlmclnt_prepare_block(host, fl);
528again:
529 /*
530 * Initialise resp->status to a valid non-zero value,
531 * since 0 == nlm_lck_granted
532 */
533 resp->status = nlm_lck_blocked;
528 for(;;) {
529 /* Reboot protection */
530 fl->fl_u.nfs_fl.state = host->h_state;
531 status = nlmclnt_call(req, NLMPROC_LOCK);
532 if (status < 0)
534 for(;;) {
535 /* Reboot protection */
536 fl->fl_u.nfs_fl.state = host->h_state;
537 status = nlmclnt_call(req, NLMPROC_LOCK);
538 if (status < 0)
533 goto out_unblock;
534 if (!req->a_args.block)
535 break;
536 /* Did a reclaimer thread notify us of a server reboot? */
537 if (resp->status == nlm_lck_denied_grace_period)
538 continue;
539 if (resp->status != nlm_lck_blocked)
540 break;
541 /* Wait on an NLM blocking lock */
542 status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
539 break;
540 /* Did a reclaimer thread notify us of a server reboot? */
541 if (resp->status == nlm_lck_denied_grace_period)
542 continue;
543 if (resp->status != nlm_lck_blocked)
544 break;
545 /* Wait on an NLM blocking lock */
546 status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
543 /* if we were interrupted. Send a CANCEL request to the server
544 * and exit
545 */
546 if (status < 0)
547 if (status < 0)
547 goto out_unblock;
548 break;
548 if (resp->status != nlm_lck_blocked)
549 break;
550 }
551
549 if (resp->status != nlm_lck_blocked)
550 break;
551 }
552
553 /* if we were interrupted while blocking, then cancel the lock request
554 * and exit
555 */
556 if (resp->status == nlm_lck_blocked) {
557 if (!req->a_args.block)
558 goto out_unlock;
559 if (nlmclnt_cancel(host, req->a_args.block, fl) == 0)
560 goto out_unblock;
561 }
562
552 if (resp->status == nlm_granted) {
553 down_read(&host->h_rwsem);
554 /* Check whether or not the server has rebooted */
555 if (fl->fl_u.nfs_fl.state != host->h_state) {
556 up_read(&host->h_rwsem);
557 goto again;
558 }
559 /* Ensure the resulting lock will get added to granted list */
560 fl->fl_flags |= FL_SLEEP;
561 if (do_vfs_lock(fl) < 0)
562 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
563 up_read(&host->h_rwsem);
564 fl->fl_flags = fl_flags;
563 if (resp->status == nlm_granted) {
564 down_read(&host->h_rwsem);
565 /* Check whether or not the server has rebooted */
566 if (fl->fl_u.nfs_fl.state != host->h_state) {
567 up_read(&host->h_rwsem);
568 goto again;
569 }
570 /* Ensure the resulting lock will get added to granted list */
571 fl->fl_flags |= FL_SLEEP;
572 if (do_vfs_lock(fl) < 0)
573 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
574 up_read(&host->h_rwsem);
575 fl->fl_flags = fl_flags;
576 status = 0;
565 }
577 }
578 if (status < 0)
579 goto out_unlock;
566 status = nlm_stat_to_errno(resp->status);
567out_unblock:
568 nlmclnt_finish_block(block);
580 status = nlm_stat_to_errno(resp->status);
581out_unblock:
582 nlmclnt_finish_block(block);
569 /* Cancel the blocked request if it is still pending */
570 if (resp->status == nlm_lck_blocked)
571 nlmclnt_cancel(host, req->a_args.block, fl);
572out:
573 nlm_release_call(req);
574 return status;
583out:
584 nlm_release_call(req);
585 return status;
586out_unlock:
587 /* Fatal error: ensure that we remove the lock altogether */
588 dprintk("lockd: lock attempt ended in fatal error.\n"
589 " Attempting to unlock.\n");
590 nlmclnt_finish_block(block);
591 fl_type = fl->fl_type;
592 fl->fl_type = F_UNLCK;
593 down_read(&host->h_rwsem);
594 do_vfs_lock(fl);
595 up_read(&host->h_rwsem);
596 fl->fl_type = fl_type;
597 fl->fl_flags = fl_flags;
598 nlmclnt_async_call(req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops);
599 return status;
575}
576
577/*
578 * RECLAIM: Try to reclaim a lock
579 */
580int
581nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl)
582{

--- 221 unchanged lines hidden ---
600}
601
602/*
603 * RECLAIM: Try to reclaim a lock
604 */
605int
606nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl)
607{

--- 221 unchanged lines hidden ---