diff options
Diffstat (limited to 'fs/lockd/clntlock.c')
-rw-r--r-- | fs/lockd/clntlock.c | 43 |
1 files changed, 16 insertions, 27 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 7cf41c1e1a88..bce744468708 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -44,32 +44,25 @@ static LIST_HEAD(nlm_blocked); | |||
44 | /* | 44 | /* |
45 | * Queue up a lock for blocking so that the GRANTED request can see it | 45 | * Queue up a lock for blocking so that the GRANTED request can see it |
46 | */ | 46 | */ |
47 | int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl) | 47 | struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl) |
48 | { | 48 | { |
49 | struct nlm_wait *block; | 49 | struct nlm_wait *block; |
50 | 50 | ||
51 | BUG_ON(req->a_block != NULL); | ||
52 | block = kmalloc(sizeof(*block), GFP_KERNEL); | 51 | block = kmalloc(sizeof(*block), GFP_KERNEL); |
53 | if (block == NULL) | 52 | if (block != NULL) { |
54 | return -ENOMEM; | 53 | block->b_host = host; |
55 | block->b_host = host; | 54 | block->b_lock = fl; |
56 | block->b_lock = fl; | 55 | init_waitqueue_head(&block->b_wait); |
57 | init_waitqueue_head(&block->b_wait); | 56 | block->b_status = NLM_LCK_BLOCKED; |
58 | block->b_status = NLM_LCK_BLOCKED; | 57 | list_add(&block->b_list, &nlm_blocked); |
59 | 58 | } | |
60 | list_add(&block->b_list, &nlm_blocked); | 59 | return block; |
61 | req->a_block = block; | ||
62 | |||
63 | return 0; | ||
64 | } | 60 | } |
65 | 61 | ||
66 | void nlmclnt_finish_block(struct nlm_rqst *req) | 62 | void nlmclnt_finish_block(struct nlm_wait *block) |
67 | { | 63 | { |
68 | struct nlm_wait *block = req->a_block; | ||
69 | |||
70 | if (block == NULL) | 64 | if (block == NULL) |
71 | return; | 65 | return; |
72 | req->a_block = NULL; | ||
73 | list_del(&block->b_list); | 66 | list_del(&block->b_list); |
74 | kfree(block); | 67 | kfree(block); |
75 | } | 68 | } |
@@ -77,15 +70,14 @@ void nlmclnt_finish_block(struct nlm_rqst *req) | |||
77 | /* | 70 | /* |
78 | * Block on a lock | 71 | * Block on a lock |
79 | */ | 72 | */ |
80 | long nlmclnt_block(struct nlm_rqst *req, long timeout) | 73 | int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) |
81 | { | 74 | { |
82 | struct nlm_wait *block = req->a_block; | ||
83 | long ret; | 75 | long ret; |
84 | 76 | ||
85 | /* A borken server might ask us to block even if we didn't | 77 | /* A borken server might ask us to block even if we didn't |
86 | * request it. Just say no! | 78 | * request it. Just say no! |
87 | */ | 79 | */ |
88 | if (!req->a_args.block) | 80 | if (block == NULL) |
89 | return -EAGAIN; | 81 | return -EAGAIN; |
90 | 82 | ||
91 | /* Go to sleep waiting for GRANT callback. Some servers seem | 83 | /* Go to sleep waiting for GRANT callback. Some servers seem |
@@ -99,13 +91,10 @@ long nlmclnt_block(struct nlm_rqst *req, long timeout) | |||
99 | ret = wait_event_interruptible_timeout(block->b_wait, | 91 | ret = wait_event_interruptible_timeout(block->b_wait, |
100 | block->b_status != NLM_LCK_BLOCKED, | 92 | block->b_status != NLM_LCK_BLOCKED, |
101 | timeout); | 93 | timeout); |
102 | 94 | if (ret < 0) | |
103 | if (block->b_status != NLM_LCK_BLOCKED) { | 95 | return -ERESTARTSYS; |
104 | req->a_res.status = block->b_status; | 96 | req->a_res.status = block->b_status; |
105 | block->b_status = NLM_LCK_BLOCKED; | 97 | return 0; |
106 | } | ||
107 | |||
108 | return ret; | ||
109 | } | 98 | } |
110 | 99 | ||
111 | /* | 100 | /* |