aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/host.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/host.c')
-rw-r--r--fs/lockd/host.c73
1 files changed, 36 insertions, 37 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index f1ef49fff118..c7854791898f 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -19,12 +19,11 @@
19 19
20 20
21#define NLMDBG_FACILITY NLMDBG_HOSTCACHE 21#define NLMDBG_FACILITY NLMDBG_HOSTCACHE
22#define NLM_HOST_MAX 64
23#define NLM_HOST_NRHASH 32 22#define NLM_HOST_NRHASH 32
24#define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) 23#define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1))
25#define NLM_HOST_REBIND (60 * HZ) 24#define NLM_HOST_REBIND (60 * HZ)
26#define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) 25#define NLM_HOST_EXPIRE (300 * HZ)
27#define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) 26#define NLM_HOST_COLLECT (120 * HZ)
28 27
29static struct hlist_head nlm_hosts[NLM_HOST_NRHASH]; 28static struct hlist_head nlm_hosts[NLM_HOST_NRHASH];
30static unsigned long next_gc; 29static unsigned long next_gc;
@@ -142,9 +141,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
142 INIT_LIST_HEAD(&host->h_granted); 141 INIT_LIST_HEAD(&host->h_granted);
143 INIT_LIST_HEAD(&host->h_reclaim); 142 INIT_LIST_HEAD(&host->h_reclaim);
144 143
145 if (++nrhosts > NLM_HOST_MAX) 144 nrhosts++;
146 next_gc = 0;
147
148out: 145out:
149 mutex_unlock(&nlm_host_mutex); 146 mutex_unlock(&nlm_host_mutex);
150 return host; 147 return host;
@@ -460,7 +457,7 @@ nlm_gc_hosts(void)
460 * Manage NSM handles 457 * Manage NSM handles
461 */ 458 */
462static LIST_HEAD(nsm_handles); 459static LIST_HEAD(nsm_handles);
463static DEFINE_MUTEX(nsm_mutex); 460static DEFINE_SPINLOCK(nsm_lock);
464 461
465static struct nsm_handle * 462static struct nsm_handle *
466__nsm_find(const struct sockaddr_in *sin, 463__nsm_find(const struct sockaddr_in *sin,
@@ -468,7 +465,7 @@ __nsm_find(const struct sockaddr_in *sin,
468 int create) 465 int create)
469{ 466{
470 struct nsm_handle *nsm = NULL; 467 struct nsm_handle *nsm = NULL;
471 struct list_head *pos; 468 struct nsm_handle *pos;
472 469
473 if (!sin) 470 if (!sin)
474 return NULL; 471 return NULL;
@@ -482,38 +479,43 @@ __nsm_find(const struct sockaddr_in *sin,
482 return NULL; 479 return NULL;
483 } 480 }
484 481
485 mutex_lock(&nsm_mutex); 482retry:
486 list_for_each(pos, &nsm_handles) { 483 spin_lock(&nsm_lock);
487 nsm = list_entry(pos, struct nsm_handle, sm_link); 484 list_for_each_entry(pos, &nsm_handles, sm_link) {
488 485
489 if (hostname && nsm_use_hostnames) { 486 if (hostname && nsm_use_hostnames) {
490 if (strlen(nsm->sm_name) != hostname_len 487 if (strlen(pos->sm_name) != hostname_len
491 || memcmp(nsm->sm_name, hostname, hostname_len)) 488 || memcmp(pos->sm_name, hostname, hostname_len))
492 continue; 489 continue;
493 } else if (!nlm_cmp_addr(&nsm->sm_addr, sin)) 490 } else if (!nlm_cmp_addr(&pos->sm_addr, sin))
494 continue; 491 continue;
495 atomic_inc(&nsm->sm_count); 492 atomic_inc(&pos->sm_count);
496 goto out; 493 kfree(nsm);
494 nsm = pos;
495 goto found;
497 } 496 }
498 497 if (nsm) {
499 if (!create) { 498 list_add(&nsm->sm_link, &nsm_handles);
500 nsm = NULL; 499 goto found;
501 goto out;
502 } 500 }
501 spin_unlock(&nsm_lock);
502
503 if (!create)
504 return NULL;
503 505
504 nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL); 506 nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
505 if (nsm != NULL) { 507 if (nsm == NULL)
506 nsm->sm_addr = *sin; 508 return NULL;
507 nsm->sm_name = (char *) (nsm + 1);
508 memcpy(nsm->sm_name, hostname, hostname_len);
509 nsm->sm_name[hostname_len] = '\0';
510 atomic_set(&nsm->sm_count, 1);
511 509
512 list_add(&nsm->sm_link, &nsm_handles); 510 nsm->sm_addr = *sin;
513 } 511 nsm->sm_name = (char *) (nsm + 1);
512 memcpy(nsm->sm_name, hostname, hostname_len);
513 nsm->sm_name[hostname_len] = '\0';
514 atomic_set(&nsm->sm_count, 1);
515 goto retry;
514 516
515out: 517found:
516 mutex_unlock(&nsm_mutex); 518 spin_unlock(&nsm_lock);
517 return nsm; 519 return nsm;
518} 520}
519 521
@@ -532,12 +534,9 @@ nsm_release(struct nsm_handle *nsm)
532{ 534{
533 if (!nsm) 535 if (!nsm)
534 return; 536 return;
535 if (atomic_dec_and_test(&nsm->sm_count)) { 537 if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
536 mutex_lock(&nsm_mutex); 538 list_del(&nsm->sm_link);
537 if (atomic_read(&nsm->sm_count) == 0) { 539 spin_unlock(&nsm_lock);
538 list_del(&nsm->sm_link); 540 kfree(nsm);
539 kfree(nsm);
540 }
541 mutex_unlock(&nsm_mutex);
542 } 541 }
543} 542}