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