diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/lockd/svc4proc.c | 13 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 96 | ||||
-rw-r--r-- | fs/lockd/svcproc.c | 13 | ||||
-rw-r--r-- | fs/lockd/svcsubs.c | 2 | ||||
-rw-r--r-- | fs/lockd/xdr.c | 1 | ||||
-rw-r--r-- | fs/lockd/xdr4.c | 1 |
6 files changed, 121 insertions, 5 deletions
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 1bddf70d9656..a00134fd8956 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -46,8 +46,13 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
46 | 46 | ||
47 | /* Set up the missing parts of the file_lock structure */ | 47 | /* Set up the missing parts of the file_lock structure */ |
48 | lock->fl.fl_file = file->f_file; | 48 | lock->fl.fl_file = file->f_file; |
49 | lock->fl.fl_owner = (fl_owner_t) host; | ||
50 | lock->fl.fl_lmops = &nlmsvc_lock_operations; | 49 | lock->fl.fl_lmops = &nlmsvc_lock_operations; |
50 | nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); | ||
51 | if (!lock->fl.fl_owner) { | ||
52 | /* lockowner allocation has failed */ | ||
53 | nlmsvc_release_host(host); | ||
54 | return nlm_lck_denied_nolocks; | ||
55 | } | ||
51 | } | 56 | } |
52 | 57 | ||
53 | return 0; | 58 | return 0; |
@@ -94,6 +99,7 @@ __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
94 | else | 99 | else |
95 | dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); | 100 | dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); |
96 | 101 | ||
102 | nlmsvc_release_lockowner(&argp->lock); | ||
97 | nlmsvc_release_host(host); | 103 | nlmsvc_release_host(host); |
98 | nlm_release_file(file); | 104 | nlm_release_file(file); |
99 | return rc; | 105 | return rc; |
@@ -142,6 +148,7 @@ __nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
142 | else | 148 | else |
143 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | 149 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); |
144 | 150 | ||
151 | nlmsvc_release_lockowner(&argp->lock); | ||
145 | nlmsvc_release_host(host); | 152 | nlmsvc_release_host(host); |
146 | nlm_release_file(file); | 153 | nlm_release_file(file); |
147 | return rc; | 154 | return rc; |
@@ -178,6 +185,7 @@ __nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
178 | resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock); | 185 | resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock); |
179 | 186 | ||
180 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 187 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
188 | nlmsvc_release_lockowner(&argp->lock); | ||
181 | nlmsvc_release_host(host); | 189 | nlmsvc_release_host(host); |
182 | nlm_release_file(file); | 190 | nlm_release_file(file); |
183 | return rpc_success; | 191 | return rpc_success; |
@@ -217,6 +225,7 @@ __nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
217 | resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock); | 225 | resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock); |
218 | 226 | ||
219 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 227 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
228 | nlmsvc_release_lockowner(&argp->lock); | ||
220 | nlmsvc_release_host(host); | 229 | nlmsvc_release_host(host); |
221 | nlm_release_file(file); | 230 | nlm_release_file(file); |
222 | return rpc_success; | 231 | return rpc_success; |
@@ -365,6 +374,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp) | |||
365 | resp->status = nlmsvc_share_file(host, file, argp); | 374 | resp->status = nlmsvc_share_file(host, file, argp); |
366 | 375 | ||
367 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); | 376 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); |
377 | nlmsvc_release_lockowner(&argp->lock); | ||
368 | nlmsvc_release_host(host); | 378 | nlmsvc_release_host(host); |
369 | nlm_release_file(file); | 379 | nlm_release_file(file); |
370 | return rpc_success; | 380 | return rpc_success; |
@@ -399,6 +409,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp) | |||
399 | resp->status = nlmsvc_unshare_file(host, file, argp); | 409 | resp->status = nlmsvc_unshare_file(host, file, argp); |
400 | 410 | ||
401 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); | 411 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); |
412 | nlmsvc_release_lockowner(&argp->lock); | ||
402 | nlmsvc_release_host(host); | 413 | nlmsvc_release_host(host); |
403 | nlm_release_file(file); | 414 | nlm_release_file(file); |
404 | return rpc_success; | 415 | return rpc_success; |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index ea719cdd6a36..34c6ee85274e 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -332,6 +332,93 @@ restart: | |||
332 | mutex_unlock(&file->f_mutex); | 332 | mutex_unlock(&file->f_mutex); |
333 | } | 333 | } |
334 | 334 | ||
335 | static struct nlm_lockowner * | ||
336 | nlmsvc_get_lockowner(struct nlm_lockowner *lockowner) | ||
337 | { | ||
338 | refcount_inc(&lockowner->count); | ||
339 | return lockowner; | ||
340 | } | ||
341 | |||
342 | static void nlmsvc_put_lockowner(struct nlm_lockowner *lockowner) | ||
343 | { | ||
344 | if (!refcount_dec_and_lock(&lockowner->count, &lockowner->host->h_lock)) | ||
345 | return; | ||
346 | list_del(&lockowner->list); | ||
347 | spin_unlock(&lockowner->host->h_lock); | ||
348 | nlmsvc_release_host(lockowner->host); | ||
349 | kfree(lockowner); | ||
350 | } | ||
351 | |||
352 | static struct nlm_lockowner *__nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid) | ||
353 | { | ||
354 | struct nlm_lockowner *lockowner; | ||
355 | list_for_each_entry(lockowner, &host->h_lockowners, list) { | ||
356 | if (lockowner->pid != pid) | ||
357 | continue; | ||
358 | return nlmsvc_get_lockowner(lockowner); | ||
359 | } | ||
360 | return NULL; | ||
361 | } | ||
362 | |||
363 | static struct nlm_lockowner *nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid) | ||
364 | { | ||
365 | struct nlm_lockowner *res, *new = NULL; | ||
366 | |||
367 | spin_lock(&host->h_lock); | ||
368 | res = __nlmsvc_find_lockowner(host, pid); | ||
369 | |||
370 | if (res == NULL) { | ||
371 | spin_unlock(&host->h_lock); | ||
372 | new = kmalloc(sizeof(*res), GFP_KERNEL); | ||
373 | spin_lock(&host->h_lock); | ||
374 | res = __nlmsvc_find_lockowner(host, pid); | ||
375 | if (res == NULL && new != NULL) { | ||
376 | res = new; | ||
377 | /* fs/locks.c will manage the refcount through lock_ops */ | ||
378 | refcount_set(&new->count, 1); | ||
379 | new->pid = pid; | ||
380 | new->host = nlm_get_host(host); | ||
381 | list_add(&new->list, &host->h_lockowners); | ||
382 | new = NULL; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | spin_unlock(&host->h_lock); | ||
387 | kfree(new); | ||
388 | return res; | ||
389 | } | ||
390 | |||
391 | void | ||
392 | nlmsvc_release_lockowner(struct nlm_lock *lock) | ||
393 | { | ||
394 | if (lock->fl.fl_owner) | ||
395 | nlmsvc_put_lockowner(lock->fl.fl_owner); | ||
396 | } | ||
397 | |||
398 | static void nlmsvc_locks_copy_lock(struct file_lock *new, struct file_lock *fl) | ||
399 | { | ||
400 | struct nlm_lockowner *nlm_lo = (struct nlm_lockowner *)fl->fl_owner; | ||
401 | new->fl_owner = nlmsvc_get_lockowner(nlm_lo); | ||
402 | } | ||
403 | |||
404 | static void nlmsvc_locks_release_private(struct file_lock *fl) | ||
405 | { | ||
406 | nlmsvc_put_lockowner((struct nlm_lockowner *)fl->fl_owner); | ||
407 | } | ||
408 | |||
409 | const struct file_lock_operations nlmsvc_lock_ops = { | ||
410 | .fl_copy_lock = nlmsvc_locks_copy_lock, | ||
411 | .fl_release_private = nlmsvc_locks_release_private, | ||
412 | }; | ||
413 | |||
414 | void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host, | ||
415 | pid_t pid) | ||
416 | { | ||
417 | fl->fl_owner = nlmsvc_find_lockowner(host, pid); | ||
418 | if (fl->fl_owner != NULL) | ||
419 | fl->fl_ops = &nlmsvc_lock_ops; | ||
420 | } | ||
421 | |||
335 | /* | 422 | /* |
336 | * Initialize arguments for GRANTED call. The nlm_rqst structure | 423 | * Initialize arguments for GRANTED call. The nlm_rqst structure |
337 | * has been cleared already. | 424 | * has been cleared already. |
@@ -509,6 +596,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
509 | { | 596 | { |
510 | int error; | 597 | int error; |
511 | __be32 ret; | 598 | __be32 ret; |
599 | struct nlm_lockowner *test_owner; | ||
512 | 600 | ||
513 | dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", | 601 | dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", |
514 | locks_inode(file->f_file)->i_sb->s_id, | 602 | locks_inode(file->f_file)->i_sb->s_id, |
@@ -522,6 +610,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
522 | goto out; | 610 | goto out; |
523 | } | 611 | } |
524 | 612 | ||
613 | /* If there's a conflicting lock, remember to clean up the test lock */ | ||
614 | test_owner = (struct nlm_lockowner *)lock->fl.fl_owner; | ||
615 | |||
525 | error = vfs_test_lock(file->f_file, &lock->fl); | 616 | error = vfs_test_lock(file->f_file, &lock->fl); |
526 | if (error) { | 617 | if (error) { |
527 | /* We can't currently deal with deferred test requests */ | 618 | /* We can't currently deal with deferred test requests */ |
@@ -548,6 +639,11 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
548 | conflock->fl.fl_start = lock->fl.fl_start; | 639 | conflock->fl.fl_start = lock->fl.fl_start; |
549 | conflock->fl.fl_end = lock->fl.fl_end; | 640 | conflock->fl.fl_end = lock->fl.fl_end; |
550 | locks_release_private(&lock->fl); | 641 | locks_release_private(&lock->fl); |
642 | |||
643 | /* Clean up the test lock */ | ||
644 | lock->fl.fl_owner = NULL; | ||
645 | nlmsvc_put_lockowner(test_owner); | ||
646 | |||
551 | ret = nlm_lck_denied; | 647 | ret = nlm_lck_denied; |
552 | out: | 648 | out: |
553 | return ret; | 649 | return ret; |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index ea77c66d3cc3..36245ab43ae3 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -76,8 +76,13 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
76 | 76 | ||
77 | /* Set up the missing parts of the file_lock structure */ | 77 | /* Set up the missing parts of the file_lock structure */ |
78 | lock->fl.fl_file = file->f_file; | 78 | lock->fl.fl_file = file->f_file; |
79 | lock->fl.fl_owner = (fl_owner_t) host; | ||
80 | lock->fl.fl_lmops = &nlmsvc_lock_operations; | 79 | lock->fl.fl_lmops = &nlmsvc_lock_operations; |
80 | nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); | ||
81 | if (!lock->fl.fl_owner) { | ||
82 | /* lockowner allocation has failed */ | ||
83 | nlmsvc_release_host(host); | ||
84 | return nlm_lck_denied_nolocks; | ||
85 | } | ||
81 | } | 86 | } |
82 | 87 | ||
83 | return 0; | 88 | return 0; |
@@ -125,6 +130,7 @@ __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
125 | dprintk("lockd: TEST status %d vers %d\n", | 130 | dprintk("lockd: TEST status %d vers %d\n", |
126 | ntohl(resp->status), rqstp->rq_vers); | 131 | ntohl(resp->status), rqstp->rq_vers); |
127 | 132 | ||
133 | nlmsvc_release_lockowner(&argp->lock); | ||
128 | nlmsvc_release_host(host); | 134 | nlmsvc_release_host(host); |
129 | nlm_release_file(file); | 135 | nlm_release_file(file); |
130 | return rc; | 136 | return rc; |
@@ -173,6 +179,7 @@ __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
173 | else | 179 | else |
174 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | 180 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); |
175 | 181 | ||
182 | nlmsvc_release_lockowner(&argp->lock); | ||
176 | nlmsvc_release_host(host); | 183 | nlmsvc_release_host(host); |
177 | nlm_release_file(file); | 184 | nlm_release_file(file); |
178 | return rc; | 185 | return rc; |
@@ -210,6 +217,7 @@ __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
210 | resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); | 217 | resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); |
211 | 218 | ||
212 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 219 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
220 | nlmsvc_release_lockowner(&argp->lock); | ||
213 | nlmsvc_release_host(host); | 221 | nlmsvc_release_host(host); |
214 | nlm_release_file(file); | 222 | nlm_release_file(file); |
215 | return rpc_success; | 223 | return rpc_success; |
@@ -250,6 +258,7 @@ __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) | |||
250 | resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); | 258 | resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); |
251 | 259 | ||
252 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 260 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
261 | nlmsvc_release_lockowner(&argp->lock); | ||
253 | nlmsvc_release_host(host); | 262 | nlmsvc_release_host(host); |
254 | nlm_release_file(file); | 263 | nlm_release_file(file); |
255 | return rpc_success; | 264 | return rpc_success; |
@@ -408,6 +417,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp) | |||
408 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); | 417 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); |
409 | 418 | ||
410 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); | 419 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); |
420 | nlmsvc_release_lockowner(&argp->lock); | ||
411 | nlmsvc_release_host(host); | 421 | nlmsvc_release_host(host); |
412 | nlm_release_file(file); | 422 | nlm_release_file(file); |
413 | return rpc_success; | 423 | return rpc_success; |
@@ -442,6 +452,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp) | |||
442 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); | 452 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); |
443 | 453 | ||
444 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); | 454 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); |
455 | nlmsvc_release_lockowner(&argp->lock); | ||
445 | nlmsvc_release_host(host); | 456 | nlmsvc_release_host(host); |
446 | nlm_release_file(file); | 457 | nlm_release_file(file); |
447 | return rpc_success; | 458 | return rpc_success; |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 0e610f422406..028fc152da22 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -180,7 +180,7 @@ again: | |||
180 | /* update current lock count */ | 180 | /* update current lock count */ |
181 | file->f_locks++; | 181 | file->f_locks++; |
182 | 182 | ||
183 | lockhost = (struct nlm_host *) fl->fl_owner; | 183 | lockhost = ((struct nlm_lockowner *)fl->fl_owner)->host; |
184 | if (match(lockhost, host)) { | 184 | if (match(lockhost, host)) { |
185 | struct file_lock lock = *fl; | 185 | struct file_lock lock = *fl; |
186 | 186 | ||
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 7147e4aebecc..ec717ae41ee3 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c | |||
@@ -126,7 +126,6 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock) | |||
126 | lock->svid = ntohl(*p++); | 126 | lock->svid = ntohl(*p++); |
127 | 127 | ||
128 | locks_init_lock(fl); | 128 | locks_init_lock(fl); |
129 | fl->fl_owner = current->files; | ||
130 | fl->fl_pid = (pid_t)lock->svid; | 129 | fl->fl_pid = (pid_t)lock->svid; |
131 | fl->fl_flags = FL_POSIX; | 130 | fl->fl_flags = FL_POSIX; |
132 | fl->fl_type = F_RDLCK; /* as good as anything else */ | 131 | fl->fl_type = F_RDLCK; /* as good as anything else */ |
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index 7ed9edf9aed4..45741adfe041 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c | |||
@@ -118,7 +118,6 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock) | |||
118 | lock->svid = ntohl(*p++); | 118 | lock->svid = ntohl(*p++); |
119 | 119 | ||
120 | locks_init_lock(fl); | 120 | locks_init_lock(fl); |
121 | fl->fl_owner = current->files; | ||
122 | fl->fl_pid = (pid_t)lock->svid; | 121 | fl->fl_pid = (pid_t)lock->svid; |
123 | fl->fl_flags = FL_POSIX; | 122 | fl->fl_flags = FL_POSIX; |
124 | fl->fl_type = F_RDLCK; /* as good as anything else */ | 123 | fl->fl_type = F_RDLCK; /* as good as anything else */ |