FreeBSD/sys/nlm/nlm_prot_impl.c
/*
 * Search for an existing NLM host that matches the given name
 * (typically the caller_name element of an nlm4_lock).  If none is
 * found, create a new host. If 'addr' is non-NULL, record the remote
 * address of the host so that we can call it back for async
 * responses. If 'vers' is greater than zero then record the NLM
 * program version to use to communicate with this client.
 */
Search for an existing NLM host that matches the given name
(typically the caller_name element of an nlm4_lock).  If none is
found, create a new host. If 'addr' is non-NULL, record the remote
address of the host so that we can call it back for async
responses. If 'vers' is greater than zero then record the NLM
program version to use to communicate with this client.
Search for an existing NLM host that matches the given name ( typically the caller_name element of an nlm4_lock ) . If none is found create a new host . If ' addr ' is non - NULL record the remote address of the host so that we can call it back for async responses . If ' vers ' is greater than zero then record the NLM program version to use to communicate with this client .
struct nlm_host *
nlm_find_host_by_name(const char *name, const struct sockaddr *addr,
    rpcvers_t vers)
{
	struct nlm_host *host;
	mtx_lock(&nlm_global_lock);
	TAILQ_FOREACH(host, &nlm_hosts, nh_link) {
		if (!strcmp(host->nh_caller_name, name))
			break;
	}
	if (!host) {
		host = nlm_create_host(name);
		if (!host) {
			mtx_unlock(&nlm_global_lock);
			return (NULL);
		}
	}
	refcount_acquire(&host->nh_refs);
	host->nh_idle_timeout = time_uptime + NLM_IDLE_TIMEOUT;
	if (addr) {
		KASSERT(addr->sa_len < sizeof(struct sockaddr_storage),
		    ("Strange remote transport address length"));
		if (host->nh_addr.ss_len && host->nh_srvrpc.nr_client) {
			if (!nlm_compare_addr(
				    (struct sockaddr *) &host->nh_addr,
				    addr)
			    || host->nh_vers != vers) {
				CLIENT *client;
				mtx_lock(&host->nh_lock);
				client = host->nh_srvrpc.nr_client;
				host->nh_srvrpc.nr_client = NULL;
				mtx_unlock(&host->nh_lock);
				if (client) {
					CLNT_RELEASE(client);
				}
			}
		}
		memcpy(&host->nh_addr, addr, addr->sa_len);
		host->nh_vers = vers;
	}
	nlm_check_idle();
	mtx_unlock(&nlm_global_lock);
	return (host);
}
struct nlm_host * nlm_find_host_by_name ( const char * name , const struct sockaddr * addr , rpcvers_t vers ) { struct nlm_host * host ; mtx_lock ( & nlm_global_lock ) ; TAILQ_FOREACH ( host , & nlm_hosts , nh_link ) { if ( ! strcmp ( host -> nh_caller_name , name ) ) break ; } if ( ! host ) { host = nlm_create_host ( name ) ; if ( ! host ) { mtx_unlock ( & nlm_global_lock ) ; return ( NULL ) ; } } refcount_acquire ( & host -> nh_refs ) ; host -> nh_idle_timeout = time_uptime + NLM_IDLE_TIMEOUT ; if ( addr ) { KASSERT ( addr -> sa_len < sizeof ( struct sockaddr_storage ) , ( " " ) ) ; if ( host -> nh_addr . ss_len && host -> nh_srvrpc . nr_client ) { if ( ! nlm_compare_addr ( ( struct sockaddr * ) & host -> nh_addr , addr ) || host -> nh_vers != vers ) { CLIENT * client ; mtx_lock ( & host -> nh_lock ) ; client = host -> nh_srvrpc . nr_client ; host -> nh_srvrpc . nr_client = NULL ; mtx_unlock ( & host -> nh_lock ) ; if ( client ) { CLNT_RELEASE ( client ) ; } } } memcpy ( & host -> nh_addr , addr , addr -> sa_len ) ; host -> nh_vers = vers ; } nlm_check_idle ( ) ; mtx_unlock ( & nlm_global_lock ) ; return ( host ) ; }
Search for an existing NLM host that matches the given name
 (typically the caller_name element of an nlm4_lock).
Search for an existing NLM host that matches the given name ( typically the caller_name element of an nlm4_lock ) .
/*
	 * The remote host is determined by caller_name.
	 */ /*
	 * If we have an address for the host, record it so that we
	 * can send async replies etc.
	 */ /*
		 * If we have seen an address before and we currently
		 * have an RPC client handle, make sure the address is
		 * the same, otherwise discard the client handle.
		 */