aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd
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
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')
-rw-r--r--fs/lockd/host.c91
-rw-r--r--fs/lockd/svc4proc.c16
-rw-r--r--fs/lockd/svcproc.c18
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
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);
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
53no_locks: 53no_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
82no_locks: 82no_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