diff options
Diffstat (limited to 'fs/lockd/clntproc.c')
-rw-r--r-- | fs/lockd/clntproc.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index f96e38155b5c..4db62098d3f4 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -508,7 +508,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) | |||
508 | } | 508 | } |
509 | 509 | ||
510 | block = nlmclnt_prepare_block(host, fl); | 510 | block = nlmclnt_prepare_block(host, fl); |
511 | again: | ||
511 | for(;;) { | 512 | for(;;) { |
513 | /* Reboot protection */ | ||
514 | fl->fl_u.nfs_fl.state = host->h_state; | ||
512 | status = nlmclnt_call(req, NLMPROC_LOCK); | 515 | status = nlmclnt_call(req, NLMPROC_LOCK); |
513 | if (status < 0) | 516 | if (status < 0) |
514 | goto out_unblock; | 517 | goto out_unblock; |
@@ -531,10 +534,16 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) | |||
531 | } | 534 | } |
532 | 535 | ||
533 | if (resp->status == NLM_LCK_GRANTED) { | 536 | if (resp->status == NLM_LCK_GRANTED) { |
534 | fl->fl_u.nfs_fl.state = host->h_state; | 537 | down_read(&host->h_rwsem); |
538 | /* Check whether or not the server has rebooted */ | ||
539 | if (fl->fl_u.nfs_fl.state != host->h_state) { | ||
540 | up_read(&host->h_rwsem); | ||
541 | goto again; | ||
542 | } | ||
535 | fl->fl_flags |= FL_SLEEP; | 543 | fl->fl_flags |= FL_SLEEP; |
536 | /* Ensure the resulting lock will get added to granted list */ | 544 | /* Ensure the resulting lock will get added to granted list */ |
537 | do_vfs_lock(fl); | 545 | do_vfs_lock(fl); |
546 | up_read(&host->h_rwsem); | ||
538 | } | 547 | } |
539 | status = nlm_stat_to_errno(resp->status); | 548 | status = nlm_stat_to_errno(resp->status); |
540 | out_unblock: | 549 | out_unblock: |
@@ -596,6 +605,7 @@ nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl) | |||
596 | static int | 605 | static int |
597 | nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | 606 | nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) |
598 | { | 607 | { |
608 | struct nlm_host *host = req->a_host; | ||
599 | struct nlm_res *resp = &req->a_res; | 609 | struct nlm_res *resp = &req->a_res; |
600 | int status; | 610 | int status; |
601 | 611 | ||
@@ -604,7 +614,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | |||
604 | * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either | 614 | * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either |
605 | * case, we want to unlock. | 615 | * case, we want to unlock. |
606 | */ | 616 | */ |
617 | down_read(&host->h_rwsem); | ||
607 | do_vfs_lock(fl); | 618 | do_vfs_lock(fl); |
619 | up_read(&host->h_rwsem); | ||
608 | 620 | ||
609 | if (req->a_flags & RPC_TASK_ASYNC) | 621 | if (req->a_flags & RPC_TASK_ASYNC) |
610 | return nlm_async_call(req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops); | 622 | return nlm_async_call(req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops); |