diff options
author | Oleg Drokin <Oleg.Drokin@Sun.COM> | 2007-11-29 14:02:21 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-02-01 16:42:06 -0500 |
commit | 29dbf546159f5701e11de26fa2da5c4a962e0f83 (patch) | |
tree | 1dcdd1785445cbbf30a159a15b7b1d77f42c51c2 /fs/lockd | |
parent | 406a7ea97d9dc1a9348ba92c4cd0e7c678185c4c (diff) |
lockd: fix a leak in nlmsvc_testlock asynchronous request handling
Without the patch, there is a leakage of nlmblock structure refcount
that holds a reference nlmfile structure, that holds a reference to
struct file, when async GETFL is used (-EINPROGRESS return from
file_ops->lock()), and also in some error cases.
Fix up a style nit while we're here.
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/svclock.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index d120ec39bcb0..84c4d5e04ebb 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -501,25 +501,29 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
501 | block, block->b_flags, block->b_fl); | 501 | block, block->b_flags, block->b_fl); |
502 | if (block->b_flags & B_TIMED_OUT) { | 502 | if (block->b_flags & B_TIMED_OUT) { |
503 | nlmsvc_unlink_block(block); | 503 | nlmsvc_unlink_block(block); |
504 | return nlm_lck_denied; | 504 | ret = nlm_lck_denied; |
505 | goto out; | ||
505 | } | 506 | } |
506 | if (block->b_flags & B_GOT_CALLBACK) { | 507 | if (block->b_flags & B_GOT_CALLBACK) { |
507 | if (block->b_fl != NULL | 508 | if (block->b_fl != NULL |
508 | && block->b_fl->fl_type != F_UNLCK) { | 509 | && block->b_fl->fl_type != F_UNLCK) { |
509 | lock->fl = *block->b_fl; | 510 | lock->fl = *block->b_fl; |
510 | goto conf_lock; | 511 | goto conf_lock; |
511 | } | 512 | } else { |
512 | else { | ||
513 | nlmsvc_unlink_block(block); | 513 | nlmsvc_unlink_block(block); |
514 | return nlm_granted; | 514 | ret = nlm_granted; |
515 | goto out; | ||
515 | } | 516 | } |
516 | } | 517 | } |
517 | return nlm_drop_reply; | 518 | ret = nlm_drop_reply; |
519 | goto out; | ||
518 | } | 520 | } |
519 | 521 | ||
520 | error = vfs_test_lock(file->f_file, &lock->fl); | 522 | error = vfs_test_lock(file->f_file, &lock->fl); |
521 | if (error == -EINPROGRESS) | 523 | if (error == -EINPROGRESS) { |
522 | return nlmsvc_defer_lock_rqst(rqstp, block); | 524 | ret = nlmsvc_defer_lock_rqst(rqstp, block); |
525 | goto out; | ||
526 | } | ||
523 | if (error) { | 527 | if (error) { |
524 | ret = nlm_lck_denied_nolocks; | 528 | ret = nlm_lck_denied_nolocks; |
525 | goto out; | 529 | goto out; |