diff options
| -rw-r--r-- | fs/lockd/clntproc.c | 43 | ||||
| -rw-r--r-- | fs/lockd/svclock.c | 56 | ||||
| -rw-r--r-- | include/linux/lockd/lockd.h | 2 |
3 files changed, 53 insertions, 48 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index acc3eb13a0..80ae312769 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
| @@ -148,49 +148,6 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req) | |||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | /* | 150 | /* |
| 151 | * Initialize arguments for GRANTED call. The nlm_rqst structure | ||
| 152 | * has been cleared already. | ||
| 153 | */ | ||
| 154 | int | ||
| 155 | nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) | ||
| 156 | { | ||
| 157 | locks_copy_lock(&call->a_args.lock.fl, &lock->fl); | ||
| 158 | memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); | ||
| 159 | call->a_args.lock.caller = system_utsname.nodename; | ||
| 160 | call->a_args.lock.oh.len = lock->oh.len; | ||
| 161 | |||
| 162 | /* set default data area */ | ||
| 163 | call->a_args.lock.oh.data = call->a_owner; | ||
| 164 | call->a_args.lock.svid = lock->fl.fl_pid; | ||
| 165 | |||
| 166 | if (lock->oh.len > NLMCLNT_OHSIZE) { | ||
| 167 | void *data = kmalloc(lock->oh.len, GFP_KERNEL); | ||
| 168 | if (!data) { | ||
| 169 | nlmclnt_freegrantargs(call); | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | call->a_args.lock.oh.data = (u8 *) data; | ||
| 173 | } | ||
| 174 | |||
| 175 | memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len); | ||
| 176 | return 1; | ||
| 177 | } | ||
| 178 | |||
| 179 | void | ||
| 180 | nlmclnt_freegrantargs(struct nlm_rqst *call) | ||
| 181 | { | ||
| 182 | struct file_lock *fl = &call->a_args.lock.fl; | ||
| 183 | /* | ||
| 184 | * Check whether we allocated memory for the owner. | ||
| 185 | */ | ||
| 186 | if (call->a_args.lock.oh.data != (u8 *) call->a_owner) { | ||
| 187 | kfree(call->a_args.lock.oh.data); | ||
| 188 | } | ||
| 189 | if (fl->fl_ops && fl->fl_ops->fl_release_private) | ||
| 190 | fl->fl_ops->fl_release_private(fl); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* | ||
| 194 | * This is the main entry point for the NLM client. | 151 | * This is the main entry point for the NLM client. |
| 195 | */ | 152 | */ |
| 196 | int | 153 | int |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 20caeceffb..3c7dd956d9 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
| @@ -43,6 +43,8 @@ static void nlmsvc_release_block(struct nlm_block *block); | |||
| 43 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); | 43 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); |
| 44 | static int nlmsvc_remove_block(struct nlm_block *block); | 44 | static int nlmsvc_remove_block(struct nlm_block *block); |
| 45 | 45 | ||
| 46 | static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); | ||
| 47 | static void nlmsvc_freegrantargs(struct nlm_rqst *call); | ||
| 46 | static const struct rpc_call_ops nlmsvc_grant_ops; | 48 | static const struct rpc_call_ops nlmsvc_grant_ops; |
| 47 | 49 | ||
| 48 | /* | 50 | /* |
| @@ -196,7 +198,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, | |||
| 196 | locks_init_lock(&block->b_call.a_res.lock.fl); | 198 | locks_init_lock(&block->b_call.a_res.lock.fl); |
| 197 | kref_init(&block->b_count); | 199 | kref_init(&block->b_count); |
| 198 | 200 | ||
| 199 | if (!nlmclnt_setgrantargs(&block->b_call, lock)) | 201 | if (!nlmsvc_setgrantargs(&block->b_call, lock)) |
| 200 | goto failed_free; | 202 | goto failed_free; |
| 201 | 203 | ||
| 202 | /* Set notifier function for VFS, and init args */ | 204 | /* Set notifier function for VFS, and init args */ |
| @@ -264,7 +266,7 @@ static void nlmsvc_free_block(struct kref *kref) | |||
| 264 | 266 | ||
| 265 | if (block->b_host) | 267 | if (block->b_host) |
| 266 | nlm_release_host(block->b_host); | 268 | nlm_release_host(block->b_host); |
| 267 | nlmclnt_freegrantargs(&block->b_call); | 269 | nlmsvc_freegrantargs(&block->b_call); |
| 268 | kfree(block); | 270 | kfree(block); |
| 269 | } | 271 | } |
| 270 | 272 | ||
| @@ -299,6 +301,49 @@ nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) | |||
| 299 | } | 301 | } |
| 300 | 302 | ||
| 301 | /* | 303 | /* |
| 304 | * Initialize arguments for GRANTED call. The nlm_rqst structure | ||
| 305 | * has been cleared already. | ||
| 306 | */ | ||
| 307 | static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) | ||
| 308 | { | ||
| 309 | locks_copy_lock(&call->a_args.lock.fl, &lock->fl); | ||
| 310 | memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); | ||
| 311 | call->a_args.lock.caller = system_utsname.nodename; | ||
| 312 | call->a_args.lock.oh.len = lock->oh.len; | ||
| 313 | |||
| 314 | /* set default data area */ | ||
| 315 | call->a_args.lock.oh.data = call->a_owner; | ||
| 316 | call->a_args.lock.svid = lock->fl.fl_pid; | ||
| 317 | |||
| 318 | if (lock->oh.len > NLMCLNT_OHSIZE) { | ||
| 319 | void *data = kmalloc(lock->oh.len, GFP_KERNEL); | ||
| 320 | if (!data) { | ||
| 321 | nlmsvc_freegrantargs(call); | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | call->a_args.lock.oh.data = (u8 *) data; | ||
| 325 | } | ||
| 326 | |||
| 327 | memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len); | ||
| 328 | return 1; | ||
| 329 | } | ||
| 330 | |||
| 331 | static void nlmsvc_freegrantargs(struct nlm_rqst *call) | ||
| 332 | { | ||
| 333 | struct file_lock *fl = &call->a_args.lock.fl; | ||
| 334 | /* | ||
| 335 | * Check whether we allocated memory for the owner. | ||
| 336 | */ | ||
| 337 | if (call->a_args.lock.oh.data != (u8 *) call->a_owner) { | ||
| 338 | kfree(call->a_args.lock.oh.data); | ||
| 339 | } | ||
| 340 | if (fl->fl_ops && fl->fl_ops->fl_release_private) | ||
| 341 | fl->fl_ops->fl_release_private(fl); | ||
| 342 | if (fl->fl_lmops && fl->fl_lmops->fl_release_private) | ||
| 343 | fl->fl_lmops->fl_release_private(fl); | ||
| 344 | } | ||
| 345 | |||
| 346 | /* | ||
| 302 | * Attempt to establish a lock, and if it can't be granted, block it | 347 | * Attempt to establish a lock, and if it can't be granted, block it |
| 303 | * if required. | 348 | * if required. |
| 304 | */ | 349 | */ |
| @@ -600,11 +645,16 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) | |||
| 600 | } | 645 | } |
| 601 | nlmsvc_insert_block(block, timeout); | 646 | nlmsvc_insert_block(block, timeout); |
| 602 | svc_wake_up(block->b_daemon); | 647 | svc_wake_up(block->b_daemon); |
| 603 | nlmsvc_release_block(block); | 648 | } |
| 649 | |||
| 650 | void nlmsvc_grant_release(void *data) | ||
| 651 | { | ||
| 652 | nlmsvc_release_block(data); | ||
| 604 | } | 653 | } |
| 605 | 654 | ||
| 606 | static const struct rpc_call_ops nlmsvc_grant_ops = { | 655 | static const struct rpc_call_ops nlmsvc_grant_ops = { |
| 607 | .rpc_call_done = nlmsvc_grant_callback, | 656 | .rpc_call_done = nlmsvc_grant_callback, |
| 657 | .rpc_release = nlmsvc_grant_release, | ||
| 608 | }; | 658 | }; |
| 609 | 659 | ||
| 610 | /* | 660 | /* |
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 08ab9773f7..860a93f6ce 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
| @@ -153,8 +153,6 @@ long nlmclnt_block(struct nlm_rqst *req, long timeout); | |||
| 153 | u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); | 153 | u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); |
| 154 | void nlmclnt_recovery(struct nlm_host *, u32); | 154 | void nlmclnt_recovery(struct nlm_host *, u32); |
| 155 | int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); | 155 | int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); |
| 156 | int nlmclnt_setgrantargs(struct nlm_rqst *, struct nlm_lock *); | ||
| 157 | void nlmclnt_freegrantargs(struct nlm_rqst *); | ||
| 158 | 156 | ||
| 159 | /* | 157 | /* |
| 160 | * Host cache | 158 | * Host cache |
