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/host.c | |
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/host.c')
-rw-r--r-- | fs/lockd/host.c | 91 |
1 files changed, 72 insertions, 19 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); |