diff options
Diffstat (limited to 'fs/lockd/svcproc.c')
-rw-r--r-- | fs/lockd/svcproc.c | 89 |
1 files changed, 40 insertions, 49 deletions
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index dbb66a3b5cd9..32e99a6e8dca 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -22,8 +22,8 @@ | |||
22 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 22 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
23 | 23 | ||
24 | #ifdef CONFIG_LOCKD_V4 | 24 | #ifdef CONFIG_LOCKD_V4 |
25 | static u32 | 25 | static __be32 |
26 | cast_to_nlm(u32 status, u32 vers) | 26 | cast_to_nlm(__be32 status, u32 vers) |
27 | { | 27 | { |
28 | /* Note: status is assumed to be in network byte order !!! */ | 28 | /* Note: status is assumed to be in network byte order !!! */ |
29 | if (vers != 4){ | 29 | if (vers != 4){ |
@@ -52,22 +52,22 @@ cast_to_nlm(u32 status, u32 vers) | |||
52 | /* | 52 | /* |
53 | * Obtain client and file from arguments | 53 | * Obtain client and file from arguments |
54 | */ | 54 | */ |
55 | static u32 | 55 | static __be32 |
56 | nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | 56 | nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, |
57 | struct nlm_host **hostp, struct nlm_file **filp) | 57 | struct nlm_host **hostp, struct nlm_file **filp) |
58 | { | 58 | { |
59 | struct nlm_host *host = NULL; | 59 | struct nlm_host *host = NULL; |
60 | struct nlm_file *file = NULL; | 60 | struct nlm_file *file = NULL; |
61 | struct nlm_lock *lock = &argp->lock; | 61 | struct nlm_lock *lock = &argp->lock; |
62 | u32 error; | 62 | __be32 error = 0; |
63 | 63 | ||
64 | /* nfsd callbacks must have been installed for this procedure */ | 64 | /* nfsd callbacks must have been installed for this procedure */ |
65 | if (!nlmsvc_ops) | 65 | if (!nlmsvc_ops) |
66 | return nlm_lck_denied_nolocks; | 66 | return nlm_lck_denied_nolocks; |
67 | 67 | ||
68 | /* Obtain host handle */ | 68 | /* Obtain host handle */ |
69 | if (!(host = nlmsvc_lookup_host(rqstp)) | 69 | if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len)) |
70 | || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0)) | 70 | || (argp->monitor && nsm_monitor(host) < 0)) |
71 | goto no_locks; | 71 | goto no_locks; |
72 | *hostp = host; | 72 | *hostp = host; |
73 | 73 | ||
@@ -88,13 +88,15 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
88 | no_locks: | 88 | no_locks: |
89 | if (host) | 89 | if (host) |
90 | nlm_release_host(host); | 90 | nlm_release_host(host); |
91 | if (error) | ||
92 | return error; | ||
91 | return nlm_lck_denied_nolocks; | 93 | return nlm_lck_denied_nolocks; |
92 | } | 94 | } |
93 | 95 | ||
94 | /* | 96 | /* |
95 | * NULL: Test for presence of service | 97 | * NULL: Test for presence of service |
96 | */ | 98 | */ |
97 | static int | 99 | static __be32 |
98 | nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) | 100 | nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) |
99 | { | 101 | { |
100 | dprintk("lockd: NULL called\n"); | 102 | dprintk("lockd: NULL called\n"); |
@@ -104,7 +106,7 @@ nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) | |||
104 | /* | 106 | /* |
105 | * TEST: Check for conflicting lock | 107 | * TEST: Check for conflicting lock |
106 | */ | 108 | */ |
107 | static int | 109 | static __be32 |
108 | nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | 110 | nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, |
109 | struct nlm_res *resp) | 111 | struct nlm_res *resp) |
110 | { | 112 | { |
@@ -122,7 +124,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
122 | 124 | ||
123 | /* Obtain client and file */ | 125 | /* Obtain client and file */ |
124 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 126 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
125 | return rpc_success; | 127 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
126 | 128 | ||
127 | /* Now check for conflicting locks */ | 129 | /* Now check for conflicting locks */ |
128 | resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock)); | 130 | resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock)); |
@@ -134,7 +136,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
134 | return rpc_success; | 136 | return rpc_success; |
135 | } | 137 | } |
136 | 138 | ||
137 | static int | 139 | static __be32 |
138 | nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | 140 | nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, |
139 | struct nlm_res *resp) | 141 | struct nlm_res *resp) |
140 | { | 142 | { |
@@ -153,7 +155,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
153 | 155 | ||
154 | /* Obtain client and file */ | 156 | /* Obtain client and file */ |
155 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 157 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
156 | return rpc_success; | 158 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
157 | 159 | ||
158 | #if 0 | 160 | #if 0 |
159 | /* If supplied state doesn't match current state, we assume it's | 161 | /* If supplied state doesn't match current state, we assume it's |
@@ -177,7 +179,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
177 | return rpc_success; | 179 | return rpc_success; |
178 | } | 180 | } |
179 | 181 | ||
180 | static int | 182 | static __be32 |
181 | nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | 183 | nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, |
182 | struct nlm_res *resp) | 184 | struct nlm_res *resp) |
183 | { | 185 | { |
@@ -196,7 +198,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
196 | 198 | ||
197 | /* Obtain client and file */ | 199 | /* Obtain client and file */ |
198 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 200 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
199 | return rpc_success; | 201 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
200 | 202 | ||
201 | /* Try to cancel request. */ | 203 | /* Try to cancel request. */ |
202 | resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); | 204 | resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); |
@@ -210,7 +212,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
210 | /* | 212 | /* |
211 | * UNLOCK: release a lock | 213 | * UNLOCK: release a lock |
212 | */ | 214 | */ |
213 | static int | 215 | static __be32 |
214 | nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | 216 | nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, |
215 | struct nlm_res *resp) | 217 | struct nlm_res *resp) |
216 | { | 218 | { |
@@ -229,7 +231,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
229 | 231 | ||
230 | /* Obtain client and file */ | 232 | /* Obtain client and file */ |
231 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 233 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
232 | return rpc_success; | 234 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
233 | 235 | ||
234 | /* Now try to remove the lock */ | 236 | /* Now try to remove the lock */ |
235 | resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); | 237 | resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); |
@@ -244,7 +246,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
244 | * GRANTED: A server calls us to tell that a process' lock request | 246 | * GRANTED: A server calls us to tell that a process' lock request |
245 | * was granted | 247 | * was granted |
246 | */ | 248 | */ |
247 | static int | 249 | static __be32 |
248 | nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | 250 | nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, |
249 | struct nlm_res *resp) | 251 | struct nlm_res *resp) |
250 | { | 252 | { |
@@ -280,14 +282,16 @@ static const struct rpc_call_ops nlmsvc_callback_ops = { | |||
280 | * because we send the callback before the reply proper. I hope this | 282 | * because we send the callback before the reply proper. I hope this |
281 | * doesn't break any clients. | 283 | * doesn't break any clients. |
282 | */ | 284 | */ |
283 | static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, | 285 | static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, |
284 | int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) | 286 | __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) |
285 | { | 287 | { |
286 | struct nlm_host *host; | 288 | struct nlm_host *host; |
287 | struct nlm_rqst *call; | 289 | struct nlm_rqst *call; |
288 | int stat; | 290 | __be32 stat; |
289 | 291 | ||
290 | host = nlmsvc_lookup_host(rqstp); | 292 | host = nlmsvc_lookup_host(rqstp, |
293 | argp->lock.caller, | ||
294 | argp->lock.len); | ||
291 | if (host == NULL) | 295 | if (host == NULL) |
292 | return rpc_system_err; | 296 | return rpc_system_err; |
293 | 297 | ||
@@ -307,28 +311,28 @@ static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *ar | |||
307 | return rpc_success; | 311 | return rpc_success; |
308 | } | 312 | } |
309 | 313 | ||
310 | static int nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | 314 | static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, |
311 | void *resp) | 315 | void *resp) |
312 | { | 316 | { |
313 | dprintk("lockd: TEST_MSG called\n"); | 317 | dprintk("lockd: TEST_MSG called\n"); |
314 | return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test); | 318 | return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test); |
315 | } | 319 | } |
316 | 320 | ||
317 | static int nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | 321 | static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, |
318 | void *resp) | 322 | void *resp) |
319 | { | 323 | { |
320 | dprintk("lockd: LOCK_MSG called\n"); | 324 | dprintk("lockd: LOCK_MSG called\n"); |
321 | return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock); | 325 | return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock); |
322 | } | 326 | } |
323 | 327 | ||
324 | static int nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | 328 | static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, |
325 | void *resp) | 329 | void *resp) |
326 | { | 330 | { |
327 | dprintk("lockd: CANCEL_MSG called\n"); | 331 | dprintk("lockd: CANCEL_MSG called\n"); |
328 | return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel); | 332 | return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel); |
329 | } | 333 | } |
330 | 334 | ||
331 | static int | 335 | static __be32 |
332 | nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | 336 | nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, |
333 | void *resp) | 337 | void *resp) |
334 | { | 338 | { |
@@ -336,7 +340,7 @@ nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
336 | return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock); | 340 | return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock); |
337 | } | 341 | } |
338 | 342 | ||
339 | static int | 343 | static __be32 |
340 | nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | 344 | nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, |
341 | void *resp) | 345 | void *resp) |
342 | { | 346 | { |
@@ -347,7 +351,7 @@ nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
347 | /* | 351 | /* |
348 | * SHARE: create a DOS share or alter existing share. | 352 | * SHARE: create a DOS share or alter existing share. |
349 | */ | 353 | */ |
350 | static int | 354 | static __be32 |
351 | nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | 355 | nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, |
352 | struct nlm_res *resp) | 356 | struct nlm_res *resp) |
353 | { | 357 | { |
@@ -366,7 +370,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
366 | 370 | ||
367 | /* Obtain client and file */ | 371 | /* Obtain client and file */ |
368 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 372 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
369 | return rpc_success; | 373 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
370 | 374 | ||
371 | /* Now try to create the share */ | 375 | /* Now try to create the share */ |
372 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); | 376 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); |
@@ -380,7 +384,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
380 | /* | 384 | /* |
381 | * UNSHARE: Release a DOS share. | 385 | * UNSHARE: Release a DOS share. |
382 | */ | 386 | */ |
383 | static int | 387 | static __be32 |
384 | nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | 388 | nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, |
385 | struct nlm_res *resp) | 389 | struct nlm_res *resp) |
386 | { | 390 | { |
@@ -399,7 +403,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
399 | 403 | ||
400 | /* Obtain client and file */ | 404 | /* Obtain client and file */ |
401 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 405 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
402 | return rpc_success; | 406 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
403 | 407 | ||
404 | /* Now try to unshare the file */ | 408 | /* Now try to unshare the file */ |
405 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); | 409 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); |
@@ -413,7 +417,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
413 | /* | 417 | /* |
414 | * NM_LOCK: Create an unmonitored lock | 418 | * NM_LOCK: Create an unmonitored lock |
415 | */ | 419 | */ |
416 | static int | 420 | static __be32 |
417 | nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | 421 | nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, |
418 | struct nlm_res *resp) | 422 | struct nlm_res *resp) |
419 | { | 423 | { |
@@ -426,7 +430,7 @@ nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
426 | /* | 430 | /* |
427 | * FREE_ALL: Release all locks and shares held by client | 431 | * FREE_ALL: Release all locks and shares held by client |
428 | */ | 432 | */ |
429 | static int | 433 | static __be32 |
430 | nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, | 434 | nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, |
431 | void *resp) | 435 | void *resp) |
432 | { | 436 | { |
@@ -444,14 +448,11 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
444 | /* | 448 | /* |
445 | * SM_NOTIFY: private callback from statd (not part of official NLM proto) | 449 | * SM_NOTIFY: private callback from statd (not part of official NLM proto) |
446 | */ | 450 | */ |
447 | static int | 451 | static __be32 |
448 | nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | 452 | nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, |
449 | void *resp) | 453 | void *resp) |
450 | { | 454 | { |
451 | struct sockaddr_in saddr = rqstp->rq_addr; | 455 | struct sockaddr_in saddr = rqstp->rq_addr; |
452 | int vers = argp->vers; | ||
453 | int prot = argp->proto >> 1; | ||
454 | struct nlm_host *host; | ||
455 | 456 | ||
456 | dprintk("lockd: SM_NOTIFY called\n"); | 457 | dprintk("lockd: SM_NOTIFY called\n"); |
457 | if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) | 458 | if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) |
@@ -466,19 +467,9 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
466 | /* Obtain the host pointer for this NFS server and try to | 467 | /* Obtain the host pointer for this NFS server and try to |
467 | * reclaim all locks we hold on this server. | 468 | * reclaim all locks we hold on this server. |
468 | */ | 469 | */ |
470 | memset(&saddr, 0, sizeof(saddr)); | ||
469 | saddr.sin_addr.s_addr = argp->addr; | 471 | saddr.sin_addr.s_addr = argp->addr; |
470 | if ((argp->proto & 1)==0) { | 472 | nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state); |
471 | if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { | ||
472 | nlmclnt_recovery(host, argp->state); | ||
473 | nlm_release_host(host); | ||
474 | } | ||
475 | } else { | ||
476 | /* If we run on an NFS server, delete all locks held by the client */ | ||
477 | if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) { | ||
478 | nlmsvc_free_host_resources(host); | ||
479 | nlm_release_host(host); | ||
480 | } | ||
481 | } | ||
482 | 473 | ||
483 | return rpc_success; | 474 | return rpc_success; |
484 | } | 475 | } |
@@ -486,7 +477,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
486 | /* | 477 | /* |
487 | * client sent a GRANTED_RES, let's remove the associated block | 478 | * client sent a GRANTED_RES, let's remove the associated block |
488 | */ | 479 | */ |
489 | static int | 480 | static __be32 |
490 | nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, | 481 | nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, |
491 | void *resp) | 482 | void *resp) |
492 | { | 483 | { |
@@ -495,7 +486,7 @@ nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, | |||
495 | 486 | ||
496 | dprintk("lockd: GRANTED_RES called\n"); | 487 | dprintk("lockd: GRANTED_RES called\n"); |
497 | 488 | ||
498 | nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status); | 489 | nlmsvc_grant_reply(&argp->cookie, argp->status); |
499 | return rpc_success; | 490 | return rpc_success; |
500 | } | 491 | } |
501 | 492 | ||