Blame view
fs/lockd/host.c
15.9 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 |
/* * linux/fs/lockd/host.c * * Management for NLM peer hosts. The nlm_host struct is shared * between client and server implementation. The only reason to * do so is to reduce code bloat. * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> */ #include <linux/types.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/slab.h> #include <linux/in.h> |
1b333c54a lockd: address-fa... |
14 |
#include <linux/in6.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 |
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> |
353ab6e97 [PATCH] sem2mutex... |
18 |
#include <linux/mutex.h> |
1da177e4c Linux-2.6.12-rc2 |
19 |
|
1b333c54a lockd: address-fa... |
20 |
#include <net/ipv6.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 |
#define NLMDBG_FACILITY NLMDBG_HOSTCACHE |
1da177e4c Linux-2.6.12-rc2 |
23 |
#define NLM_HOST_NRHASH 32 |
1da177e4c Linux-2.6.12-rc2 |
24 |
#define NLM_HOST_REBIND (60 * HZ) |
1447d25eb knfsd: Remove NLM... |
25 26 |
#define NLM_HOST_EXPIRE (300 * HZ) #define NLM_HOST_COLLECT (120 * HZ) |
1da177e4c Linux-2.6.12-rc2 |
27 |
|
d2df0484b lockd: Rename nlm... |
28 |
static struct hlist_head nlm_server_hosts[NLM_HOST_NRHASH]; |
8ea6ecc8b lockd: Create cli... |
29 |
static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH]; |
b11374688 lockd: define hos... |
30 31 32 33 34 35 36 37 38 39 40 |
#define for_each_host(host, pos, chain, table) \ for ((chain) = (table); \ (chain) < (table) + NLM_HOST_NRHASH; ++(chain)) \ hlist_for_each_entry((host), (pos), (chain), h_hash) #define for_each_host_safe(host, pos, next, chain, table) \ for ((chain) = (table); \ (chain) < (table) + NLM_HOST_NRHASH; ++(chain)) \ hlist_for_each_entry_safe((host), (pos), (next), \ (chain), h_hash) |
1da177e4c Linux-2.6.12-rc2 |
41 |
static unsigned long next_gc; |
fcc072c78 lockd: Make nrhos... |
42 |
static unsigned long nrhosts; |
353ab6e97 [PATCH] sem2mutex... |
43 |
static DEFINE_MUTEX(nlm_host_mutex); |
1da177e4c Linux-2.6.12-rc2 |
44 |
|
1da177e4c Linux-2.6.12-rc2 |
45 |
static void nlm_gc_hosts(void); |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
7f1ed18bd NLM: Convert nlm_... |
47 48 |
struct nlm_lookup_host_info { const int server; /* search for server|client */ |
88541c848 lockd: Support no... |
49 50 |
const struct sockaddr *sap; /* address to search for */ const size_t salen; /* it's length */ |
7f1ed18bd NLM: Convert nlm_... |
51 52 53 54 |
const unsigned short protocol; /* transport to search for*/ const u32 version; /* NLM version to search for */ const char *hostname; /* remote's hostname */ const size_t hostname_len; /* it's length */ |
0cb2659b8 NLM: allow lockd ... |
55 |
const int noresvport; /* use non-priv port */ |
7f1ed18bd NLM: Convert nlm_... |
56 |
}; |
ede2fea09 lockd: Support AF... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
/* * Hash function must work well on big- and little-endian platforms */ static unsigned int __nlm_hash32(const __be32 n) { unsigned int hash = (__force u32)n ^ ((__force u32)n >> 16); return hash ^ (hash >> 8); } static unsigned int __nlm_hash_addr4(const struct sockaddr *sap) { const struct sockaddr_in *sin = (struct sockaddr_in *)sap; return __nlm_hash32(sin->sin_addr.s_addr); } static unsigned int __nlm_hash_addr6(const struct sockaddr *sap) { const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; const struct in6_addr addr = sin6->sin6_addr; return __nlm_hash32(addr.s6_addr32[0]) ^ __nlm_hash32(addr.s6_addr32[1]) ^ __nlm_hash32(addr.s6_addr32[2]) ^ __nlm_hash32(addr.s6_addr32[3]); } static unsigned int nlm_hash_address(const struct sockaddr *sap) { unsigned int hash; switch (sap->sa_family) { case AF_INET: hash = __nlm_hash_addr4(sap); break; case AF_INET6: hash = __nlm_hash_addr6(sap); break; default: hash = 0; } return hash & (NLM_HOST_NRHASH - 1); } |
1da177e4c Linux-2.6.12-rc2 |
98 |
/* |
a7952f405 lockd: Add nlm_al... |
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
* Allocate and initialize an nlm_host. Common to both client and server. */ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, struct nsm_handle *nsm) { struct nlm_host *host = NULL; unsigned long now = jiffies; if (nsm != NULL) atomic_inc(&nsm->sm_count); else { host = NULL; nsm = nsm_get_handle(ni->sap, ni->salen, ni->hostname, ni->hostname_len); if (unlikely(nsm == NULL)) { dprintk("lockd: %s failed; no nsm handle ", __func__); goto out; } } host = kmalloc(sizeof(*host), GFP_KERNEL); if (unlikely(host == NULL)) { dprintk("lockd: %s failed; no memory ", __func__); nsm_release(nsm); goto out; } memcpy(nlm_addr(host), ni->sap, ni->salen); host->h_addrlen = ni->salen; rpc_set_port(nlm_addr(host), 0); host->h_srcaddrlen = 0; host->h_rpcclnt = NULL; host->h_name = nsm->sm_name; host->h_version = ni->version; host->h_proto = ni->protocol; host->h_reclaiming = 0; host->h_server = ni->server; host->h_noresvport = ni->noresvport; host->h_inuse = 0; init_waitqueue_head(&host->h_gracewait); init_rwsem(&host->h_rwsem); host->h_state = 0; host->h_nsmstate = 0; host->h_pidcount = 0; atomic_set(&host->h_count, 1); mutex_init(&host->h_mutex); host->h_nextrebind = now + NLM_HOST_REBIND; host->h_expires = now + NLM_HOST_EXPIRE; INIT_LIST_HEAD(&host->h_lockowners); spin_lock_init(&host->h_lock); INIT_LIST_HEAD(&host->h_granted); INIT_LIST_HEAD(&host->h_reclaim); host->h_nsmhandle = nsm; host->h_addrbuf = nsm->sm_addrbuf; out: return host; } /* |
723bb5b50 lockd: Add nlm_de... |
163 164 165 |
* Destroy an nlm_host and free associated resources * * Caller must hold nlm_host_mutex. |
c53c1bb94 [PATCH] knfsd: lo... |
166 |
*/ |
723bb5b50 lockd: Add nlm_de... |
167 |
static void nlm_destroy_host_locked(struct nlm_host *host) |
c53c1bb94 [PATCH] knfsd: lo... |
168 169 |
{ struct rpc_clnt *clnt; |
723bb5b50 lockd: Add nlm_de... |
170 171 |
dprintk("lockd: destroy host %s ", host->h_name); |
c53c1bb94 [PATCH] knfsd: lo... |
172 173 |
BUG_ON(!list_empty(&host->h_lockowners)); BUG_ON(atomic_read(&host->h_count)); |
723bb5b50 lockd: Add nlm_de... |
174 |
hlist_del_init(&host->h_hash); |
c53c1bb94 [PATCH] knfsd: lo... |
175 |
nsm_unmonitor(host); |
c8c23c423 NSM: Release nsmh... |
176 |
nsm_release(host->h_nsmhandle); |
c53c1bb94 [PATCH] knfsd: lo... |
177 |
|
34f52e359 SUNRPC: Convert r... |
178 179 180 |
clnt = host->h_rpcclnt; if (clnt != NULL) rpc_shutdown_client(clnt); |
c53c1bb94 [PATCH] knfsd: lo... |
181 |
kfree(host); |
723bb5b50 lockd: Add nlm_de... |
182 183 |
nrhosts--; |
c53c1bb94 [PATCH] knfsd: lo... |
184 |
} |
d7d204403 lockd: Adjust nlm... |
185 186 187 188 189 190 191 |
/** * nlmclnt_lookup_host - Find an NLM host handle matching a remote server * @sap: network address of server * @salen: length of server address * @protocol: transport protocol to use * @version: NLM protocol version * @hostname: '\0'-terminated hostname of server |
0cb2659b8 NLM: allow lockd ... |
192 |
* @noresvport: 1 if non-privileged port should be used |
d7d204403 lockd: Adjust nlm... |
193 194 195 196 197 |
* * Returns an nlm_host structure that matches the passed-in * [server address, transport protocol, NLM version, server hostname]. * If one doesn't already exist in the host cache, a new handle is * created and returned. |
c585646dd [PATCH] fs/lockd/... |
198 |
*/ |
d7d204403 lockd: Adjust nlm... |
199 200 201 |
struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, const size_t salen, const unsigned short protocol, |
0cb2659b8 NLM: allow lockd ... |
202 203 204 |
const u32 version, const char *hostname, int noresvport) |
c585646dd [PATCH] fs/lockd/... |
205 |
{ |
7f1ed18bd NLM: Convert nlm_... |
206 207 |
struct nlm_lookup_host_info ni = { .server = 0, |
d7d204403 lockd: Adjust nlm... |
208 209 210 |
.sap = sap, .salen = salen, .protocol = protocol, |
7f1ed18bd NLM: Convert nlm_... |
211 212 |
.version = version, .hostname = hostname, |
d7d204403 lockd: Adjust nlm... |
213 |
.hostname_len = strlen(hostname), |
0cb2659b8 NLM: allow lockd ... |
214 |
.noresvport = noresvport, |
7f1ed18bd NLM: Convert nlm_... |
215 |
}; |
8ea6ecc8b lockd: Create cli... |
216 217 218 219 |
struct hlist_head *chain; struct hlist_node *pos; struct nlm_host *host; struct nsm_handle *nsm = NULL; |
c98451bdb NLM: fix source a... |
220 |
|
7f1ed18bd NLM: Convert nlm_... |
221 222 223 |
dprintk("lockd: %s(host='%s', vers=%u, proto=%s) ", __func__, (hostname ? hostname : "<none>"), version, |
d7d204403 lockd: Adjust nlm... |
224 |
(protocol == IPPROTO_UDP ? "udp" : "tcp")); |
7f1ed18bd NLM: Convert nlm_... |
225 |
|
8ea6ecc8b lockd: Create cli... |
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
mutex_lock(&nlm_host_mutex); chain = &nlm_client_hosts[nlm_hash_address(sap)]; hlist_for_each_entry(host, pos, chain, h_hash) { if (!rpc_cmp_addr(nlm_addr(host), sap)) continue; /* Same address. Share an NSM handle if we already have one */ if (nsm == NULL) nsm = host->h_nsmhandle; if (host->h_proto != protocol) continue; if (host->h_version != version) continue; nlm_get_host(host); dprintk("lockd: %s found host %s (%s) ", __func__, host->h_name, host->h_addrbuf); goto out; } host = nlm_alloc_host(&ni, nsm); if (unlikely(host == NULL)) goto out; hlist_add_head(&host->h_hash, chain); nrhosts++; dprintk("lockd: %s created host %s (%s) ", __func__, host->h_name, host->h_addrbuf); out: mutex_unlock(&nlm_host_mutex); return host; } /** * nlmclnt_release_host - release client nlm_host * @host: nlm_host to release * */ void nlmclnt_release_host(struct nlm_host *host) { if (host == NULL) return; dprintk("lockd: release client host %s ", host->h_name); BUG_ON(atomic_read(&host->h_count) < 0); BUG_ON(host->h_server); if (atomic_dec_and_test(&host->h_count)) { BUG_ON(!list_empty(&host->h_lockowners)); BUG_ON(!list_empty(&host->h_granted)); BUG_ON(!list_empty(&host->h_reclaim)); mutex_lock(&nlm_host_mutex); nlm_destroy_host_locked(host); mutex_unlock(&nlm_host_mutex); } |
c585646dd [PATCH] fs/lockd/... |
290 |
} |
6bfbe8af4 lockd: Adjust nlm... |
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
/** * nlmsvc_lookup_host - Find an NLM host handle matching a remote client * @rqstp: incoming NLM request * @hostname: name of client host * @hostname_len: length of client hostname * * Returns an nlm_host structure that matches the [client address, * transport protocol, NLM version, client hostname] of the passed-in * NLM request. If one doesn't already exist in the host cache, a * new handle is created and returned. * * Before possibly creating a new nlm_host, construct a sockaddr * for a specific source address in case the local system has * multiple network addresses. The family of the address in * rq_daddr is guaranteed to be the same as the family of the * address in rq_addr, so it's safe to use the same family for * the source address. |
c585646dd [PATCH] fs/lockd/... |
308 |
*/ |
6bfbe8af4 lockd: Adjust nlm... |
309 310 311 |
struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, const char *hostname, const size_t hostname_len) |
c585646dd [PATCH] fs/lockd/... |
312 |
{ |
67216b94d lockd: Clean up n... |
313 314 315 316 |
struct hlist_head *chain; struct hlist_node *pos; struct nlm_host *host = NULL; struct nsm_handle *nsm = NULL; |
849a1cf13 SUNRPC: Replace s... |
317 318 |
struct sockaddr *src_sap = svc_daddr(rqstp); size_t src_len = rqstp->rq_daddrlen; |
7f1ed18bd NLM: Convert nlm_... |
319 320 |
struct nlm_lookup_host_info ni = { .server = 1, |
88541c848 lockd: Support no... |
321 322 |
.sap = svc_addr(rqstp), .salen = rqstp->rq_addrlen, |
7f1ed18bd NLM: Convert nlm_... |
323 324 325 326 |
.protocol = rqstp->rq_prot, .version = rqstp->rq_vers, .hostname = hostname, .hostname_len = hostname_len, |
7f1ed18bd NLM: Convert nlm_... |
327 328 329 330 331 332 |
}; dprintk("lockd: %s(host='%*s', vers=%u, proto=%s) ", __func__, (int)hostname_len, hostname, rqstp->rq_vers, (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); |
c98451bdb NLM: fix source a... |
333 |
|
67216b94d lockd: Clean up n... |
334 |
mutex_lock(&nlm_host_mutex); |
67216b94d lockd: Clean up n... |
335 336 |
if (time_after_eq(jiffies, next_gc)) nlm_gc_hosts(); |
d2df0484b lockd: Rename nlm... |
337 |
chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; |
67216b94d lockd: Clean up n... |
338 339 340 341 342 343 344 345 346 347 348 349 |
hlist_for_each_entry(host, pos, chain, h_hash) { if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) continue; /* Same address. Share an NSM handle if we already have one */ if (nsm == NULL) nsm = host->h_nsmhandle; if (host->h_proto != ni.protocol) continue; if (host->h_version != ni.version) continue; |
796918366 lockd: Remove src... |
350 |
if (!rpc_cmp_addr(nlm_srcaddr(host), src_sap)) |
67216b94d lockd: Clean up n... |
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
continue; /* Move to head of hash chain. */ hlist_del(&host->h_hash); hlist_add_head(&host->h_hash, chain); nlm_get_host(host); dprintk("lockd: %s found host %s (%s) ", __func__, host->h_name, host->h_addrbuf); goto out; } host = nlm_alloc_host(&ni, nsm); if (unlikely(host == NULL)) goto out; |
796918366 lockd: Remove src... |
367 368 |
memcpy(nlm_srcaddr(host), src_sap, src_len); host->h_srcaddrlen = src_len; |
67216b94d lockd: Clean up n... |
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
hlist_add_head(&host->h_hash, chain); nrhosts++; dprintk("lockd: %s created host %s (%s) ", __func__, host->h_name, host->h_addrbuf); out: mutex_unlock(&nlm_host_mutex); return host; } /** * nlmsvc_release_host - release server nlm_host * @host: nlm_host to release * * Host is destroyed later in nlm_gc_host(). */ void nlmsvc_release_host(struct nlm_host *host) { if (host == NULL) return; dprintk("lockd: release server host %s ", host->h_name); BUG_ON(atomic_read(&host->h_count) < 0); BUG_ON(!host->h_server); atomic_dec(&host->h_count); |
c585646dd [PATCH] fs/lockd/... |
398 399 400 |
} /* |
1da177e4c Linux-2.6.12-rc2 |
401 402 403 404 405 406 |
* Create the NLM RPC client for an NLM peer */ struct rpc_clnt * nlm_bind_host(struct nlm_host *host) { struct rpc_clnt *clnt; |
1da177e4c Linux-2.6.12-rc2 |
407 |
|
1df40b609 NLM: Remove addre... |
408 409 410 |
dprintk("lockd: nlm_bind_host %s (%s) ", host->h_name, host->h_addrbuf); |
1da177e4c Linux-2.6.12-rc2 |
411 412 |
/* Lock host handle */ |
504679141 NLM: sem to mutex... |
413 |
mutex_lock(&host->h_mutex); |
1da177e4c Linux-2.6.12-rc2 |
414 415 416 |
/* If we've already created an RPC client, check whether * RPC rebind is required |
1da177e4c Linux-2.6.12-rc2 |
417 418 |
*/ if ((clnt = host->h_rpcclnt) != NULL) { |
43118c29d [PATCH] RPC: get ... |
419 |
if (time_after_eq(jiffies, host->h_nextrebind)) { |
35f5a422c SUNRPC: new inter... |
420 |
rpc_force_rebind(clnt); |
1da177e4c Linux-2.6.12-rc2 |
421 |
host->h_nextrebind = jiffies + NLM_HOST_REBIND; |
1b333c54a lockd: address-fa... |
422 423 |
dprintk("lockd: next rebind in %lu jiffies ", |
1da177e4c Linux-2.6.12-rc2 |
424 425 426 |
host->h_nextrebind - jiffies); } } else { |
21051ba62 NLM: Fix locking ... |
427 |
unsigned long increment = nlmsvc_timeout; |
e1ec78928 LOCKD: Convert to... |
428 429 430 431 432 433 434 |
struct rpc_timeout timeparms = { .to_initval = increment, .to_increment = increment, .to_maxval = increment * 6UL, .to_retries = 5U, }; struct rpc_create_args args = { |
c653ce3f0 sunrpc: Add net t... |
435 |
.net = &init_net, |
e1ec78928 LOCKD: Convert to... |
436 |
.protocol = host->h_proto, |
b4ed58fd3 lockd: Use sockad... |
437 438 |
.address = nlm_addr(host), .addrsize = host->h_addrlen, |
e1ec78928 LOCKD: Convert to... |
439 440 441 442 443 |
.timeout = &timeparms, .servername = host->h_name, .program = &nlm_program, .version = host->h_version, .authflavor = RPC_AUTH_UNIX, |
90bd17c87 NLM: have server-... |
444 |
.flags = (RPC_CLNT_CREATE_NOPING | |
e1ec78928 LOCKD: Convert to... |
445 446 |
RPC_CLNT_CREATE_AUTOBIND), }; |
90bd17c87 NLM: have server-... |
447 448 449 450 451 452 453 |
/* * lockd retries server side blocks automatically so we want * those to be soft RPC calls. Client side calls need to be * hard RPC tasks. */ if (!host->h_server) args.flags |= RPC_CLNT_CREATE_HARDRTRY; |
0cb2659b8 NLM: allow lockd ... |
454 455 |
if (host->h_noresvport) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; |
8e35f8e7c NLM: Fix a regres... |
456 457 |
if (host->h_srcaddrlen) args.saddress = nlm_srcaddr(host); |
90bd17c87 NLM: have server-... |
458 |
|
e1ec78928 LOCKD: Convert to... |
459 460 461 462 463 464 465 466 |
clnt = rpc_create(&args); if (!IS_ERR(clnt)) host->h_rpcclnt = clnt; else { printk("lockd: couldn't create RPC handle for %s ", host->h_name); clnt = NULL; } |
1da177e4c Linux-2.6.12-rc2 |
467 |
} |
504679141 NLM: sem to mutex... |
468 |
mutex_unlock(&host->h_mutex); |
1da177e4c Linux-2.6.12-rc2 |
469 |
return clnt; |
1da177e4c Linux-2.6.12-rc2 |
470 471 472 473 474 475 476 477 478 479 480 |
} /* * Force a portmap lookup of the remote lockd port */ void nlm_rebind_host(struct nlm_host *host) { dprintk("lockd: rebind host %s ", host->h_name); if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) { |
35f5a422c SUNRPC: new inter... |
481 |
rpc_force_rebind(host->h_rpcclnt); |
1da177e4c Linux-2.6.12-rc2 |
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
host->h_nextrebind = jiffies + NLM_HOST_REBIND; } } /* * Increment NLM host count */ struct nlm_host * nlm_get_host(struct nlm_host *host) { if (host) { dprintk("lockd: get host %s ", host->h_name); atomic_inc(&host->h_count); host->h_expires = jiffies + NLM_HOST_EXPIRE; } return host; } |
b10e30f65 lockd: reorganize... |
499 500 501 502 |
static struct nlm_host *next_host_state(struct hlist_head *cache, struct nsm_handle *nsm, const struct nlm_reboot *info) { |
80c30e8de NLM: Fix "kernel ... |
503 |
struct nlm_host *host; |
b10e30f65 lockd: reorganize... |
504 505 506 507 508 509 510 511 512 513 514 |
struct hlist_head *chain; struct hlist_node *pos; mutex_lock(&nlm_host_mutex); for_each_host(host, pos, chain, cache) { if (host->h_nsmhandle == nsm && host->h_nsmstate != info->state) { host->h_nsmstate = info->state; host->h_state++; nlm_get_host(host); |
80c30e8de NLM: Fix "kernel ... |
515 516 |
mutex_unlock(&nlm_host_mutex); return host; |
b10e30f65 lockd: reorganize... |
517 518 |
} } |
80c30e8de NLM: Fix "kernel ... |
519 |
|
b10e30f65 lockd: reorganize... |
520 |
mutex_unlock(&nlm_host_mutex); |
80c30e8de NLM: Fix "kernel ... |
521 |
return NULL; |
b10e30f65 lockd: reorganize... |
522 |
} |
7fefc9cb9 NLM: Change nlm_h... |
523 524 525 526 527 528 |
/** * nlm_host_rebooted - Release all resources held by rebooted host * @info: pointer to decoded results of NLM_SM_NOTIFY call * * We were notified that the specified host has rebooted. Release * all resources held by that peer. |
cf712c24d [PATCH] knfsd: co... |
529 |
*/ |
7fefc9cb9 NLM: Change nlm_h... |
530 |
void nlm_host_rebooted(const struct nlm_reboot *info) |
cf712c24d [PATCH] knfsd: co... |
531 |
{ |
5c8dd29ca [PATCH] knfsd: lo... |
532 |
struct nsm_handle *nsm; |
0cea32761 [PATCH] knfsd: lo... |
533 |
struct nlm_host *host; |
cf712c24d [PATCH] knfsd: co... |
534 |
|
8c7378fd2 NLM: Call nsm_reb... |
535 536 |
nsm = nsm_reboot_lookup(info); if (unlikely(nsm == NULL)) |
db4e4c9a9 [PATCH] knfsd: wh... |
537 |
return; |
5c8dd29ca [PATCH] knfsd: lo... |
538 539 540 541 542 543 |
/* Mark all hosts tied to this NSM state as having rebooted. * We run the loop repeatedly, because we drop the host table * lock for this. * To avoid processing a host several times, we match the nsmstate. */ |
d2df0484b lockd: Rename nlm... |
544 |
while ((host = next_host_state(nlm_server_hosts, nsm, info)) != NULL) { |
8ea6ecc8b lockd: Create cli... |
545 |
nlmsvc_free_host_resources(host); |
67216b94d lockd: Clean up n... |
546 |
nlmsvc_release_host(host); |
cf712c24d [PATCH] knfsd: co... |
547 |
} |
8ea6ecc8b lockd: Create cli... |
548 549 550 551 |
while ((host = next_host_state(nlm_client_hosts, nsm, info)) != NULL) { nlmclnt_recovery(host); nlmclnt_release_host(host); } |
cdd30fa16 lockd: release re... |
552 |
nsm_release(nsm); |
cf712c24d [PATCH] knfsd: co... |
553 554 555 |
} /* |
1da177e4c Linux-2.6.12-rc2 |
556 557 558 559 560 561 |
* Shut down the hosts module. * Note that this routine is called only at server shutdown time. */ void nlm_shutdown_hosts(void) { |
0cea32761 [PATCH] knfsd: lo... |
562 563 |
struct hlist_head *chain; struct hlist_node *pos; |
1da177e4c Linux-2.6.12-rc2 |
564 |
struct nlm_host *host; |
1da177e4c Linux-2.6.12-rc2 |
565 566 567 |
dprintk("lockd: shutting down host module "); |
353ab6e97 [PATCH] sem2mutex... |
568 |
mutex_lock(&nlm_host_mutex); |
1da177e4c Linux-2.6.12-rc2 |
569 570 571 572 |
/* First, make all hosts eligible for gc */ dprintk("lockd: nuking all hosts... "); |
d2df0484b lockd: Rename nlm... |
573 |
for_each_host(host, pos, chain, nlm_server_hosts) { |
b11374688 lockd: define hos... |
574 575 576 577 |
host->h_expires = jiffies - 1; if (host->h_rpcclnt) { rpc_shutdown_client(host->h_rpcclnt); host->h_rpcclnt = NULL; |
d801b8616 NLM: tear down RP... |
578 |
} |
1da177e4c Linux-2.6.12-rc2 |
579 580 581 582 |
} /* Then, perform a garbage collection pass */ nlm_gc_hosts(); |
353ab6e97 [PATCH] sem2mutex... |
583 |
mutex_unlock(&nlm_host_mutex); |
1da177e4c Linux-2.6.12-rc2 |
584 585 |
/* complain if any hosts are left */ |
fcc072c78 lockd: Make nrhos... |
586 |
if (nrhosts != 0) { |
1da177e4c Linux-2.6.12-rc2 |
587 588 |
printk(KERN_WARNING "lockd: couldn't shutdown host module! "); |
fcc072c78 lockd: Make nrhos... |
589 590 |
dprintk("lockd: %lu hosts left: ", nrhosts); |
d2df0484b lockd: Rename nlm... |
591 |
for_each_host(host, pos, chain, nlm_server_hosts) { |
b11374688 lockd: define hos... |
592 593 594 595 |
dprintk(" %s (cnt %d use %d exp %ld) ", host->h_name, atomic_read(&host->h_count), host->h_inuse, host->h_expires); |
1da177e4c Linux-2.6.12-rc2 |
596 597 598 599 600 601 602 603 604 605 606 607 |
} } } /* * Garbage collect any unused NLM hosts. * This GC combines reference counting for async operations with * mark & sweep for resources held by remote clients. */ static void nlm_gc_hosts(void) { |
0cea32761 [PATCH] knfsd: lo... |
608 609 610 |
struct hlist_head *chain; struct hlist_node *pos, *next; struct nlm_host *host; |
1da177e4c Linux-2.6.12-rc2 |
611 612 613 |
dprintk("lockd: host garbage collection "); |
d2df0484b lockd: Rename nlm... |
614 |
for_each_host(host, pos, chain, nlm_server_hosts) |
b11374688 lockd: define hos... |
615 |
host->h_inuse = 0; |
1da177e4c Linux-2.6.12-rc2 |
616 617 618 |
/* Mark all hosts that hold locks, blocks or shares */ nlmsvc_mark_resources(); |
d2df0484b lockd: Rename nlm... |
619 |
for_each_host_safe(host, pos, next, chain, nlm_server_hosts) { |
b11374688 lockd: define hos... |
620 621 622 623 624 625 626 627 |
if (atomic_read(&host->h_count) || host->h_inuse || time_before(jiffies, host->h_expires)) { dprintk("nlm_gc_hosts skipping %s " "(cnt %d use %d exp %ld) ", host->h_name, atomic_read(&host->h_count), host->h_inuse, host->h_expires); continue; |
1da177e4c Linux-2.6.12-rc2 |
628 |
} |
723bb5b50 lockd: Add nlm_de... |
629 |
nlm_destroy_host_locked(host); |
1da177e4c Linux-2.6.12-rc2 |
630 631 632 633 |
} next_gc = jiffies + NLM_HOST_COLLECT; } |