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