aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svclock.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:45 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:45 -0500
commit92737230dd3f1478033819d4bc20339f8da852da (patch)
tree27bc7804a077a29b7614c698bb02632dc4ce228e /fs/lockd/svclock.c
parente4cd038a45a46ffbe06a1a72f3f15246e5b041ca (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.c66
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
226failed_free: 228failed_free:
227 kfree(block); 229 kfree(block);
228failed: 230failed:
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
330static void nlmsvc_freegrantargs(struct nlm_rqst *call) 329static 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
558nlmsvc_grant_blocked(struct nlm_block *block) 548nlmsvc_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);
612out_unlock: 602out_unlock:
@@ -624,7 +614,7 @@ out_unlock:
624static void nlmsvc_grant_callback(struct rpc_task *task, void *data) 614static 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");