diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2010-12-14 10:06:12 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-12-16 12:37:26 -0500 |
commit | 67216b94d498f5880d8bba2a6b841880739dd524 (patch) | |
tree | c1334c1db47782b6af9cd69e5165538d9659bca1 /fs/lockd | |
parent | 8ea6ecc8b0759756a766c05dc7c98c51ec90de37 (diff) |
lockd: Clean up nlmsvc_lookup_host()
Clean up.
Change nlmsvc_lookup_host() to be purpose-built for server-side
nlm_host management. This replaces the generic nlm_lookup_host()
helper function, just like on the client side. The lookup logic is
specialized for server host lookups.
The server side cache also gets its own specialized equivalent of the
nlm_release_host() function.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/host.c | 91 | ||||
-rw-r--r-- | fs/lockd/svc4proc.c | 16 | ||||
-rw-r--r-- | fs/lockd/svcproc.c | 18 |
3 files changed, 89 insertions, 36 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index c6942fb4bd0d..0250b0e4f5e9 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -383,6 +383,10 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
383 | const char *hostname, | 383 | const char *hostname, |
384 | const size_t hostname_len) | 384 | const size_t hostname_len) |
385 | { | 385 | { |
386 | struct hlist_head *chain; | ||
387 | struct hlist_node *pos; | ||
388 | struct nlm_host *host = NULL; | ||
389 | struct nsm_handle *nsm = NULL; | ||
386 | struct sockaddr_in sin = { | 390 | struct sockaddr_in sin = { |
387 | .sin_family = AF_INET, | 391 | .sin_family = AF_INET, |
388 | }; | 392 | }; |
@@ -404,6 +408,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
404 | (int)hostname_len, hostname, rqstp->rq_vers, | 408 | (int)hostname_len, hostname, rqstp->rq_vers, |
405 | (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); | 409 | (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); |
406 | 410 | ||
411 | mutex_lock(&nlm_host_mutex); | ||
412 | |||
407 | switch (ni.sap->sa_family) { | 413 | switch (ni.sap->sa_family) { |
408 | case AF_INET: | 414 | case AF_INET: |
409 | sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; | 415 | sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; |
@@ -414,10 +420,73 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
414 | ni.src_sap = (struct sockaddr *)&sin6; | 420 | ni.src_sap = (struct sockaddr *)&sin6; |
415 | break; | 421 | break; |
416 | default: | 422 | default: |
417 | return NULL; | 423 | dprintk("lockd: %s failed; unrecognized address family\n", |
424 | __func__); | ||
425 | goto out; | ||
418 | } | 426 | } |
419 | 427 | ||
420 | return nlm_lookup_host(&ni); | 428 | if (time_after_eq(jiffies, next_gc)) |
429 | nlm_gc_hosts(); | ||
430 | |||
431 | chain = &nlm_hosts[nlm_hash_address(ni.sap)]; | ||
432 | hlist_for_each_entry(host, pos, chain, h_hash) { | ||
433 | if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) | ||
434 | continue; | ||
435 | |||
436 | /* Same address. Share an NSM handle if we already have one */ | ||
437 | if (nsm == NULL) | ||
438 | nsm = host->h_nsmhandle; | ||
439 | |||
440 | if (host->h_proto != ni.protocol) | ||
441 | continue; | ||
442 | if (host->h_version != ni.version) | ||
443 | continue; | ||
444 | if (!rpc_cmp_addr(nlm_srcaddr(host), ni.src_sap)) | ||
445 | continue; | ||
446 | |||
447 | /* Move to head of hash chain. */ | ||
448 | hlist_del(&host->h_hash); | ||
449 | hlist_add_head(&host->h_hash, chain); | ||
450 | |||
451 | nlm_get_host(host); | ||
452 | dprintk("lockd: %s found host %s (%s)\n", | ||
453 | __func__, host->h_name, host->h_addrbuf); | ||
454 | goto out; | ||
455 | } | ||
456 | |||
457 | host = nlm_alloc_host(&ni, nsm); | ||
458 | if (unlikely(host == NULL)) | ||
459 | goto out; | ||
460 | |||
461 | memcpy(nlm_srcaddr(host), ni.src_sap, ni.src_len); | ||
462 | host->h_srcaddrlen = ni.src_len; | ||
463 | hlist_add_head(&host->h_hash, chain); | ||
464 | nrhosts++; | ||
465 | |||
466 | dprintk("lockd: %s created host %s (%s)\n", | ||
467 | __func__, host->h_name, host->h_addrbuf); | ||
468 | |||
469 | out: | ||
470 | mutex_unlock(&nlm_host_mutex); | ||
471 | return host; | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * nlmsvc_release_host - release server nlm_host | ||
476 | * @host: nlm_host to release | ||
477 | * | ||
478 | * Host is destroyed later in nlm_gc_host(). | ||
479 | */ | ||
480 | void nlmsvc_release_host(struct nlm_host *host) | ||
481 | { | ||
482 | if (host == NULL) | ||
483 | return; | ||
484 | |||
485 | dprintk("lockd: release server host %s\n", host->h_name); | ||
486 | |||
487 | BUG_ON(atomic_read(&host->h_count) < 0); | ||
488 | BUG_ON(!host->h_server); | ||
489 | atomic_dec(&host->h_count); | ||
421 | } | 490 | } |
422 | 491 | ||
423 | /* | 492 | /* |
@@ -517,22 +586,6 @@ struct nlm_host * nlm_get_host(struct nlm_host *host) | |||
517 | return host; | 586 | return host; |
518 | } | 587 | } |
519 | 588 | ||
520 | /* | ||
521 | * Release NLM host after use | ||
522 | */ | ||
523 | void nlm_release_host(struct nlm_host *host) | ||
524 | { | ||
525 | if (host != NULL) { | ||
526 | dprintk("lockd: release host %s\n", host->h_name); | ||
527 | BUG_ON(atomic_read(&host->h_count) < 0); | ||
528 | if (atomic_dec_and_test(&host->h_count)) { | ||
529 | BUG_ON(!list_empty(&host->h_lockowners)); | ||
530 | BUG_ON(!list_empty(&host->h_granted)); | ||
531 | BUG_ON(!list_empty(&host->h_reclaim)); | ||
532 | } | ||
533 | } | ||
534 | } | ||
535 | |||
536 | static struct nlm_host *next_host_state(struct hlist_head *cache, | 589 | static struct nlm_host *next_host_state(struct hlist_head *cache, |
537 | struct nsm_handle *nsm, | 590 | struct nsm_handle *nsm, |
538 | const struct nlm_reboot *info) | 591 | const struct nlm_reboot *info) |
@@ -581,7 +634,7 @@ void nlm_host_rebooted(const struct nlm_reboot *info) | |||
581 | */ | 634 | */ |
582 | while ((host = next_host_state(nlm_hosts, nsm, info)) != NULL) { | 635 | while ((host = next_host_state(nlm_hosts, nsm, info)) != NULL) { |
583 | nlmsvc_free_host_resources(host); | 636 | nlmsvc_free_host_resources(host); |
584 | nlm_release_host(host); | 637 | nlmsvc_release_host(host); |
585 | } | 638 | } |
586 | while ((host = next_host_state(nlm_client_hosts, nsm, info)) != NULL) { | 639 | while ((host = next_host_state(nlm_client_hosts, nsm, info)) != NULL) { |
587 | nlmclnt_recovery(host); | 640 | nlmclnt_recovery(host); |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index c187422026d8..9a41fdc19511 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -51,7 +51,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
51 | return 0; | 51 | return 0; |
52 | 52 | ||
53 | no_locks: | 53 | no_locks: |
54 | nlm_release_host(host); | 54 | nlmsvc_release_host(host); |
55 | if (error) | 55 | if (error) |
56 | return error; | 56 | return error; |
57 | return nlm_lck_denied_nolocks; | 57 | return nlm_lck_denied_nolocks; |
@@ -92,7 +92,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
92 | else | 92 | else |
93 | dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); | 93 | dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); |
94 | 94 | ||
95 | nlm_release_host(host); | 95 | nlmsvc_release_host(host); |
96 | nlm_release_file(file); | 96 | nlm_release_file(file); |
97 | return rc; | 97 | return rc; |
98 | } | 98 | } |
@@ -134,7 +134,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
134 | else | 134 | else |
135 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | 135 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); |
136 | 136 | ||
137 | nlm_release_host(host); | 137 | nlmsvc_release_host(host); |
138 | nlm_release_file(file); | 138 | nlm_release_file(file); |
139 | return rc; | 139 | return rc; |
140 | } | 140 | } |
@@ -164,7 +164,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
164 | resp->status = nlmsvc_cancel_blocked(file, &argp->lock); | 164 | resp->status = nlmsvc_cancel_blocked(file, &argp->lock); |
165 | 165 | ||
166 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 166 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
167 | nlm_release_host(host); | 167 | nlmsvc_release_host(host); |
168 | nlm_release_file(file); | 168 | nlm_release_file(file); |
169 | return rpc_success; | 169 | return rpc_success; |
170 | } | 170 | } |
@@ -197,7 +197,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
197 | resp->status = nlmsvc_unlock(file, &argp->lock); | 197 | resp->status = nlmsvc_unlock(file, &argp->lock); |
198 | 198 | ||
199 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 199 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
200 | nlm_release_host(host); | 200 | nlmsvc_release_host(host); |
201 | nlm_release_file(file); | 201 | nlm_release_file(file); |
202 | return rpc_success; | 202 | return rpc_success; |
203 | } | 203 | } |
@@ -334,7 +334,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
334 | resp->status = nlmsvc_share_file(host, file, argp); | 334 | resp->status = nlmsvc_share_file(host, file, argp); |
335 | 335 | ||
336 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); | 336 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); |
337 | nlm_release_host(host); | 337 | nlmsvc_release_host(host); |
338 | nlm_release_file(file); | 338 | nlm_release_file(file); |
339 | return rpc_success; | 339 | return rpc_success; |
340 | } | 340 | } |
@@ -367,7 +367,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
367 | resp->status = nlmsvc_unshare_file(host, file, argp); | 367 | resp->status = nlmsvc_unshare_file(host, file, argp); |
368 | 368 | ||
369 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); | 369 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); |
370 | nlm_release_host(host); | 370 | nlmsvc_release_host(host); |
371 | nlm_release_file(file); | 371 | nlm_release_file(file); |
372 | return rpc_success; | 372 | return rpc_success; |
373 | } | 373 | } |
@@ -399,7 +399,7 @@ nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
399 | return rpc_success; | 399 | return rpc_success; |
400 | 400 | ||
401 | nlmsvc_free_host_resources(host); | 401 | nlmsvc_free_host_resources(host); |
402 | nlm_release_host(host); | 402 | nlmsvc_release_host(host); |
403 | return rpc_success; | 403 | return rpc_success; |
404 | } | 404 | } |
405 | 405 | ||
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 0df65ec29e43..d27aab11f324 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -80,7 +80,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
80 | return 0; | 80 | return 0; |
81 | 81 | ||
82 | no_locks: | 82 | no_locks: |
83 | nlm_release_host(host); | 83 | nlmsvc_release_host(host); |
84 | if (error) | 84 | if (error) |
85 | return error; | 85 | return error; |
86 | return nlm_lck_denied_nolocks; | 86 | return nlm_lck_denied_nolocks; |
@@ -122,7 +122,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
122 | dprintk("lockd: TEST status %d vers %d\n", | 122 | dprintk("lockd: TEST status %d vers %d\n", |
123 | ntohl(resp->status), rqstp->rq_vers); | 123 | ntohl(resp->status), rqstp->rq_vers); |
124 | 124 | ||
125 | nlm_release_host(host); | 125 | nlmsvc_release_host(host); |
126 | nlm_release_file(file); | 126 | nlm_release_file(file); |
127 | return rc; | 127 | return rc; |
128 | } | 128 | } |
@@ -164,7 +164,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
164 | else | 164 | else |
165 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | 165 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); |
166 | 166 | ||
167 | nlm_release_host(host); | 167 | nlmsvc_release_host(host); |
168 | nlm_release_file(file); | 168 | nlm_release_file(file); |
169 | return rc; | 169 | return rc; |
170 | } | 170 | } |
@@ -194,7 +194,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
194 | resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); | 194 | resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); |
195 | 195 | ||
196 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 196 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
197 | nlm_release_host(host); | 197 | nlmsvc_release_host(host); |
198 | nlm_release_file(file); | 198 | nlm_release_file(file); |
199 | return rpc_success; | 199 | return rpc_success; |
200 | } | 200 | } |
@@ -227,7 +227,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
227 | resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); | 227 | resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); |
228 | 228 | ||
229 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 229 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
230 | nlm_release_host(host); | 230 | nlmsvc_release_host(host); |
231 | nlm_release_file(file); | 231 | nlm_release_file(file); |
232 | return rpc_success; | 232 | return rpc_success; |
233 | } | 233 | } |
@@ -261,7 +261,7 @@ void nlmsvc_release_call(struct nlm_rqst *call) | |||
261 | { | 261 | { |
262 | if (!atomic_dec_and_test(&call->a_count)) | 262 | if (!atomic_dec_and_test(&call->a_count)) |
263 | return; | 263 | return; |
264 | nlm_release_host(call->a_host); | 264 | nlmsvc_release_host(call->a_host); |
265 | kfree(call); | 265 | kfree(call); |
266 | } | 266 | } |
267 | 267 | ||
@@ -374,7 +374,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
374 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); | 374 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); |
375 | 375 | ||
376 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); | 376 | dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); |
377 | nlm_release_host(host); | 377 | nlmsvc_release_host(host); |
378 | nlm_release_file(file); | 378 | nlm_release_file(file); |
379 | return rpc_success; | 379 | return rpc_success; |
380 | } | 380 | } |
@@ -407,7 +407,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
407 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); | 407 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); |
408 | 408 | ||
409 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); | 409 | dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); |
410 | nlm_release_host(host); | 410 | nlmsvc_release_host(host); |
411 | nlm_release_file(file); | 411 | nlm_release_file(file); |
412 | return rpc_success; | 412 | return rpc_success; |
413 | } | 413 | } |
@@ -439,7 +439,7 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
439 | return rpc_success; | 439 | return rpc_success; |
440 | 440 | ||
441 | nlmsvc_free_host_resources(host); | 441 | nlmsvc_free_host_resources(host); |
442 | nlm_release_host(host); | 442 | nlmsvc_release_host(host); |
443 | return rpc_success; | 443 | return rpc_success; |
444 | } | 444 | } |
445 | 445 | ||