diff options
author | Oleg Drokin <green@linuxhacker.ru> | 2007-11-26 13:35:11 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-02-01 16:42:06 -0500 |
commit | b7e6b86948df8d08d420558212e09eb449be9bfa (patch) | |
tree | b9bce0e95a93a6b9142b55c647fb0fbe163a2130 /fs/lockd/svcproc.c | |
parent | 404ec117be5d36e1a4c4582d0c518594333e32df (diff) |
lockd: fix reference count leaks in async locking case
In a number of places where we wish only to translate nlm_drop_reply to
rpc_drop_reply errors we instead return early with rpc_drop_reply,
skipping some important end-of-function cleanup.
This results in reference count leaks when lockd is doing posix locking
on GFS2.
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/lockd/svcproc.c')
-rw-r--r-- | fs/lockd/svcproc.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 9cd5c8b37593..88379cc6e0b1 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -113,6 +113,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
113 | { | 113 | { |
114 | struct nlm_host *host; | 114 | struct nlm_host *host; |
115 | struct nlm_file *file; | 115 | struct nlm_file *file; |
116 | int rc = rpc_success; | ||
116 | 117 | ||
117 | dprintk("lockd: TEST called\n"); | 118 | dprintk("lockd: TEST called\n"); |
118 | resp->cookie = argp->cookie; | 119 | resp->cookie = argp->cookie; |
@@ -120,7 +121,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
120 | /* Don't accept test requests during grace period */ | 121 | /* Don't accept test requests during grace period */ |
121 | if (nlmsvc_grace_period) { | 122 | if (nlmsvc_grace_period) { |
122 | resp->status = nlm_lck_denied_grace_period; | 123 | resp->status = nlm_lck_denied_grace_period; |
123 | return rpc_success; | 124 | return rc; |
124 | } | 125 | } |
125 | 126 | ||
126 | /* Obtain client and file */ | 127 | /* Obtain client and file */ |
@@ -130,13 +131,14 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
130 | /* Now check for conflicting locks */ | 131 | /* Now check for conflicting locks */ |
131 | resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie)); | 132 | resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie)); |
132 | if (resp->status == nlm_drop_reply) | 133 | if (resp->status == nlm_drop_reply) |
133 | return rpc_drop_reply; | 134 | rc = rpc_drop_reply; |
135 | else | ||
136 | dprintk("lockd: TEST status %d vers %d\n", | ||
137 | ntohl(resp->status), rqstp->rq_vers); | ||
134 | 138 | ||
135 | dprintk("lockd: TEST status %d vers %d\n", | ||
136 | ntohl(resp->status), rqstp->rq_vers); | ||
137 | nlm_release_host(host); | 139 | nlm_release_host(host); |
138 | nlm_release_file(file); | 140 | nlm_release_file(file); |
139 | return rpc_success; | 141 | return rc; |
140 | } | 142 | } |
141 | 143 | ||
142 | static __be32 | 144 | static __be32 |
@@ -145,6 +147,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
145 | { | 147 | { |
146 | struct nlm_host *host; | 148 | struct nlm_host *host; |
147 | struct nlm_file *file; | 149 | struct nlm_file *file; |
150 | int rc = rpc_success; | ||
148 | 151 | ||
149 | dprintk("lockd: LOCK called\n"); | 152 | dprintk("lockd: LOCK called\n"); |
150 | 153 | ||
@@ -153,7 +156,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
153 | /* Don't accept new lock requests during grace period */ | 156 | /* Don't accept new lock requests during grace period */ |
154 | if (nlmsvc_grace_period && !argp->reclaim) { | 157 | if (nlmsvc_grace_period && !argp->reclaim) { |
155 | resp->status = nlm_lck_denied_grace_period; | 158 | resp->status = nlm_lck_denied_grace_period; |
156 | return rpc_success; | 159 | return rc; |
157 | } | 160 | } |
158 | 161 | ||
159 | /* Obtain client and file */ | 162 | /* Obtain client and file */ |
@@ -176,12 +179,13 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
176 | resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock, | 179 | resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock, |
177 | argp->block, &argp->cookie)); | 180 | argp->block, &argp->cookie)); |
178 | if (resp->status == nlm_drop_reply) | 181 | if (resp->status == nlm_drop_reply) |
179 | return rpc_drop_reply; | 182 | rc = rpc_drop_reply; |
183 | else | ||
184 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | ||
180 | 185 | ||
181 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | ||
182 | nlm_release_host(host); | 186 | nlm_release_host(host); |
183 | nlm_release_file(file); | 187 | nlm_release_file(file); |
184 | return rpc_success; | 188 | return rc; |
185 | } | 189 | } |
186 | 190 | ||
187 | static __be32 | 191 | static __be32 |