xref: /illumos-gate/usr/src/uts/common/klm/nlm_impl.h (revision 54b3584e)
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