1bbaa8b60SDan Kruchinin /* 2bbaa8b60SDan Kruchinin * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 3bbaa8b60SDan Kruchinin * Authors: Doug Rabson <dfr@rabson.org> 4bbaa8b60SDan Kruchinin * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 5bbaa8b60SDan Kruchinin * 6bbaa8b60SDan Kruchinin * Redistribution and use in source and binary forms, with or without 7bbaa8b60SDan Kruchinin * modification, are permitted provided that the following conditions 8bbaa8b60SDan Kruchinin * are met: 9bbaa8b60SDan Kruchinin * 1. Redistributions of source code must retain the above copyright 10bbaa8b60SDan Kruchinin * notice, this list of conditions and the following disclaimer. 11bbaa8b60SDan Kruchinin * 2. Redistributions in binary form must reproduce the above copyright 12bbaa8b60SDan Kruchinin * notice, this list of conditions and the following disclaimer in the 13bbaa8b60SDan Kruchinin * documentation and/or other materials provided with the distribution. 14bbaa8b60SDan Kruchinin * 15bbaa8b60SDan Kruchinin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16bbaa8b60SDan Kruchinin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17bbaa8b60SDan Kruchinin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18bbaa8b60SDan Kruchinin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19bbaa8b60SDan Kruchinin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20bbaa8b60SDan Kruchinin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21bbaa8b60SDan Kruchinin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22bbaa8b60SDan Kruchinin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23bbaa8b60SDan Kruchinin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24bbaa8b60SDan Kruchinin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25bbaa8b60SDan Kruchinin * SUCH DAMAGE. 26bbaa8b60SDan Kruchinin * 27bbaa8b60SDan Kruchinin * $FreeBSD$ 28bbaa8b60SDan Kruchinin */ 29bbaa8b60SDan Kruchinin 30bbaa8b60SDan Kruchinin /* 31*54b3584eSGordon Ross * Copyright 2019 Nexenta by DDN, Inc. All rights reserved. 32bbaa8b60SDan Kruchinin * Copyright (c) 2012 by Delphix. All rights reserved. 33bbaa8b60SDan Kruchinin */ 34bbaa8b60SDan Kruchinin 35bbaa8b60SDan Kruchinin /* 36bbaa8b60SDan Kruchinin * NFS Lock Manager (NLM) private declarations, etc. 37bbaa8b60SDan Kruchinin * 38bbaa8b60SDan Kruchinin * Source code derived from FreeBSD nlm.h 39bbaa8b60SDan Kruchinin */ 40bbaa8b60SDan Kruchinin 41bbaa8b60SDan Kruchinin #ifndef _NLM_NLM_H_ 42bbaa8b60SDan Kruchinin #define _NLM_NLM_H_ 43bbaa8b60SDan Kruchinin 44bbaa8b60SDan Kruchinin #include <sys/cmn_err.h> 45bbaa8b60SDan Kruchinin #include <sys/queue.h> 46bbaa8b60SDan Kruchinin #include <sys/modhash.h> 47bbaa8b60SDan Kruchinin #include <sys/avl.h> 48bbaa8b60SDan Kruchinin 49bbaa8b60SDan Kruchinin #define RPC_MSGOUT(args...) cmn_err(CE_NOTE, args) 50bbaa8b60SDan Kruchinin #define NLM_ERR(...) cmn_err(CE_NOTE, __VA_ARGS__) 51bbaa8b60SDan Kruchinin #define NLM_WARN(...) cmn_err(CE_WARN, __VA_ARGS__) 52bbaa8b60SDan Kruchinin 53bbaa8b60SDan Kruchinin #ifndef SEEK_SET 54bbaa8b60SDan Kruchinin #define SEEK_SET 0 55bbaa8b60SDan Kruchinin #endif 56bbaa8b60SDan Kruchinin #ifndef SEEK_CUR 57bbaa8b60SDan Kruchinin #define SEEK_CUR 1 58bbaa8b60SDan Kruchinin #endif 59bbaa8b60SDan Kruchinin #ifndef SEEK_END 60bbaa8b60SDan Kruchinin #define SEEK_END 2 61bbaa8b60SDan Kruchinin #endif 62bbaa8b60SDan Kruchinin 63bbaa8b60SDan Kruchinin /* 64bbaa8b60SDan Kruchinin * Maximum offset supported by NLM calls using the older 65bbaa8b60SDan Kruchinin * (32-bit) versions of the protocol. 66bbaa8b60SDan Kruchinin */ 67bbaa8b60SDan Kruchinin #define MAX_UOFF32 0xffffffffULL 68bbaa8b60SDan Kruchinin 69bbaa8b60SDan Kruchinin struct nlm_host; 70bbaa8b60SDan Kruchinin struct vnode; 71bbaa8b60SDan Kruchinin struct exportinfo; 72bbaa8b60SDan Kruchinin struct shrlock; 73bbaa8b60SDan Kruchinin struct _kthread; 74bbaa8b60SDan Kruchinin 75bbaa8b60SDan Kruchinin /* 76bbaa8b60SDan Kruchinin * How to read the code: probably the best point to start 77bbaa8b60SDan Kruchinin * it the nlm_host structure that is sort of most major 78bbaa8b60SDan Kruchinin * structure in klmmod. nlm_host is closely tied with all 79bbaa8b60SDan Kruchinin * other NLM structures. 80bbaa8b60SDan Kruchinin * 81bbaa8b60SDan Kruchinin * There're three major locks we use inside NLM: 82bbaa8b60SDan Kruchinin * 1) Global read-write lock (lm_lck) that is used to 83bbaa8b60SDan Kruchinin * protect operations with sysid allocation and 84bbaa8b60SDan Kruchinin * management of zone globals structures for each 85bbaa8b60SDan Kruchinin * zone. 86bbaa8b60SDan Kruchinin * 2) Zone global lock: (nlm_globals->lock) is a mutex 87bbaa8b60SDan Kruchinin * used to protect all operations inside particular 88bbaa8b60SDan Kruchinin * zone. 89bbaa8b60SDan Kruchinin * 3) Host's lock: (nlm_host->nh_lock) is per-host mutex 90bbaa8b60SDan Kruchinin * used to protect host's internal fields and all 91bbaa8b60SDan Kruchinin * operations with the given host. 92bbaa8b60SDan Kruchinin * 93bbaa8b60SDan Kruchinin * Locks order _must_ obey the following scheme: 94bbaa8b60SDan Kruchinin * lm_lck then nlm_globals->lock then nlm_host->nh_lock 95bbaa8b60SDan Kruchinin * 96bbaa8b60SDan Kruchinin * Locks: 97bbaa8b60SDan Kruchinin * (g) locked by lm_lck 98bbaa8b60SDan Kruchinin * (z) locked by nlm_globals->lock 99bbaa8b60SDan Kruchinin * (l) locked by host->nh_lock 100bbaa8b60SDan Kruchinin * (c) const until freeing 101bbaa8b60SDan Kruchinin */ 102bbaa8b60SDan Kruchinin 103bbaa8b60SDan Kruchinin /* 104bbaa8b60SDan Kruchinin * Callback functions for nlm_do_lock() and others. 105bbaa8b60SDan Kruchinin * 106bbaa8b60SDan Kruchinin * Calls to nlm_do_lock are unusual, because it needs to handle 107bbaa8b60SDan Kruchinin * the reply itself, instead of letting it happen the normal way. 108bbaa8b60SDan Kruchinin * It also needs to make an RPC call _back_ to the client when a 109bbaa8b60SDan Kruchinin * blocked lock request completes. 110bbaa8b60SDan Kruchinin * 111bbaa8b60SDan Kruchinin * We pass three callback functions to nlm_do_lock: 112bbaa8b60SDan Kruchinin * nlm_reply_cb: send a normal RPC reply 113bbaa8b60SDan Kruchinin * nlm_res_cb: do a _res (message style) RPC (call) 114*54b3584eSGordon Ross * nlm_granted_cb: do a "granted" RPC call (after blocking) 115bbaa8b60SDan Kruchinin * Only one of the 1st or 2nd is used. 116bbaa8b60SDan Kruchinin * The 3rd is used only for blocking 117bbaa8b60SDan Kruchinin * 118bbaa8b60SDan Kruchinin * We also use callback functions for all the _msg variants 119bbaa8b60SDan Kruchinin * of the NLM svc calls, where the reply is a reverse call. 120bbaa8b60SDan Kruchinin * The nlm_testres_cb is used by the _test_msg svc calls. 121bbaa8b60SDan Kruchinin * The nlm_res_cb type is used by the other _msg calls. 122bbaa8b60SDan Kruchinin */ 123bbaa8b60SDan Kruchinin typedef bool_t (*nlm_reply_cb)(SVCXPRT *, nlm4_res *); 124bbaa8b60SDan Kruchinin typedef enum clnt_stat (*nlm_res_cb)(nlm4_res *, void *, CLIENT *); 125*54b3584eSGordon Ross typedef enum clnt_stat (*nlm_granted_cb)(nlm4_testargs *, nlm4_res *, CLIENT *); 126bbaa8b60SDan Kruchinin typedef enum clnt_stat (*nlm_testres_cb)(nlm4_testres *, void *, CLIENT *); 127bbaa8b60SDan Kruchinin 128bbaa8b60SDan Kruchinin /* 129bbaa8b60SDan Kruchinin * NLM sleeping lock request. 130bbaa8b60SDan Kruchinin * 131bbaa8b60SDan Kruchinin * Sleeping lock requests are server side only objects 132bbaa8b60SDan Kruchinin * that are created when client asks server to add new 133bbaa8b60SDan Kruchinin * sleeping lock and when this lock needs to block. 134bbaa8b60SDan Kruchinin * Server keeps a track of these requests in order to be 135bbaa8b60SDan Kruchinin * able to cancel them or clean them up. 136bbaa8b60SDan Kruchinin * 137bbaa8b60SDan Kruchinin * Sleeping lock requests are closely tiled with particular 138bbaa8b60SDan Kruchinin * vnode or, strictly speaking, NLM vhold object that holds 139bbaa8b60SDan Kruchinin * the vnode. 140bbaa8b60SDan Kruchinin * 141bbaa8b60SDan Kruchinin * struct nlm_slreq: 142bbaa8b60SDan Kruchinin * nsr_fl: an information about file lock 143bbaa8b60SDan Kruchinin * nsr_link: a list node to store lock requests 144bbaa8b60SDan Kruchinin * in vhold object. 145bbaa8b60SDan Kruchinin */ 146bbaa8b60SDan Kruchinin struct nlm_slreq { 147bbaa8b60SDan Kruchinin struct flock64 nsr_fl; 148bbaa8b60SDan Kruchinin TAILQ_ENTRY(nlm_slreq) nsr_link; 149bbaa8b60SDan Kruchinin }; 150bbaa8b60SDan Kruchinin TAILQ_HEAD(nlm_slreq_list, nlm_slreq); 151bbaa8b60SDan Kruchinin 152bbaa8b60SDan Kruchinin /* 153bbaa8b60SDan Kruchinin * NLM vhold object is a sort of wrapper on vnodes remote 154bbaa8b60SDan Kruchinin * clients have locked (or added share reservation) 155bbaa8b60SDan Kruchinin * on NLM server. Vhold keeps vnode held (by VN_HOLD()) 156bbaa8b60SDan Kruchinin * while vnode has any locks or shares made by parent host. 157bbaa8b60SDan Kruchinin * Vholds are used for two purposes: 158bbaa8b60SDan Kruchinin * 1) Hold vnode (with VN_HOLD) while it has any locks; 159bbaa8b60SDan Kruchinin * 2) Keep a track of all vnodes remote host touched 160bbaa8b60SDan Kruchinin * with lock/share operations on NLM server, so that NLM 161bbaa8b60SDan Kruchinin * can know what vnodes are potentially locked; 162bbaa8b60SDan Kruchinin * 163bbaa8b60SDan Kruchinin * Vholds are used on server side only. For server side it's really 164bbaa8b60SDan Kruchinin * important to keep vnodes held while they potentially have 165bbaa8b60SDan Kruchinin * any locks/shares. In contrast, it's not important for clinet 166bbaa8b60SDan Kruchinin * side at all. When particular vnode comes to the NLM client side 167bbaa8b60SDan Kruchinin * code, it's already held (VN_HOLD) by the process calling 168bbaa8b60SDan Kruchinin * lock/share function (it's referenced because client calls open() 169bbaa8b60SDan Kruchinin * before making locks or shares). 170bbaa8b60SDan Kruchinin * 171bbaa8b60SDan Kruchinin * Each NLM host object has a collection of vholds associated 172bbaa8b60SDan Kruchinin * with vnodes host touched earlier by adding locks or shares. 173bbaa8b60SDan Kruchinin * Having this collection allows us to decide if host is still 174bbaa8b60SDan Kruchinin * in use. When it has any vhold objects it's considered to be 175bbaa8b60SDan Kruchinin * in use. Otherwise we're free to destroy it. 176bbaa8b60SDan Kruchinin * 177bbaa8b60SDan Kruchinin * Vholds are destroyed by the NLM garbage collecter thread that 178bbaa8b60SDan Kruchinin * periodically checks whether they have any locks or shares. 179bbaa8b60SDan Kruchinin * Checking occures when parent host is untouched by client 180bbaa8b60SDan Kruchinin * or server for some period of time. 181bbaa8b60SDan Kruchinin * 182bbaa8b60SDan Kruchinin * struct nlm_vhold: 183bbaa8b60SDan Kruchinin * nv_vp: a pointer to vnode that is hold by given nlm_vhold 184bbaa8b60SDan Kruchinin * nv_refcnt: reference counter (non zero when vhold is inuse) 185bbaa8b60SDan Kruchinin * nv_slreqs: sleeping lock requests that were made on the nv_vp 186bbaa8b60SDan Kruchinin * nv_link: list node to store vholds in host's nh_vnodes_list 187bbaa8b60SDan Kruchinin */ 188bbaa8b60SDan Kruchinin struct nlm_vhold { 189bbaa8b60SDan Kruchinin vnode_t *nv_vp; /* (c) */ 190bbaa8b60SDan Kruchinin int nv_refcnt; /* (l) */ 191bbaa8b60SDan Kruchinin struct nlm_slreq_list nv_slreqs; /* (l) */ 192bbaa8b60SDan Kruchinin TAILQ_ENTRY(nlm_vhold) nv_link; /* (l) */ 193bbaa8b60SDan Kruchinin }; 194bbaa8b60SDan Kruchinin TAILQ_HEAD(nlm_vhold_list, nlm_vhold); 195bbaa8b60SDan Kruchinin 196bbaa8b60SDan Kruchinin /* 197bbaa8b60SDan Kruchinin * Client side sleeping lock state. 198bbaa8b60SDan Kruchinin * - NLM_SL_BLOCKED: some thread is blocked on this lock 199bbaa8b60SDan Kruchinin * - NLM_SL_GRANTED: server granted us the lock 200bbaa8b60SDan Kruchinin * - NLM_SL_CANCELLED: the lock is cancelled (i.e. invalid/inactive) 201bbaa8b60SDan Kruchinin */ 202bbaa8b60SDan Kruchinin typedef enum nlm_slock_state { 203bbaa8b60SDan Kruchinin NLM_SL_UNKNOWN = 0, 204bbaa8b60SDan Kruchinin NLM_SL_BLOCKED, 205bbaa8b60SDan Kruchinin NLM_SL_GRANTED, 206bbaa8b60SDan Kruchinin NLM_SL_CANCELLED 207bbaa8b60SDan Kruchinin } nlm_slock_state_t; 208bbaa8b60SDan Kruchinin 209bbaa8b60SDan Kruchinin /* 210bbaa8b60SDan Kruchinin * A client side sleeping lock request (set by F_SETLKW) 211bbaa8b60SDan Kruchinin * stored in nlm_slocks collection of nlm_globals. 212bbaa8b60SDan Kruchinin * 213bbaa8b60SDan Kruchinin * struct nlm_slock 214bbaa8b60SDan Kruchinin * nsl_state: Sleeping lock state. 215bbaa8b60SDan Kruchinin * (see nlm_slock_state for more information) 216bbaa8b60SDan Kruchinin * nsl_cond: Condvar that is used when sleeping lock 217bbaa8b60SDan Kruchinin * needs to wait for a GRANT callback 218bbaa8b60SDan Kruchinin * or cancellation event. 219bbaa8b60SDan Kruchinin * nsl_lock: nlm4_lock structure that is sent to the server 220bbaa8b60SDan Kruchinin * nsl_fh: Filehandle that corresponds to nw_vp 221bbaa8b60SDan Kruchinin * nsl_host: A host owning this sleeping lock 222bbaa8b60SDan Kruchinin * nsl_vp: A vnode sleeping lock is waiting on. 223bbaa8b60SDan Kruchinin * nsl_link: A list node for nlm_globals->nlm_slocks list. 224bbaa8b60SDan Kruchinin */ 225bbaa8b60SDan Kruchinin struct nlm_slock { 226bbaa8b60SDan Kruchinin nlm_slock_state_t nsl_state; /* (z) */ 227bbaa8b60SDan Kruchinin kcondvar_t nsl_cond; /* (z) */ 228bbaa8b60SDan Kruchinin nlm4_lock nsl_lock; /* (c) */ 229bbaa8b60SDan Kruchinin struct netobj nsl_fh; /* (c) */ 230bbaa8b60SDan Kruchinin struct nlm_host *nsl_host; /* (c) */ 231bbaa8b60SDan Kruchinin struct vnode *nsl_vp; /* (c) */ 232bbaa8b60SDan Kruchinin TAILQ_ENTRY(nlm_slock) nsl_link; /* (z) */ 233bbaa8b60SDan Kruchinin }; 234bbaa8b60SDan Kruchinin TAILQ_HEAD(nlm_slock_list, nlm_slock); 235bbaa8b60SDan Kruchinin 236bbaa8b60SDan Kruchinin /* 237bbaa8b60SDan Kruchinin * Share reservation description. NLM tracks all active 238bbaa8b60SDan Kruchinin * share reservations made by the client side, so that 239bbaa8b60SDan Kruchinin * they can be easily recovered if remote NLM server 240bbaa8b60SDan Kruchinin * reboots. Share reservations tracking is also useful 241bbaa8b60SDan Kruchinin * when NLM needs to determine whether host owns any 242bbaa8b60SDan Kruchinin * resources on the system and can't be destroyed. 243bbaa8b60SDan Kruchinin * 244bbaa8b60SDan Kruchinin * nlm_shres: 245bbaa8b60SDan Kruchinin * ns_shr: share reservation description 246bbaa8b60SDan Kruchinin * ns_vp: a pointer to vnode where share reservation is located 247bbaa8b60SDan Kruchinin * ns_next: next nlm_shres instance (or NULL if next item isn't 248bbaa8b60SDan Kruchinin * present). 249bbaa8b60SDan Kruchinin */ 250bbaa8b60SDan Kruchinin struct nlm_shres { 251bbaa8b60SDan Kruchinin struct shrlock *ns_shr; 252bbaa8b60SDan Kruchinin vnode_t *ns_vp; 253bbaa8b60SDan Kruchinin struct nlm_shres *ns_next; 254bbaa8b60SDan Kruchinin }; 255bbaa8b60SDan Kruchinin 256bbaa8b60SDan Kruchinin /* 257bbaa8b60SDan Kruchinin * NLM RPC handle object. 258bbaa8b60SDan Kruchinin * 259bbaa8b60SDan Kruchinin * In kRPC subsystem it's unsafe to use one RPC handle by 260bbaa8b60SDan Kruchinin * several threads simultaneously. It was designed so that 261bbaa8b60SDan Kruchinin * each thread has to create an RPC handle that it'll use. 262bbaa8b60SDan Kruchinin * RPC handle creation can be quite expensive operation, especially 263bbaa8b60SDan Kruchinin * with session oriented protocols (such as TCP) that need to 264bbaa8b60SDan Kruchinin * establish session at first. NLM RPC handle object is a sort of 265bbaa8b60SDan Kruchinin * wrapper on kRPC handle object that can be cached and used in 266bbaa8b60SDan Kruchinin * future. We store all created RPC handles for given host in a 267bbaa8b60SDan Kruchinin * host's RPC handles cache, so that to make new requests threads 268bbaa8b60SDan Kruchinin * can simply take ready objects from the cache. That improves 269bbaa8b60SDan Kruchinin * NLM performance. 270bbaa8b60SDan Kruchinin * 271bbaa8b60SDan Kruchinin * nlm_rpc_t: 272bbaa8b60SDan Kruchinin * nr_handle: a kRPC handle itself. 273bbaa8b60SDan Kruchinin * nr_vers: a version of NLM protocol kRPC handle was 274bbaa8b60SDan Kruchinin * created for. 275bbaa8b60SDan Kruchinin * nr_link: a list node to store NLM RPC handles in the host 276bbaa8b60SDan Kruchinin * RPC handles cache. 277bbaa8b60SDan Kruchinin */ 278bbaa8b60SDan Kruchinin typedef struct nlm_rpc { 279bbaa8b60SDan Kruchinin CLIENT *nr_handle; /* (l) */ 280bbaa8b60SDan Kruchinin rpcvers_t nr_vers; /* (c) */ 281bbaa8b60SDan Kruchinin TAILQ_ENTRY(nlm_rpc) nr_link; /* (l) */ 282bbaa8b60SDan Kruchinin } nlm_rpc_t; 283bbaa8b60SDan Kruchinin TAILQ_HEAD(nlm_rpch_list, nlm_rpc); 284bbaa8b60SDan Kruchinin 285bbaa8b60SDan Kruchinin /* 286bbaa8b60SDan Kruchinin * Describes the state of NLM host's RPC binding. 287bbaa8b60SDan Kruchinin * RPC binding can be in one of three states: 288bbaa8b60SDan Kruchinin * 1) NRPCB_NEED_UPDATE: 289bbaa8b60SDan Kruchinin * Binding is either not initialized or stale. 290bbaa8b60SDan Kruchinin * 2) NRPCB_UPDATE_INPROGRESS: 291bbaa8b60SDan Kruchinin * When some thread updates host's RPC binding, 292bbaa8b60SDan Kruchinin * it sets binding's state to NRPCB_UPDATE_INPROGRESS 293bbaa8b60SDan Kruchinin * which denotes that other threads must wait until 294bbaa8b60SDan Kruchinin * update process is finished. 295bbaa8b60SDan Kruchinin * 3) NRPCB_UPDATED: 296bbaa8b60SDan Kruchinin * Denotes that host's RPC binding is both initialized 297bbaa8b60SDan Kruchinin * and fresh. 298bbaa8b60SDan Kruchinin */ 299bbaa8b60SDan Kruchinin enum nlm_rpcb_state { 300bbaa8b60SDan Kruchinin NRPCB_NEED_UPDATE = 0, 301bbaa8b60SDan Kruchinin NRPCB_UPDATE_INPROGRESS, 302bbaa8b60SDan Kruchinin NRPCB_UPDATED 303bbaa8b60SDan Kruchinin }; 304bbaa8b60SDan Kruchinin 305bbaa8b60SDan Kruchinin /* 306bbaa8b60SDan Kruchinin * NLM host flags 307bbaa8b60SDan Kruchinin */ 308bbaa8b60SDan Kruchinin #define NLM_NH_MONITORED 0x01 309bbaa8b60SDan Kruchinin #define NLM_NH_RECLAIM 0x02 310bbaa8b60SDan Kruchinin #define NLM_NH_INIDLE 0x04 311bbaa8b60SDan Kruchinin #define NLM_NH_SUSPEND 0x08 312bbaa8b60SDan Kruchinin 313bbaa8b60SDan Kruchinin /* 314bbaa8b60SDan Kruchinin * NLM host object is the most major structure in NLM. 315bbaa8b60SDan Kruchinin * It identifies remote client or remote server or both. 316bbaa8b60SDan Kruchinin * NLM host object keep a track of all vnodes client/server 317bbaa8b60SDan Kruchinin * locked and all sleeping locks it has. All lock/unlock 318bbaa8b60SDan Kruchinin * operations are done using host object. 319bbaa8b60SDan Kruchinin * 320bbaa8b60SDan Kruchinin * nlm_host: 321bbaa8b60SDan Kruchinin * nh_lock: a mutex protecting host object fields 322bbaa8b60SDan Kruchinin * nh_refs: reference counter. Identifies how many threads 323bbaa8b60SDan Kruchinin * uses this host object. 324bbaa8b60SDan Kruchinin * nh_link: a list node for keeping host in zone-global list. 325bbaa8b60SDan Kruchinin * nh_by_addr: an AVL tree node for keeping host in zone-global tree. 326bbaa8b60SDan Kruchinin * Host can be looked up in the tree by <netid, address> 327bbaa8b60SDan Kruchinin * pair. 328bbaa8b60SDan Kruchinin * nh_name: host name. 329bbaa8b60SDan Kruchinin * nh_netid: netid string identifying type of transport host uses. 330bbaa8b60SDan Kruchinin * nh_knc: host's knetconfig (used by kRPC subsystem). 331bbaa8b60SDan Kruchinin * nh_addr: host's address (either IPv4 or IPv6). 332bbaa8b60SDan Kruchinin * nh_sysid: unique sysid associated with this host. 333bbaa8b60SDan Kruchinin * nh_state: last seen host's state reported by NSM. 334bbaa8b60SDan Kruchinin * nh_flags: ORed host flags. 335bbaa8b60SDan Kruchinin * nh_idle_timeout: host idle timeout. When expired host is freed. 336bbaa8b60SDan Kruchinin * nh_recl_cv: condition variable used for reporting that reclamation 337bbaa8b60SDan Kruchinin * process is finished. 338bbaa8b60SDan Kruchinin * nh_rpcb_cv: condition variable that is used to make sure 339bbaa8b60SDan Kruchinin * that only one thread renews host's RPC binding. 340bbaa8b60SDan Kruchinin * nh_rpcb_ustat: error code returned by RPC binding update operation. 341bbaa8b60SDan Kruchinin * nh_rpcb_state: host's RPC binding state (see enum nlm_rpcb_state 342bbaa8b60SDan Kruchinin * for more details). 343bbaa8b60SDan Kruchinin * nh_rpchc: host's RPC handles cache. 344bbaa8b60SDan Kruchinin * nh_vholds_by_vp: a hash table of all vholds host owns. (used for lookup) 345bbaa8b60SDan Kruchinin * nh_vholds_list: a linked list of all vholds host owns. (used for iteration) 346bbaa8b60SDan Kruchinin * nh_shrlist: a list of all active share resevations on the client side. 347bbaa8b60SDan Kruchinin * nh_reclaimer: a pointer to reclamation thread (kthread_t) 348bbaa8b60SDan Kruchinin * NULL if reclamation thread doesn't exist 349bbaa8b60SDan Kruchinin */ 350bbaa8b60SDan Kruchinin struct nlm_host { 351bbaa8b60SDan Kruchinin kmutex_t nh_lock; /* (c) */ 352bbaa8b60SDan Kruchinin volatile uint_t nh_refs; /* (z) */ 353bbaa8b60SDan Kruchinin TAILQ_ENTRY(nlm_host) nh_link; /* (z) */ 354bbaa8b60SDan Kruchinin avl_node_t nh_by_addr; /* (z) */ 355bbaa8b60SDan Kruchinin char *nh_name; /* (c) */ 356bbaa8b60SDan Kruchinin char *nh_netid; /* (c) */ 357bbaa8b60SDan Kruchinin struct knetconfig nh_knc; /* (c) */ 358bbaa8b60SDan Kruchinin struct netbuf nh_addr; /* (c) */ 359bbaa8b60SDan Kruchinin sysid_t nh_sysid; /* (c) */ 360bbaa8b60SDan Kruchinin int32_t nh_state; /* (z) */ 361bbaa8b60SDan Kruchinin clock_t nh_idle_timeout; /* (z) */ 362bbaa8b60SDan Kruchinin uint8_t nh_flags; /* (z) */ 363bbaa8b60SDan Kruchinin kcondvar_t nh_recl_cv; /* (z) */ 364bbaa8b60SDan Kruchinin kcondvar_t nh_rpcb_cv; /* (l) */ 365bbaa8b60SDan Kruchinin enum clnt_stat nh_rpcb_ustat; /* (l) */ 366bbaa8b60SDan Kruchinin enum nlm_rpcb_state nh_rpcb_state; /* (l) */ 367bbaa8b60SDan Kruchinin struct nlm_rpch_list nh_rpchc; /* (l) */ 368bbaa8b60SDan Kruchinin mod_hash_t *nh_vholds_by_vp; /* (l) */ 369bbaa8b60SDan Kruchinin struct nlm_vhold_list nh_vholds_list; /* (l) */ 370bbaa8b60SDan Kruchinin struct nlm_shres *nh_shrlist; /* (l) */ 371bbaa8b60SDan Kruchinin kthread_t *nh_reclaimer; /* (l) */ 372bbaa8b60SDan Kruchinin }; 373bbaa8b60SDan Kruchinin TAILQ_HEAD(nlm_host_list, nlm_host); 374bbaa8b60SDan Kruchinin 375bbaa8b60SDan Kruchinin /* 376bbaa8b60SDan Kruchinin * nlm_nsm structure describes RPC client handle that can be 377bbaa8b60SDan Kruchinin * used to communicate with local NSM via kRPC. 378bbaa8b60SDan Kruchinin * 379bbaa8b60SDan Kruchinin * We need to wrap handle with nlm_nsm structure because kRPC 380bbaa8b60SDan Kruchinin * can not share one handle between several threads. It's assumed 381bbaa8b60SDan Kruchinin * that NLM uses only one NSM handle per zone, thus all RPC operations 382bbaa8b60SDan Kruchinin * on NSM's handle are serialized using nlm_nsm->sem semaphore. 383bbaa8b60SDan Kruchinin * 384bbaa8b60SDan Kruchinin * nlm_nsm also contains refcnt field used for reference counting. 385bbaa8b60SDan Kruchinin * It's used because there exist a possibility of simultaneous 386bbaa8b60SDan Kruchinin * execution of NLM shutdown operation and host monitor/unmonitor 387bbaa8b60SDan Kruchinin * operations. 388bbaa8b60SDan Kruchinin * 389bbaa8b60SDan Kruchinin * struct nlm_nsm: 390bbaa8b60SDan Kruchinin * ns_sem: a semaphore for serialization network operations to statd 391bbaa8b60SDan Kruchinin * ns_knc: a kneconfig describing transport that is used for communication 392bbaa8b60SDan Kruchinin * ns_addr: an address of local statd we're talking to 393bbaa8b60SDan Kruchinin * ns_handle: an RPC handle used for talking to local statd using the status 394bbaa8b60SDan Kruchinin * monitor protocol (SM_PROG) 395bbaa8b60SDan Kruchinin * ns_addr_handle: an RPC handle used for talking to local statd using the 396bbaa8b60SDan Kruchinin * address registration protocol (NSM_ADDR_PROGRAM) 397bbaa8b60SDan Kruchinin */ 398bbaa8b60SDan Kruchinin struct nlm_nsm { 399bbaa8b60SDan Kruchinin ksema_t ns_sem; 400bbaa8b60SDan Kruchinin struct knetconfig ns_knc; /* (c) */ 401bbaa8b60SDan Kruchinin struct netbuf ns_addr; /* (c) */ 402bbaa8b60SDan Kruchinin CLIENT *ns_handle; /* (c) */ 403bbaa8b60SDan Kruchinin CLIENT *ns_addr_handle; /* (c) */ 404bbaa8b60SDan Kruchinin }; 405bbaa8b60SDan Kruchinin 406bbaa8b60SDan Kruchinin /* 407bbaa8b60SDan Kruchinin * Could use flock.h flk_nlm_status_t instead, but 408bbaa8b60SDan Kruchinin * prefer our own enum with initial zero... 409bbaa8b60SDan Kruchinin */ 410bbaa8b60SDan Kruchinin typedef enum { 411bbaa8b60SDan Kruchinin NLM_ST_DOWN = 0, 412bbaa8b60SDan Kruchinin NLM_ST_STOPPING, 413bbaa8b60SDan Kruchinin NLM_ST_UP, 414bbaa8b60SDan Kruchinin NLM_ST_STARTING 415bbaa8b60SDan Kruchinin } nlm_run_status_t; 416bbaa8b60SDan Kruchinin 417bbaa8b60SDan Kruchinin /* 418bbaa8b60SDan Kruchinin * nlm_globals structure allows NLM be zone aware. The structure 419bbaa8b60SDan Kruchinin * collects all "global variables" NLM has for each zone. 420bbaa8b60SDan Kruchinin * 421bbaa8b60SDan Kruchinin * struct nlm_globals: 422bbaa8b60SDan Kruchinin * lock: mutex protecting all operations inside given zone 423bbaa8b60SDan Kruchinin * grace_threshold: grace period expiration time (in ticks) 424bbaa8b60SDan Kruchinin * lockd_pid: PID of lockd user space daemon 425bbaa8b60SDan Kruchinin * run_status: run status of klmmod inside given zone 426bbaa8b60SDan Kruchinin * nsm_state: state obtained from local statd during klmmod startup 427bbaa8b60SDan Kruchinin * nlm_gc_thread: garbage collector thread 428bbaa8b60SDan Kruchinin * nlm_gc_sched_cv: condvar that can be signalled to wakeup GC 429bbaa8b60SDan Kruchinin * nlm_gc_finish_cv: condvar that is signalled just before GC thread exits 430bbaa8b60SDan Kruchinin * nlm_nsm: an object describing RPC handle used for talking to local statd 431bbaa8b60SDan Kruchinin * nlm_hosts_tree: an AVL tree of all hosts in the given zone 432bbaa8b60SDan Kruchinin * (used for hosts lookup by <netid, address> pair) 433bbaa8b60SDan Kruchinin * nlm_hosts_hash: a hash table of all hosts in the given zone 434bbaa8b60SDan Kruchinin * (used for hosts lookup by sysid) 435bbaa8b60SDan Kruchinin * nlm_idle_hosts: a list of all hosts that are idle state (i.e. unused) 436bbaa8b60SDan Kruchinin * nlm_slocks: a list of all client-side sleeping locks in the zone 437bbaa8b60SDan Kruchinin * cn_idle_tmo: a value of idle timeout (in seconds) obtained from lockd 438bbaa8b60SDan Kruchinin * grace_period: a value of grace period (in seconds) obtained from lockd 439bbaa8b60SDan Kruchinin * retrans_tmo: a value of retransmission timeout (in seconds) obtained 440bbaa8b60SDan Kruchinin * from lockd. 441bbaa8b60SDan Kruchinin * clean_lock: mutex used to serialize clear_locks calls. 442bbaa8b60SDan Kruchinin * nlm_link: a list node used for keeping all nlm_globals objects 443bbaa8b60SDan Kruchinin * in one global linked list. 444bbaa8b60SDan Kruchinin */ 445bbaa8b60SDan Kruchinin struct nlm_globals { 446bbaa8b60SDan Kruchinin kmutex_t lock; 447bbaa8b60SDan Kruchinin clock_t grace_threshold; /* (z) */ 448bbaa8b60SDan Kruchinin pid_t lockd_pid; /* (z) */ 449bbaa8b60SDan Kruchinin nlm_run_status_t run_status; /* (z) */ 450bbaa8b60SDan Kruchinin int32_t nsm_state; /* (z) */ 451bbaa8b60SDan Kruchinin kthread_t *nlm_gc_thread; /* (z) */ 452bbaa8b60SDan Kruchinin kcondvar_t nlm_gc_sched_cv; /* (z) */ 453bbaa8b60SDan Kruchinin kcondvar_t nlm_gc_finish_cv; /* (z) */ 454bbaa8b60SDan Kruchinin struct nlm_nsm nlm_nsm; /* (z) */ 455bbaa8b60SDan Kruchinin avl_tree_t nlm_hosts_tree; /* (z) */ 456bbaa8b60SDan Kruchinin mod_hash_t *nlm_hosts_hash; /* (z) */ 457bbaa8b60SDan Kruchinin struct nlm_host_list nlm_idle_hosts; /* (z) */ 458bbaa8b60SDan Kruchinin struct nlm_slock_list nlm_slocks; /* (z) */ 459bbaa8b60SDan Kruchinin int cn_idle_tmo; /* (z) */ 460bbaa8b60SDan Kruchinin int grace_period; /* (z) */ 461bbaa8b60SDan Kruchinin int retrans_tmo; /* (z) */ 4620dfe541eSEvan Layton zoneid_t nlm_zoneid; /* (c) */ 463bbaa8b60SDan Kruchinin kmutex_t clean_lock; /* (c) */ 464bbaa8b60SDan Kruchinin TAILQ_ENTRY(nlm_globals) nlm_link; /* (g) */ 465bbaa8b60SDan Kruchinin }; 466bbaa8b60SDan Kruchinin TAILQ_HEAD(nlm_globals_list, nlm_globals); 467bbaa8b60SDan Kruchinin 468bbaa8b60SDan Kruchinin 469bbaa8b60SDan Kruchinin /* 470bbaa8b60SDan Kruchinin * This is what we pass as the "owner handle" for NLM_LOCK. 471bbaa8b60SDan Kruchinin * This lets us find the blocked lock in NLM_GRANTED. 472bbaa8b60SDan Kruchinin * It also exposes on the wire what we're using as the 473bbaa8b60SDan Kruchinin * sysid for any server, which can be very helpful for 474bbaa8b60SDan Kruchinin * problem diagnosis. (Observability is good). 475bbaa8b60SDan Kruchinin */ 476bbaa8b60SDan Kruchinin struct nlm_owner_handle { 477bbaa8b60SDan Kruchinin sysid_t oh_sysid; /* of remote host */ 478bbaa8b60SDan Kruchinin }; 479bbaa8b60SDan Kruchinin 480bbaa8b60SDan Kruchinin /* 481bbaa8b60SDan Kruchinin * Number retries NLM RPC call is repeatead in case of failure. 482bbaa8b60SDan Kruchinin * (used in case of conectionless transport). 483bbaa8b60SDan Kruchinin */ 484bbaa8b60SDan Kruchinin #define NLM_RPC_RETRIES 5 485bbaa8b60SDan Kruchinin 486bbaa8b60SDan Kruchinin /* 487bbaa8b60SDan Kruchinin * Klmmod global variables 488bbaa8b60SDan Kruchinin */ 489bbaa8b60SDan Kruchinin extern krwlock_t lm_lck; 490bbaa8b60SDan Kruchinin extern zone_key_t nlm_zone_key; 491bbaa8b60SDan Kruchinin 492bbaa8b60SDan Kruchinin /* 493bbaa8b60SDan Kruchinin * NLM interface functions (called directly by 494bbaa8b60SDan Kruchinin * either klmmod or klmpos) 495bbaa8b60SDan Kruchinin */ 496bbaa8b60SDan Kruchinin extern int nlm_frlock(struct vnode *, int, struct flock64 *, int, u_offset_t, 497bbaa8b60SDan Kruchinin struct cred *, struct netobj *, struct flk_callback *, int); 498bbaa8b60SDan Kruchinin extern int nlm_shrlock(struct vnode *, int, struct shrlock *, int, 499bbaa8b60SDan Kruchinin struct netobj *, int); 500bbaa8b60SDan Kruchinin extern int nlm_safemap(const vnode_t *); 501bbaa8b60SDan Kruchinin extern int nlm_safelock(vnode_t *, const struct flock64 *, cred_t *); 502bbaa8b60SDan Kruchinin extern int nlm_has_sleep(const vnode_t *); 503bbaa8b60SDan Kruchinin extern void nlm_register_lock_locally(struct vnode *, struct nlm_host *, 504bbaa8b60SDan Kruchinin struct flock64 *, int, u_offset_t); 505bbaa8b60SDan Kruchinin int nlm_vp_active(const vnode_t *vp); 506bbaa8b60SDan Kruchinin void nlm_sysid_free(sysid_t); 507bbaa8b60SDan Kruchinin int nlm_vp_active(const vnode_t *); 508bbaa8b60SDan Kruchinin void nlm_unexport(struct exportinfo *); 509bbaa8b60SDan Kruchinin 510bbaa8b60SDan Kruchinin /* 511bbaa8b60SDan Kruchinin * NLM startup/shutdown 512bbaa8b60SDan Kruchinin */ 513bbaa8b60SDan Kruchinin int nlm_svc_starting(struct nlm_globals *, struct file *, 514bbaa8b60SDan Kruchinin const char *, struct knetconfig *); 515bbaa8b60SDan Kruchinin void nlm_svc_stopping(struct nlm_globals *); 516bbaa8b60SDan Kruchinin int nlm_svc_add_ep(struct file *, const char *, struct knetconfig *); 517bbaa8b60SDan Kruchinin 518bbaa8b60SDan Kruchinin /* 519bbaa8b60SDan Kruchinin * NLM suspend/resume 520bbaa8b60SDan Kruchinin */ 521bbaa8b60SDan Kruchinin void nlm_cprsuspend(void); 522bbaa8b60SDan Kruchinin void nlm_cprresume(void); 523bbaa8b60SDan Kruchinin 524bbaa8b60SDan Kruchinin /* 525bbaa8b60SDan Kruchinin * NLM internal functions for initialization. 526bbaa8b60SDan Kruchinin */ 527bbaa8b60SDan Kruchinin void nlm_init(void); 528bbaa8b60SDan Kruchinin void nlm_rpc_init(void); 529bbaa8b60SDan Kruchinin void nlm_rpc_cache_destroy(struct nlm_host *); 530bbaa8b60SDan Kruchinin void nlm_globals_register(struct nlm_globals *); 531bbaa8b60SDan Kruchinin void nlm_globals_unregister(struct nlm_globals *); 532bbaa8b60SDan Kruchinin sysid_t nlm_sysid_alloc(void); 533bbaa8b60SDan Kruchinin 534bbaa8b60SDan Kruchinin /* 535bbaa8b60SDan Kruchinin * Client reclamation/cancelation 536bbaa8b60SDan Kruchinin */ 537bbaa8b60SDan Kruchinin void nlm_reclaim_client(struct nlm_globals *, struct nlm_host *); 538bbaa8b60SDan Kruchinin void nlm_client_cancel_all(struct nlm_globals *, struct nlm_host *); 539bbaa8b60SDan Kruchinin 540bbaa8b60SDan Kruchinin /* (nlm_rpc_clnt.c) */ 541bbaa8b60SDan Kruchinin enum clnt_stat nlm_null_rpc(CLIENT *, rpcvers_t); 542bbaa8b60SDan Kruchinin enum clnt_stat nlm_test_rpc(nlm4_testargs *, nlm4_testres *, 543bbaa8b60SDan Kruchinin CLIENT *, rpcvers_t); 544bbaa8b60SDan Kruchinin enum clnt_stat nlm_lock_rpc(nlm4_lockargs *, nlm4_res *, 545bbaa8b60SDan Kruchinin CLIENT *, rpcvers_t); 546bbaa8b60SDan Kruchinin enum clnt_stat nlm_cancel_rpc(nlm4_cancargs *, nlm4_res *, 547bbaa8b60SDan Kruchinin CLIENT *, rpcvers_t); 548bbaa8b60SDan Kruchinin enum clnt_stat nlm_unlock_rpc(nlm4_unlockargs *, nlm4_res *, 549bbaa8b60SDan Kruchinin CLIENT *, rpcvers_t); 550bbaa8b60SDan Kruchinin enum clnt_stat nlm_share_rpc(nlm4_shareargs *, nlm4_shareres *, 551bbaa8b60SDan Kruchinin CLIENT *, rpcvers_t); 552bbaa8b60SDan Kruchinin enum clnt_stat nlm_unshare_rpc(nlm4_shareargs *, nlm4_shareres *, 553bbaa8b60SDan Kruchinin CLIENT *, rpcvers_t); 554bbaa8b60SDan Kruchinin 555bbaa8b60SDan Kruchinin 556bbaa8b60SDan Kruchinin /* 557bbaa8b60SDan Kruchinin * RPC service functions. 558bbaa8b60SDan Kruchinin * nlm_dispatch.c 559bbaa8b60SDan Kruchinin */ 560bbaa8b60SDan Kruchinin void nlm_prog_3(struct svc_req *rqstp, SVCXPRT *transp); 561bbaa8b60SDan Kruchinin void nlm_prog_4(struct svc_req *rqstp, SVCXPRT *transp); 562bbaa8b60SDan Kruchinin 563bbaa8b60SDan Kruchinin /* 564bbaa8b60SDan Kruchinin * Functions for working with knetconfigs (nlm_netconfig.c) 565bbaa8b60SDan Kruchinin */ 566bbaa8b60SDan Kruchinin const char *nlm_knc_to_netid(struct knetconfig *); 567bbaa8b60SDan Kruchinin int nlm_knc_from_netid(const char *, struct knetconfig *); 568bbaa8b60SDan Kruchinin 569bbaa8b60SDan Kruchinin /* 570bbaa8b60SDan Kruchinin * NLM host functions (nlm_impl.c) 571bbaa8b60SDan Kruchinin */ 572bbaa8b60SDan Kruchinin struct nlm_host *nlm_host_findcreate(struct nlm_globals *, char *, 573bbaa8b60SDan Kruchinin const char *, struct netbuf *); 574bbaa8b60SDan Kruchinin struct nlm_host *nlm_host_find(struct nlm_globals *, 575bbaa8b60SDan Kruchinin const char *, struct netbuf *); 576bbaa8b60SDan Kruchinin struct nlm_host *nlm_host_find_by_sysid(struct nlm_globals *, sysid_t); 577bbaa8b60SDan Kruchinin void nlm_host_release(struct nlm_globals *, struct nlm_host *); 578bbaa8b60SDan Kruchinin 579bbaa8b60SDan Kruchinin void nlm_host_monitor(struct nlm_globals *, struct nlm_host *, int); 580bbaa8b60SDan Kruchinin void nlm_host_unmonitor(struct nlm_globals *, struct nlm_host *); 581bbaa8b60SDan Kruchinin 582bbaa8b60SDan Kruchinin void nlm_host_notify_server(struct nlm_host *, int32_t); 583bbaa8b60SDan Kruchinin void nlm_host_notify_client(struct nlm_host *, int32_t); 584bbaa8b60SDan Kruchinin 585bbaa8b60SDan Kruchinin int nlm_host_get_state(struct nlm_host *); 586bbaa8b60SDan Kruchinin 587bbaa8b60SDan Kruchinin struct nlm_vhold *nlm_vhold_get(struct nlm_host *, vnode_t *); 588bbaa8b60SDan Kruchinin void nlm_vhold_release(struct nlm_host *, struct nlm_vhold *); 589bbaa8b60SDan Kruchinin struct nlm_vhold *nlm_vhold_find_locked(struct nlm_host *, const vnode_t *); 590bbaa8b60SDan Kruchinin 591bbaa8b60SDan Kruchinin struct nlm_slock *nlm_slock_register(struct nlm_globals *, 592bbaa8b60SDan Kruchinin struct nlm_host *, struct nlm4_lock *, struct vnode *); 593bbaa8b60SDan Kruchinin void nlm_slock_unregister(struct nlm_globals *, struct nlm_slock *); 594bbaa8b60SDan Kruchinin int nlm_slock_wait(struct nlm_globals *, struct nlm_slock *, uint_t); 595bbaa8b60SDan Kruchinin int nlm_slock_grant(struct nlm_globals *, 596bbaa8b60SDan Kruchinin struct nlm_host *, struct nlm4_lock *); 597bbaa8b60SDan Kruchinin void nlm_host_cancel_slocks(struct nlm_globals *, struct nlm_host *); 598bbaa8b60SDan Kruchinin 599bbaa8b60SDan Kruchinin int nlm_slreq_register(struct nlm_host *, 600bbaa8b60SDan Kruchinin struct nlm_vhold *, struct flock64 *); 601bbaa8b60SDan Kruchinin int nlm_slreq_unregister(struct nlm_host *, 602bbaa8b60SDan Kruchinin struct nlm_vhold *, struct flock64 *); 603bbaa8b60SDan Kruchinin 604bbaa8b60SDan Kruchinin void nlm_shres_track(struct nlm_host *, vnode_t *, struct shrlock *); 605bbaa8b60SDan Kruchinin void nlm_shres_untrack(struct nlm_host *, vnode_t *, struct shrlock *); 606bbaa8b60SDan Kruchinin struct nlm_shres *nlm_get_active_shres(struct nlm_host *); 607bbaa8b60SDan Kruchinin void nlm_free_shrlist(struct nlm_shres *); 608bbaa8b60SDan Kruchinin 609bbaa8b60SDan Kruchinin int nlm_host_wait_grace(struct nlm_host *); 610bbaa8b60SDan Kruchinin int nlm_host_cmp(const void *, const void *); 611bbaa8b60SDan Kruchinin void nlm_copy_netobj(struct netobj *, struct netobj *); 612bbaa8b60SDan Kruchinin 613bbaa8b60SDan Kruchinin int nlm_host_get_rpc(struct nlm_host *, int, nlm_rpc_t **); 614bbaa8b60SDan Kruchinin void nlm_host_rele_rpc(struct nlm_host *, nlm_rpc_t *); 615bbaa8b60SDan Kruchinin 616bbaa8b60SDan Kruchinin /* 617bbaa8b60SDan Kruchinin * NLM server functions (nlm_service.c) 618bbaa8b60SDan Kruchinin */ 619bbaa8b60SDan Kruchinin int nlm_vp_active(const vnode_t *vp); 620bbaa8b60SDan Kruchinin void nlm_do_notify1(nlm_sm_status *, void *, struct svc_req *); 621bbaa8b60SDan Kruchinin void nlm_do_notify2(nlm_sm_status *, void *, struct svc_req *); 622bbaa8b60SDan Kruchinin void nlm_do_test(nlm4_testargs *, nlm4_testres *, 623bbaa8b60SDan Kruchinin struct svc_req *, nlm_testres_cb); 624bbaa8b60SDan Kruchinin void nlm_do_lock(nlm4_lockargs *, nlm4_res *, struct svc_req *, 625*54b3584eSGordon Ross nlm_reply_cb, nlm_res_cb, nlm_granted_cb); 626bbaa8b60SDan Kruchinin void nlm_do_cancel(nlm4_cancargs *, nlm4_res *, 627bbaa8b60SDan Kruchinin struct svc_req *, nlm_res_cb); 628bbaa8b60SDan Kruchinin void nlm_do_unlock(nlm4_unlockargs *, nlm4_res *, 629bbaa8b60SDan Kruchinin struct svc_req *, nlm_res_cb); 630bbaa8b60SDan Kruchinin void nlm_do_granted(nlm4_testargs *, nlm4_res *, 631bbaa8b60SDan Kruchinin struct svc_req *, nlm_res_cb); 632bbaa8b60SDan Kruchinin void nlm_do_share(nlm4_shareargs *, nlm4_shareres *, struct svc_req *); 633bbaa8b60SDan Kruchinin void nlm_do_unshare(nlm4_shareargs *, nlm4_shareres *, struct svc_req *); 634bbaa8b60SDan Kruchinin void nlm_do_free_all(nlm4_notify *, void *, struct svc_req *); 635bbaa8b60SDan Kruchinin 636bbaa8b60SDan Kruchinin /* 637bbaa8b60SDan Kruchinin * NLM RPC functions 638bbaa8b60SDan Kruchinin */ 639bbaa8b60SDan Kruchinin enum clnt_stat nlm_clnt_call(CLIENT *, rpcproc_t, xdrproc_t, 640bbaa8b60SDan Kruchinin caddr_t, xdrproc_t, caddr_t, struct timeval); 641bbaa8b60SDan Kruchinin bool_t nlm_caller_is_local(SVCXPRT *); 642bbaa8b60SDan Kruchinin 643bbaa8b60SDan Kruchinin #endif /* _NLM_NLM_H_ */ 644