diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:45 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:45 -0500 |
commit | 92737230dd3f1478033819d4bc20339f8da852da (patch) | |
tree | 27bc7804a077a29b7614c698bb02632dc4ce228e /fs/lockd/svclock.c | |
parent | e4cd038a45a46ffbe06a1a72f3f15246e5b041ca (diff) |
NLM: Add nlmclnt_release_call
Add a helper function to simplify the freeing of NLM client requests.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/lockd/svclock.c')
-rw-r--r-- | fs/lockd/svclock.c | 66 |
1 files changed, 28 insertions, 38 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index a95d260b7137..185bf7ea1c0c 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -117,12 +117,12 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) | |||
117 | (long long)lock->fl.fl_start, | 117 | (long long)lock->fl.fl_start, |
118 | (long long)lock->fl.fl_end, lock->fl.fl_type); | 118 | (long long)lock->fl.fl_end, lock->fl.fl_type); |
119 | for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) { | 119 | for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) { |
120 | fl = &block->b_call.a_args.lock.fl; | 120 | fl = &block->b_call->a_args.lock.fl; |
121 | dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n", | 121 | dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n", |
122 | block->b_file, fl->fl_pid, | 122 | block->b_file, fl->fl_pid, |
123 | (long long)fl->fl_start, | 123 | (long long)fl->fl_start, |
124 | (long long)fl->fl_end, fl->fl_type, | 124 | (long long)fl->fl_end, fl->fl_type, |
125 | nlmdbg_cookie2a(&block->b_call.a_args.cookie)); | 125 | nlmdbg_cookie2a(&block->b_call->a_args.cookie)); |
126 | if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { | 126 | if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { |
127 | if (remove) { | 127 | if (remove) { |
128 | *head = block->b_next; | 128 | *head = block->b_next; |
@@ -156,7 +156,7 @@ nlmsvc_find_block(struct nlm_cookie *cookie, struct sockaddr_in *sin) | |||
156 | for (block = nlm_blocked; block; block = block->b_next) { | 156 | for (block = nlm_blocked; block; block = block->b_next) { |
157 | dprintk("cookie: head of blocked queue %p, block %p\n", | 157 | dprintk("cookie: head of blocked queue %p, block %p\n", |
158 | nlm_blocked, block); | 158 | nlm_blocked, block); |
159 | if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie) | 159 | if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie) |
160 | && nlm_cmp_addr(sin, &block->b_host->h_addr)) | 160 | && nlm_cmp_addr(sin, &block->b_host->h_addr)) |
161 | break; | 161 | break; |
162 | } | 162 | } |
@@ -182,28 +182,30 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, | |||
182 | { | 182 | { |
183 | struct nlm_block *block; | 183 | struct nlm_block *block; |
184 | struct nlm_host *host; | 184 | struct nlm_host *host; |
185 | struct nlm_rqst *call; | 185 | struct nlm_rqst *call = NULL; |
186 | 186 | ||
187 | /* Create host handle for callback */ | 187 | /* Create host handle for callback */ |
188 | host = nlmsvc_lookup_host(rqstp); | 188 | host = nlmsvc_lookup_host(rqstp); |
189 | if (host == NULL) | 189 | if (host == NULL) |
190 | return NULL; | 190 | return NULL; |
191 | 191 | ||
192 | call = nlm_alloc_call(host); | ||
193 | if (call == NULL) | ||
194 | return NULL; | ||
195 | |||
192 | /* Allocate memory for block, and initialize arguments */ | 196 | /* Allocate memory for block, and initialize arguments */ |
193 | if (!(block = (struct nlm_block *) kmalloc(sizeof(*block), GFP_KERNEL))) | 197 | block = kzalloc(sizeof(*block), GFP_KERNEL); |
198 | if (block == NULL) | ||
194 | goto failed; | 199 | goto failed; |
195 | memset(block, 0, sizeof(*block)); | ||
196 | locks_init_lock(&block->b_call.a_args.lock.fl); | ||
197 | locks_init_lock(&block->b_call.a_res.lock.fl); | ||
198 | kref_init(&block->b_count); | 200 | kref_init(&block->b_count); |
199 | 201 | ||
200 | if (!nlmsvc_setgrantargs(&block->b_call, lock)) | 202 | if (!nlmsvc_setgrantargs(call, lock)) |
201 | goto failed_free; | 203 | goto failed_free; |
202 | 204 | ||
203 | /* Set notifier function for VFS, and init args */ | 205 | /* Set notifier function for VFS, and init args */ |
204 | block->b_call.a_args.lock.fl.fl_flags |= FL_SLEEP; | 206 | call->a_args.lock.fl.fl_flags |= FL_SLEEP; |
205 | block->b_call.a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations; | 207 | call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations; |
206 | block->b_call.a_args.cookie = *cookie; /* see above */ | 208 | call->a_args.cookie = *cookie; /* see above */ |
207 | 209 | ||
208 | dprintk("lockd: created block %p...\n", block); | 210 | dprintk("lockd: created block %p...\n", block); |
209 | 211 | ||
@@ -217,16 +219,16 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, | |||
217 | file->f_blocks = block; | 219 | file->f_blocks = block; |
218 | 220 | ||
219 | /* Set up RPC arguments for callback */ | 221 | /* Set up RPC arguments for callback */ |
220 | call = &block->b_call; | 222 | block->b_call = call; |
221 | call->a_host = host; | ||
222 | call->a_flags = RPC_TASK_ASYNC; | 223 | call->a_flags = RPC_TASK_ASYNC; |
224 | call->a_block = block; | ||
223 | 225 | ||
224 | return block; | 226 | return block; |
225 | 227 | ||
226 | failed_free: | 228 | failed_free: |
227 | kfree(block); | 229 | kfree(block); |
228 | failed: | 230 | failed: |
229 | nlm_release_host(host); | 231 | nlm_release_call(call); |
230 | return NULL; | 232 | return NULL; |
231 | } | 233 | } |
232 | 234 | ||
@@ -242,7 +244,7 @@ static int nlmsvc_unlink_block(struct nlm_block *block) | |||
242 | dprintk("lockd: unlinking block %p...\n", block); | 244 | dprintk("lockd: unlinking block %p...\n", block); |
243 | 245 | ||
244 | /* Remove block from list */ | 246 | /* Remove block from list */ |
245 | status = posix_unblock_lock(block->b_file->f_file, &block->b_call.a_args.lock.fl); | 247 | status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); |
246 | nlmsvc_remove_block(block); | 248 | nlmsvc_remove_block(block); |
247 | return status; | 249 | return status; |
248 | } | 250 | } |
@@ -263,9 +265,8 @@ static void nlmsvc_free_block(struct kref *kref) | |||
263 | } | 265 | } |
264 | } | 266 | } |
265 | 267 | ||
266 | if (block->b_host) | 268 | nlmsvc_freegrantargs(block->b_call); |
267 | nlm_release_host(block->b_host); | 269 | nlm_release_call(block->b_call); |
268 | nlmsvc_freegrantargs(&block->b_call); | ||
269 | kfree(block); | 270 | kfree(block); |
270 | } | 271 | } |
271 | 272 | ||
@@ -316,10 +317,8 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) | |||
316 | 317 | ||
317 | if (lock->oh.len > NLMCLNT_OHSIZE) { | 318 | if (lock->oh.len > NLMCLNT_OHSIZE) { |
318 | void *data = kmalloc(lock->oh.len, GFP_KERNEL); | 319 | void *data = kmalloc(lock->oh.len, GFP_KERNEL); |
319 | if (!data) { | 320 | if (!data) |
320 | nlmsvc_freegrantargs(call); | ||
321 | return 0; | 321 | return 0; |
322 | } | ||
323 | call->a_args.lock.oh.data = (u8 *) data; | 322 | call->a_args.lock.oh.data = (u8 *) data; |
324 | } | 323 | } |
325 | 324 | ||
@@ -329,17 +328,8 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) | |||
329 | 328 | ||
330 | static void nlmsvc_freegrantargs(struct nlm_rqst *call) | 329 | static void nlmsvc_freegrantargs(struct nlm_rqst *call) |
331 | { | 330 | { |
332 | struct file_lock *fl = &call->a_args.lock.fl; | 331 | if (call->a_args.lock.oh.data != call->a_owner) |
333 | /* | ||
334 | * Check whether we allocated memory for the owner. | ||
335 | */ | ||
336 | if (call->a_args.lock.oh.data != (u8 *) call->a_owner) { | ||
337 | kfree(call->a_args.lock.oh.data); | 332 | kfree(call->a_args.lock.oh.data); |
338 | } | ||
339 | if (fl->fl_ops && fl->fl_ops->fl_release_private) | ||
340 | fl->fl_ops->fl_release_private(fl); | ||
341 | if (fl->fl_lmops && fl->fl_lmops->fl_release_private) | ||
342 | fl->fl_lmops->fl_release_private(fl); | ||
343 | } | 333 | } |
344 | 334 | ||
345 | /* | 335 | /* |
@@ -371,9 +361,9 @@ again: | |||
371 | block = nlmsvc_lookup_block(file, lock, 0); | 361 | block = nlmsvc_lookup_block(file, lock, 0); |
372 | if (block == NULL) { | 362 | if (block == NULL) { |
373 | if (newblock != NULL) | 363 | if (newblock != NULL) |
374 | lock = &newblock->b_call.a_args.lock; | 364 | lock = &newblock->b_call->a_args.lock; |
375 | } else | 365 | } else |
376 | lock = &block->b_call.a_args.lock; | 366 | lock = &block->b_call->a_args.lock; |
377 | 367 | ||
378 | error = posix_lock_file(file->f_file, &lock->fl); | 368 | error = posix_lock_file(file->f_file, &lock->fl); |
379 | lock->fl.fl_flags &= ~FL_SLEEP; | 369 | lock->fl.fl_flags &= ~FL_SLEEP; |
@@ -523,7 +513,7 @@ nlmsvc_notify_blocked(struct file_lock *fl) | |||
523 | 513 | ||
524 | dprintk("lockd: VFS unblock notification for block %p\n", fl); | 514 | dprintk("lockd: VFS unblock notification for block %p\n", fl); |
525 | for (bp = &nlm_blocked; (block = *bp) != 0; bp = &block->b_next) { | 515 | for (bp = &nlm_blocked; (block = *bp) != 0; bp = &block->b_next) { |
526 | if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) { | 516 | if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { |
527 | nlmsvc_insert_block(block, 0); | 517 | nlmsvc_insert_block(block, 0); |
528 | svc_wake_up(block->b_daemon); | 518 | svc_wake_up(block->b_daemon); |
529 | return; | 519 | return; |
@@ -558,7 +548,7 @@ static void | |||
558 | nlmsvc_grant_blocked(struct nlm_block *block) | 548 | nlmsvc_grant_blocked(struct nlm_block *block) |
559 | { | 549 | { |
560 | struct nlm_file *file = block->b_file; | 550 | struct nlm_file *file = block->b_file; |
561 | struct nlm_lock *lock = &block->b_call.a_args.lock; | 551 | struct nlm_lock *lock = &block->b_call->a_args.lock; |
562 | int error; | 552 | int error; |
563 | 553 | ||
564 | dprintk("lockd: grant blocked lock %p\n", block); | 554 | dprintk("lockd: grant blocked lock %p\n", block); |
@@ -606,7 +596,7 @@ callback: | |||
606 | 596 | ||
607 | /* Call the client */ | 597 | /* Call the client */ |
608 | kref_get(&block->b_count); | 598 | kref_get(&block->b_count); |
609 | if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG, | 599 | if (nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, |
610 | &nlmsvc_grant_ops) < 0) | 600 | &nlmsvc_grant_ops) < 0) |
611 | nlmsvc_release_block(block); | 601 | nlmsvc_release_block(block); |
612 | out_unlock: | 602 | out_unlock: |
@@ -624,7 +614,7 @@ out_unlock: | |||
624 | static void nlmsvc_grant_callback(struct rpc_task *task, void *data) | 614 | static void nlmsvc_grant_callback(struct rpc_task *task, void *data) |
625 | { | 615 | { |
626 | struct nlm_rqst *call = data; | 616 | struct nlm_rqst *call = data; |
627 | struct nlm_block *block = container_of(call, struct nlm_block, b_call); | 617 | struct nlm_block *block = call->a_block; |
628 | unsigned long timeout; | 618 | unsigned long timeout; |
629 | 619 | ||
630 | dprintk("lockd: GRANT_MSG RPC callback\n"); | 620 | dprintk("lockd: GRANT_MSG RPC callback\n"); |