aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/host.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2010-12-14 10:06:12 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-12-16 12:37:26 -0500
commit67216b94d498f5880d8bba2a6b841880739dd524 (patch)
treec1334c1db47782b6af9cd69e5165538d9659bca1 /fs/lockd/host.c
parent8ea6ecc8b0759756a766c05dc7c98c51ec90de37 (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.c91
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
469out:
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 */
480void 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 */
523void 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
536static struct nlm_host *next_host_state(struct hlist_head *cache, 589static 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);