xref: /illumos-gate/usr/src/uts/common/nfs/nfs_clnt.h (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #ifndef	_NFS_NFS_CLNT_H
31*7c478bd9Sstevel@tonic-gate #define	_NFS_NFS_CLNT_H
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
38*7c478bd9Sstevel@tonic-gate #include <vm/page.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/thread.h>
40*7c478bd9Sstevel@tonic-gate #include <nfs/rnode.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/list.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
44*7c478bd9Sstevel@tonic-gate extern "C" {
45*7c478bd9Sstevel@tonic-gate #endif
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #define	HOSTNAMESZ	32
48*7c478bd9Sstevel@tonic-gate #define	ACREGMIN	3	/* min secs to hold cached file attr */
49*7c478bd9Sstevel@tonic-gate #define	ACREGMAX	60	/* max secs to hold cached file attr */
50*7c478bd9Sstevel@tonic-gate #define	ACDIRMIN	30	/* min secs to hold cached dir attr */
51*7c478bd9Sstevel@tonic-gate #define	ACDIRMAX	60	/* max secs to hold cached dir attr */
52*7c478bd9Sstevel@tonic-gate #define	ACMINMAX	3600	/* 1 hr is longest min timeout */
53*7c478bd9Sstevel@tonic-gate #define	ACMAXMAX	36000	/* 10 hr is longest max timeout */
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate #define	NFS_CALLTYPES	3	/* Lookups, Reads, Writes */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate /*
58*7c478bd9Sstevel@tonic-gate  * rfscall() flags
59*7c478bd9Sstevel@tonic-gate  */
60*7c478bd9Sstevel@tonic-gate #define	RFSCALL_SOFT	0x00000001	/* Do op as if fs was soft-mounted */
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate /*
63*7c478bd9Sstevel@tonic-gate  * Fake errno passed back from rfscall to indicate transfer size adjustment
64*7c478bd9Sstevel@tonic-gate  */
65*7c478bd9Sstevel@tonic-gate #define	ENFS_TRYAGAIN	999
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate /*
68*7c478bd9Sstevel@tonic-gate  * The NFS specific async_reqs structure.
69*7c478bd9Sstevel@tonic-gate  */
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate enum iotype {
72*7c478bd9Sstevel@tonic-gate 	NFS_READ_AHEAD,
73*7c478bd9Sstevel@tonic-gate 	NFS_PUTAPAGE,
74*7c478bd9Sstevel@tonic-gate 	NFS_PAGEIO,
75*7c478bd9Sstevel@tonic-gate 	NFS_READDIR,
76*7c478bd9Sstevel@tonic-gate 	NFS_COMMIT,
77*7c478bd9Sstevel@tonic-gate 	NFS_INACTIVE
78*7c478bd9Sstevel@tonic-gate };
79*7c478bd9Sstevel@tonic-gate #define	NFS_ASYNC_TYPES	(NFS_INACTIVE + 1)
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate struct nfs_async_read_req {
82*7c478bd9Sstevel@tonic-gate 	void (*readahead)();		/* pointer to readahead function */
83*7c478bd9Sstevel@tonic-gate 	u_offset_t blkoff;		/* offset in file */
84*7c478bd9Sstevel@tonic-gate 	struct seg *seg;		/* segment to do i/o to */
85*7c478bd9Sstevel@tonic-gate 	caddr_t addr;			/* address to do i/o to */
86*7c478bd9Sstevel@tonic-gate };
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate struct nfs_pageio_req {
89*7c478bd9Sstevel@tonic-gate 	int (*pageio)();		/* pointer to pageio function */
90*7c478bd9Sstevel@tonic-gate 	page_t *pp;			/* page list */
91*7c478bd9Sstevel@tonic-gate 	u_offset_t io_off;		/* offset in file */
92*7c478bd9Sstevel@tonic-gate 	uint_t io_len;			/* size of request */
93*7c478bd9Sstevel@tonic-gate 	int flags;
94*7c478bd9Sstevel@tonic-gate };
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate struct nfs_readdir_req {
97*7c478bd9Sstevel@tonic-gate 	int (*readdir)();		/* pointer to readdir function */
98*7c478bd9Sstevel@tonic-gate 	struct rddir_cache *rdc;	/* pointer to cache entry to fill */
99*7c478bd9Sstevel@tonic-gate };
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate struct nfs_commit_req {
102*7c478bd9Sstevel@tonic-gate 	void (*commit)();		/* pointer to commit function */
103*7c478bd9Sstevel@tonic-gate 	page_t *plist;			/* page list */
104*7c478bd9Sstevel@tonic-gate 	offset3 offset;			/* starting offset */
105*7c478bd9Sstevel@tonic-gate 	count3 count;			/* size of range to be commited */
106*7c478bd9Sstevel@tonic-gate };
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate struct nfs_inactive_req {
109*7c478bd9Sstevel@tonic-gate 	void (*inactive)();		/* pointer to inactive function */
110*7c478bd9Sstevel@tonic-gate };
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate struct nfs_async_reqs {
113*7c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs *a_next;	/* pointer to next arg struct */
114*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
115*7c478bd9Sstevel@tonic-gate 	kthread_t *a_queuer;		/* thread id of queueing thread */
116*7c478bd9Sstevel@tonic-gate #endif
117*7c478bd9Sstevel@tonic-gate 	struct vnode *a_vp;		/* vnode pointer */
118*7c478bd9Sstevel@tonic-gate 	struct cred *a_cred;		/* cred pointer */
119*7c478bd9Sstevel@tonic-gate 	enum iotype a_io;		/* i/o type */
120*7c478bd9Sstevel@tonic-gate 	union {
121*7c478bd9Sstevel@tonic-gate 		struct nfs_async_read_req a_read_args;
122*7c478bd9Sstevel@tonic-gate 		struct nfs_pageio_req a_pageio_args;
123*7c478bd9Sstevel@tonic-gate 		struct nfs_readdir_req a_readdir_args;
124*7c478bd9Sstevel@tonic-gate 		struct nfs_commit_req a_commit_args;
125*7c478bd9Sstevel@tonic-gate 		struct nfs_inactive_req a_inactive_args;
126*7c478bd9Sstevel@tonic-gate 	} a_args;
127*7c478bd9Sstevel@tonic-gate };
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate #define	a_nfs_readahead a_args.a_read_args.readahead
130*7c478bd9Sstevel@tonic-gate #define	a_nfs_blkoff a_args.a_read_args.blkoff
131*7c478bd9Sstevel@tonic-gate #define	a_nfs_seg a_args.a_read_args.seg
132*7c478bd9Sstevel@tonic-gate #define	a_nfs_addr a_args.a_read_args.addr
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate #define	a_nfs_putapage a_args.a_pageio_args.pageio
135*7c478bd9Sstevel@tonic-gate #define	a_nfs_pageio a_args.a_pageio_args.pageio
136*7c478bd9Sstevel@tonic-gate #define	a_nfs_pp a_args.a_pageio_args.pp
137*7c478bd9Sstevel@tonic-gate #define	a_nfs_off a_args.a_pageio_args.io_off
138*7c478bd9Sstevel@tonic-gate #define	a_nfs_len a_args.a_pageio_args.io_len
139*7c478bd9Sstevel@tonic-gate #define	a_nfs_flags a_args.a_pageio_args.flags
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate #define	a_nfs_readdir a_args.a_readdir_args.readdir
142*7c478bd9Sstevel@tonic-gate #define	a_nfs_rdc a_args.a_readdir_args.rdc
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate #define	a_nfs_commit a_args.a_commit_args.commit
145*7c478bd9Sstevel@tonic-gate #define	a_nfs_plist a_args.a_commit_args.plist
146*7c478bd9Sstevel@tonic-gate #define	a_nfs_offset a_args.a_commit_args.offset
147*7c478bd9Sstevel@tonic-gate #define	a_nfs_count a_args.a_commit_args.count
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate #define	a_nfs_inactive a_args.a_inactive_args.inactive
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate /*
152*7c478bd9Sstevel@tonic-gate  * Due to the way the address space callbacks are used to execute a delmap,
153*7c478bd9Sstevel@tonic-gate  * we must keep track of how many times the same thread has called
154*7c478bd9Sstevel@tonic-gate  * VOP_DELMAP()->nfs_delmap()/nfs3_delmap().  This is done by having a list of
155*7c478bd9Sstevel@tonic-gate  * nfs_delmapcall_t's associated with each rnode_t.  This list is protected
156*7c478bd9Sstevel@tonic-gate  * by the rnode_t's r_statelock.  The individual elements do not need to be
157*7c478bd9Sstevel@tonic-gate  * protected as they will only ever be created, modified and destroyed by
158*7c478bd9Sstevel@tonic-gate  * one thread (the call_id).
159*7c478bd9Sstevel@tonic-gate  * See nfs_delmap()/nfs3_delmap() for further explanation.
160*7c478bd9Sstevel@tonic-gate  */
161*7c478bd9Sstevel@tonic-gate typedef struct nfs_delmapcall {
162*7c478bd9Sstevel@tonic-gate 	kthread_t	*call_id;
163*7c478bd9Sstevel@tonic-gate 	int		error;	/* error from delmap */
164*7c478bd9Sstevel@tonic-gate 	list_node_t	call_node;
165*7c478bd9Sstevel@tonic-gate } nfs_delmapcall_t;
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate /*
168*7c478bd9Sstevel@tonic-gate  * delmap address space callback args
169*7c478bd9Sstevel@tonic-gate  */
170*7c478bd9Sstevel@tonic-gate typedef struct nfs_delmap_args {
171*7c478bd9Sstevel@tonic-gate 	vnode_t			*vp;
172*7c478bd9Sstevel@tonic-gate 	offset_t		off;
173*7c478bd9Sstevel@tonic-gate 	caddr_t			addr;
174*7c478bd9Sstevel@tonic-gate 	size_t			len;
175*7c478bd9Sstevel@tonic-gate 	uint_t			prot;
176*7c478bd9Sstevel@tonic-gate 	uint_t			maxprot;
177*7c478bd9Sstevel@tonic-gate 	uint_t			flags;
178*7c478bd9Sstevel@tonic-gate 	cred_t			*cr;
179*7c478bd9Sstevel@tonic-gate 	nfs_delmapcall_t	*caller; /* to retrieve errors from the cb */
180*7c478bd9Sstevel@tonic-gate } nfs_delmap_args_t;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL
183*7c478bd9Sstevel@tonic-gate extern nfs_delmapcall_t	*nfs_init_delmapcall(void);
184*7c478bd9Sstevel@tonic-gate extern void	nfs_free_delmapcall(nfs_delmapcall_t *);
185*7c478bd9Sstevel@tonic-gate extern int	nfs_find_and_delete_delmapcall(rnode_t *, int *errp);
186*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate /*
189*7c478bd9Sstevel@tonic-gate  * The following structures, chhead and chtab,  make up the client handle
190*7c478bd9Sstevel@tonic-gate  * cache.  chhead represents a quadruple(RPC program, RPC version, Protocol
191*7c478bd9Sstevel@tonic-gate  * Family, and Transport).  For example, a chhead entry could represent
192*7c478bd9Sstevel@tonic-gate  * NFS/V3/IPv4/TCP requests.  chhead nodes are linked together as a singly
193*7c478bd9Sstevel@tonic-gate  * linked list and is referenced from chtable.
194*7c478bd9Sstevel@tonic-gate  *
195*7c478bd9Sstevel@tonic-gate  * chtab represents an allocated client handle bound to a particular
196*7c478bd9Sstevel@tonic-gate  * quadruple. These nodes chain down from a chhead node.  chtab
197*7c478bd9Sstevel@tonic-gate  * entries which are on the chain are considered free, so a thread may simply
198*7c478bd9Sstevel@tonic-gate  * unlink the first node without traversing the chain.  When the thread is
199*7c478bd9Sstevel@tonic-gate  * completed with its request, it puts the chtab node back on the chain.
200*7c478bd9Sstevel@tonic-gate  */
201*7c478bd9Sstevel@tonic-gate typedef struct chhead {
202*7c478bd9Sstevel@tonic-gate 	struct chhead *ch_next;	/* next quadruple */
203*7c478bd9Sstevel@tonic-gate 	struct chtab *ch_list;	/* pointer to free client handle(s) */
204*7c478bd9Sstevel@tonic-gate 	uint64_t ch_timesused;	/* times this quadruple was requested */
205*7c478bd9Sstevel@tonic-gate 	rpcprog_t ch_prog;	/* RPC program number */
206*7c478bd9Sstevel@tonic-gate 	rpcvers_t ch_vers;	/* RPC version number */
207*7c478bd9Sstevel@tonic-gate 	dev_t ch_dev;		/* pseudo device number (i.e. /dev/udp) */
208*7c478bd9Sstevel@tonic-gate 	char *ch_protofmly;	/* protocol (i.e. NC_INET, NC_LOOPBACK) */
209*7c478bd9Sstevel@tonic-gate } chhead_t;
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate typedef struct chtab {
212*7c478bd9Sstevel@tonic-gate 	struct chtab *ch_list;	/* next free client handle */
213*7c478bd9Sstevel@tonic-gate 	struct chhead *ch_head;	/* associated quadruple */
214*7c478bd9Sstevel@tonic-gate 	time_t ch_freed;	/* timestamp when freed */
215*7c478bd9Sstevel@tonic-gate 	CLIENT *ch_client;	/* pointer to client handle */
216*7c478bd9Sstevel@tonic-gate } chtab_t;
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate /*
219*7c478bd9Sstevel@tonic-gate  * clinfo is a structure which encapsulates data that is needed to
220*7c478bd9Sstevel@tonic-gate  * obtain a client handle from the cache
221*7c478bd9Sstevel@tonic-gate  */
222*7c478bd9Sstevel@tonic-gate typedef struct clinfo {
223*7c478bd9Sstevel@tonic-gate 	rpcprog_t cl_prog;	/* RPC program number */
224*7c478bd9Sstevel@tonic-gate 	rpcvers_t cl_vers;	/* RPC version number */
225*7c478bd9Sstevel@tonic-gate 	uint_t cl_readsize;	/* transfer size */
226*7c478bd9Sstevel@tonic-gate 	int cl_retrans;		/* times to retry request */
227*7c478bd9Sstevel@tonic-gate 	uint_t cl_flags;	/* info flags */
228*7c478bd9Sstevel@tonic-gate } clinfo_t;
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate /*
231*7c478bd9Sstevel@tonic-gate  * Failover information, passed opaquely through rfscall()
232*7c478bd9Sstevel@tonic-gate  */
233*7c478bd9Sstevel@tonic-gate typedef struct failinfo {
234*7c478bd9Sstevel@tonic-gate 	struct vnode	*vp;
235*7c478bd9Sstevel@tonic-gate 	caddr_t		fhp;
236*7c478bd9Sstevel@tonic-gate 	void (*copyproc)(caddr_t, vnode_t *);
237*7c478bd9Sstevel@tonic-gate 	int (*lookupproc)(vnode_t *, char *, vnode_t **, struct pathname *,
238*7c478bd9Sstevel@tonic-gate 			int, vnode_t *, struct cred *, int);
239*7c478bd9Sstevel@tonic-gate 	int (*xattrdirproc)(vnode_t *, vnode_t **, bool_t, cred_t *, int);
240*7c478bd9Sstevel@tonic-gate } failinfo_t;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate /*
243*7c478bd9Sstevel@tonic-gate  * Static server information
244*7c478bd9Sstevel@tonic-gate  *
245*7c478bd9Sstevel@tonic-gate  * These fields are protected by sv_lock:
246*7c478bd9Sstevel@tonic-gate  *	sv_flags
247*7c478bd9Sstevel@tonic-gate  */
248*7c478bd9Sstevel@tonic-gate typedef struct servinfo {
249*7c478bd9Sstevel@tonic-gate 	struct knetconfig *sv_knconf;   /* bound TLI fd */
250*7c478bd9Sstevel@tonic-gate 	struct knetconfig *sv_origknconf;	/* For RDMA save orig knconf */
251*7c478bd9Sstevel@tonic-gate 	struct netbuf	sv_addr;	/* server's address */
252*7c478bd9Sstevel@tonic-gate 	nfs_fhandle	sv_fhandle;	/* this server's filehandle */
253*7c478bd9Sstevel@tonic-gate 	struct sec_data *sv_secdata;	/* security data for rpcsec module */
254*7c478bd9Sstevel@tonic-gate 	char	*sv_hostname;		/* server's hostname */
255*7c478bd9Sstevel@tonic-gate 	int	sv_hostnamelen;		/* server's hostname length */
256*7c478bd9Sstevel@tonic-gate 	uint_t	sv_flags;		/* see below */
257*7c478bd9Sstevel@tonic-gate 	struct servinfo	*sv_next;	/* next in list */
258*7c478bd9Sstevel@tonic-gate 	kmutex_t sv_lock;
259*7c478bd9Sstevel@tonic-gate } servinfo_t;
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate /*
262*7c478bd9Sstevel@tonic-gate  * The values for sv_flags.
263*7c478bd9Sstevel@tonic-gate  */
264*7c478bd9Sstevel@tonic-gate #define	SV_ROOT_STALE	0x1		/* root vnode got ESTALE */
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate /*
267*7c478bd9Sstevel@tonic-gate  * Switch from RDMA knconf to original mount knconf
268*7c478bd9Sstevel@tonic-gate  */
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate #define	ORIG_KNCONF(mi) (mi->mi_curr_serv->sv_origknconf ? \
271*7c478bd9Sstevel@tonic-gate 	mi->mi_curr_serv->sv_origknconf : mi->mi_curr_serv->sv_knconf)
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate /*
274*7c478bd9Sstevel@tonic-gate  * NFS private data per mounted file system
275*7c478bd9Sstevel@tonic-gate  *	The mi_lock mutex protects the following fields:
276*7c478bd9Sstevel@tonic-gate  *		mi_flags
277*7c478bd9Sstevel@tonic-gate  *		mi_printed
278*7c478bd9Sstevel@tonic-gate  *		mi_down
279*7c478bd9Sstevel@tonic-gate  *		mi_tsize
280*7c478bd9Sstevel@tonic-gate  *		mi_stsize
281*7c478bd9Sstevel@tonic-gate  *		mi_curread
282*7c478bd9Sstevel@tonic-gate  *		mi_curwrite
283*7c478bd9Sstevel@tonic-gate  *		mi_timers
284*7c478bd9Sstevel@tonic-gate  *		mi_curr_serv
285*7c478bd9Sstevel@tonic-gate  *		mi_readers
286*7c478bd9Sstevel@tonic-gate  *		mi_klmconfig
287*7c478bd9Sstevel@tonic-gate  *
288*7c478bd9Sstevel@tonic-gate  *	The mi_async_lock mutex protects the following fields:
289*7c478bd9Sstevel@tonic-gate  *		mi_async_reqs
290*7c478bd9Sstevel@tonic-gate  *		mi_async_req_count
291*7c478bd9Sstevel@tonic-gate  *		mi_async_tail
292*7c478bd9Sstevel@tonic-gate  *		mi_async_curr
293*7c478bd9Sstevel@tonic-gate  *		mi_async_clusters
294*7c478bd9Sstevel@tonic-gate  *		mi_async_init_clusters
295*7c478bd9Sstevel@tonic-gate  *		mi_threads
296*7c478bd9Sstevel@tonic-gate  *		mi_manager_thread
297*7c478bd9Sstevel@tonic-gate  *
298*7c478bd9Sstevel@tonic-gate  *	Normally the netconfig information for the mount comes from
299*7c478bd9Sstevel@tonic-gate  *	mi_curr_serv and mi_klmconfig is NULL.  If NLM calls need to use a
300*7c478bd9Sstevel@tonic-gate  *	different transport, mi_klmconfig contains the necessary netconfig
301*7c478bd9Sstevel@tonic-gate  *	information.
302*7c478bd9Sstevel@tonic-gate  *
303*7c478bd9Sstevel@tonic-gate  *	'mi_zone' is initialized at structure creation time, and never
304*7c478bd9Sstevel@tonic-gate  *	changes; it may be read without a lock.
305*7c478bd9Sstevel@tonic-gate  *
306*7c478bd9Sstevel@tonic-gate  *	mi_zone_node is linkage into the mi4_globals.mig_list, and is
307*7c478bd9Sstevel@tonic-gate  *	protected by mi4_globals.mig_list_lock.
308*7c478bd9Sstevel@tonic-gate  *
309*7c478bd9Sstevel@tonic-gate  *	Locking order:
310*7c478bd9Sstevel@tonic-gate  *	  mi_globals::mig_lock > mi_async_lock > mi_lock
311*7c478bd9Sstevel@tonic-gate  */
312*7c478bd9Sstevel@tonic-gate typedef struct mntinfo {
313*7c478bd9Sstevel@tonic-gate 	kmutex_t	mi_lock;	/* protects mntinfo fields */
314*7c478bd9Sstevel@tonic-gate 	struct servinfo *mi_servers;    /* server list */
315*7c478bd9Sstevel@tonic-gate 	struct servinfo *mi_curr_serv;  /* current server */
316*7c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_failover_cv;	/* failover synchronization */
317*7c478bd9Sstevel@tonic-gate 	int		mi_readers;	/* failover - users of mi_curr_serv */
318*7c478bd9Sstevel@tonic-gate 	struct vfs	*mi_vfsp;	/* back pointer to vfs */
319*7c478bd9Sstevel@tonic-gate 	enum vtype	mi_type;	/* file type of the root vnode */
320*7c478bd9Sstevel@tonic-gate 	uint_t		mi_flags;	/* see below */
321*7c478bd9Sstevel@tonic-gate 	uint_t		mi_tsize;	/* max read transfer size (bytes) */
322*7c478bd9Sstevel@tonic-gate 	uint_t		mi_stsize;	/* max write transfer size (bytes) */
323*7c478bd9Sstevel@tonic-gate 	int		mi_timeo;	/* inital timeout in 10th sec */
324*7c478bd9Sstevel@tonic-gate 	int		mi_retrans;	/* times to retry request */
325*7c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acregmin;	/* min time to hold cached file attr */
326*7c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acregmax;	/* max time to hold cached file attr */
327*7c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acdirmin;	/* min time to hold cached dir attr */
328*7c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acdirmax;	/* max time to hold cached dir attr */
329*7c478bd9Sstevel@tonic-gate 	len_t		mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */
330*7c478bd9Sstevel@tonic-gate 	/*
331*7c478bd9Sstevel@tonic-gate 	 * Extra fields for congestion control, one per NFS call type,
332*7c478bd9Sstevel@tonic-gate 	 * plus one global one.
333*7c478bd9Sstevel@tonic-gate 	 */
334*7c478bd9Sstevel@tonic-gate 	struct rpc_timers mi_timers[NFS_CALLTYPES+1];
335*7c478bd9Sstevel@tonic-gate 	int		mi_curread;	/* current read size */
336*7c478bd9Sstevel@tonic-gate 	int		mi_curwrite;	/* current write size */
337*7c478bd9Sstevel@tonic-gate 	/*
338*7c478bd9Sstevel@tonic-gate 	 * async I/O management
339*7c478bd9Sstevel@tonic-gate 	 */
340*7c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs *mi_async_reqs[NFS_ASYNC_TYPES];
341*7c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs *mi_async_tail[NFS_ASYNC_TYPES];
342*7c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs **mi_async_curr;	/* current async queue */
343*7c478bd9Sstevel@tonic-gate 	uint_t		mi_async_clusters[NFS_ASYNC_TYPES];
344*7c478bd9Sstevel@tonic-gate 	uint_t		mi_async_init_clusters;
345*7c478bd9Sstevel@tonic-gate 	uint_t		mi_async_req_count; /* # outstanding work requests */
346*7c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_reqs_cv; /* signaled when there's work */
347*7c478bd9Sstevel@tonic-gate 	ushort_t	mi_threads;	/* number of active async threads */
348*7c478bd9Sstevel@tonic-gate 	ushort_t	mi_max_threads;	/* max number of async worker threads */
349*7c478bd9Sstevel@tonic-gate 	kthread_t	*mi_manager_thread;  /* async manager thread */
350*7c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_cv; /* signaled when the last worker dies */
351*7c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_work_cv; /* tell workers to work */
352*7c478bd9Sstevel@tonic-gate 	kmutex_t	mi_async_lock;	/* lock to protect async list */
353*7c478bd9Sstevel@tonic-gate 	/*
354*7c478bd9Sstevel@tonic-gate 	 * Other stuff
355*7c478bd9Sstevel@tonic-gate 	 */
356*7c478bd9Sstevel@tonic-gate 	struct pathcnf *mi_pathconf;	/* static pathconf kludge */
357*7c478bd9Sstevel@tonic-gate 	rpcprog_t	mi_prog;	/* RPC program number */
358*7c478bd9Sstevel@tonic-gate 	rpcvers_t	mi_vers;	/* RPC program version number */
359*7c478bd9Sstevel@tonic-gate 	char		**mi_rfsnames;	/* mapping to proc names */
360*7c478bd9Sstevel@tonic-gate 	kstat_named_t	*mi_reqs;	/* count of requests */
361*7c478bd9Sstevel@tonic-gate 	uchar_t		*mi_call_type;	/* dynamic retrans call types */
362*7c478bd9Sstevel@tonic-gate 	uchar_t		*mi_ss_call_type;	/* semisoft call type */
363*7c478bd9Sstevel@tonic-gate 	uchar_t		*mi_timer_type;	/* dynamic retrans timer types */
364*7c478bd9Sstevel@tonic-gate 	clock_t		mi_printftime;	/* last error printf time */
365*7c478bd9Sstevel@tonic-gate 	/*
366*7c478bd9Sstevel@tonic-gate 	 * ACL entries
367*7c478bd9Sstevel@tonic-gate 	 */
368*7c478bd9Sstevel@tonic-gate 	char		**mi_aclnames;	/* mapping to proc names */
369*7c478bd9Sstevel@tonic-gate 	kstat_named_t	*mi_aclreqs;	/* count of acl requests */
370*7c478bd9Sstevel@tonic-gate 	uchar_t		*mi_acl_call_type; /* dynamic retrans call types */
371*7c478bd9Sstevel@tonic-gate 	uchar_t		*mi_acl_ss_call_type; /* semisoft call types */
372*7c478bd9Sstevel@tonic-gate 	uchar_t		*mi_acl_timer_type; /* dynamic retrans timer types */
373*7c478bd9Sstevel@tonic-gate 	/*
374*7c478bd9Sstevel@tonic-gate 	 * Client Side Failover stats
375*7c478bd9Sstevel@tonic-gate 	 */
376*7c478bd9Sstevel@tonic-gate 	uint_t		mi_noresponse;	/* server not responding count */
377*7c478bd9Sstevel@tonic-gate 	uint_t		mi_failover; 	/* failover to new server count */
378*7c478bd9Sstevel@tonic-gate 	uint_t		mi_remap;	/* remap to new server count */
379*7c478bd9Sstevel@tonic-gate 	/*
380*7c478bd9Sstevel@tonic-gate 	 * Kstat statistics
381*7c478bd9Sstevel@tonic-gate 	 */
382*7c478bd9Sstevel@tonic-gate 	struct kstat	*mi_io_kstats;
383*7c478bd9Sstevel@tonic-gate 	struct kstat	*mi_ro_kstats;
384*7c478bd9Sstevel@tonic-gate 	struct knetconfig *mi_klmconfig;
385*7c478bd9Sstevel@tonic-gate 	/*
386*7c478bd9Sstevel@tonic-gate 	 * Zones support.
387*7c478bd9Sstevel@tonic-gate 	 */
388*7c478bd9Sstevel@tonic-gate 	struct zone	*mi_zone;	/* Zone mounted in */
389*7c478bd9Sstevel@tonic-gate 	list_node_t	mi_zone_node;	/* Linkage into per-zone mi list */
390*7c478bd9Sstevel@tonic-gate } mntinfo_t;
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate /*
393*7c478bd9Sstevel@tonic-gate  * vfs pointer to mount info
394*7c478bd9Sstevel@tonic-gate  */
395*7c478bd9Sstevel@tonic-gate #define	VFTOMI(vfsp)	((mntinfo_t *)((vfsp)->vfs_data))
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate /*
398*7c478bd9Sstevel@tonic-gate  * vnode pointer to mount info
399*7c478bd9Sstevel@tonic-gate  */
400*7c478bd9Sstevel@tonic-gate #define	VTOMI(vp)	((mntinfo_t *)(((vp)->v_vfsp)->vfs_data))
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate /*
403*7c478bd9Sstevel@tonic-gate  * The values for mi_flags.
404*7c478bd9Sstevel@tonic-gate  */
405*7c478bd9Sstevel@tonic-gate #define	MI_HARD		0x1		/* hard or soft mount */
406*7c478bd9Sstevel@tonic-gate #define	MI_PRINTED	0x2		/* not responding message printed */
407*7c478bd9Sstevel@tonic-gate #define	MI_INT		0x4		/* interrupts allowed on hard mount */
408*7c478bd9Sstevel@tonic-gate #define	MI_DOWN		0x8		/* server is down */
409*7c478bd9Sstevel@tonic-gate #define	MI_NOAC		0x10		/* don't cache attributes */
410*7c478bd9Sstevel@tonic-gate #define	MI_NOCTO	0x20		/* no close-to-open consistency */
411*7c478bd9Sstevel@tonic-gate #define	MI_DYNAMIC	0x40		/* dynamic transfer size adjustment */
412*7c478bd9Sstevel@tonic-gate #define	MI_LLOCK	0x80		/* local locking only (no lockmgr) */
413*7c478bd9Sstevel@tonic-gate #define	MI_GRPID	0x100		/* System V group id inheritance */
414*7c478bd9Sstevel@tonic-gate #define	MI_RPCTIMESYNC	0x200		/* RPC time sync */
415*7c478bd9Sstevel@tonic-gate #define	MI_LINK		0x400		/* server supports link */
416*7c478bd9Sstevel@tonic-gate #define	MI_SYMLINK	0x800		/* server supports symlink */
417*7c478bd9Sstevel@tonic-gate #define	MI_READDIRONLY	0x1000		/* use readdir instead of readdirplus */
418*7c478bd9Sstevel@tonic-gate #define	MI_ACL		0x2000		/* server supports NFS_ACL */
419*7c478bd9Sstevel@tonic-gate #define	MI_BINDINPROG	0x4000		/* binding to server is changing */
420*7c478bd9Sstevel@tonic-gate #define	MI_LOOPBACK	0x8000		/* Set if this is a loopback mount */
421*7c478bd9Sstevel@tonic-gate #define	MI_SEMISOFT	0x10000		/* soft reads, hard modify */
422*7c478bd9Sstevel@tonic-gate #define	MI_NOPRINT	0x20000		/* don't print messages */
423*7c478bd9Sstevel@tonic-gate #define	MI_DIRECTIO	0x40000		/* do direct I/O */
424*7c478bd9Sstevel@tonic-gate #define	MI_EXTATTR	0x80000		/* server supports extended attrs */
425*7c478bd9Sstevel@tonic-gate #define	MI_ASYNC_MGR_STOP	0x100000	/* tell async mgr to die */
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate /*
428*7c478bd9Sstevel@tonic-gate  * Read-only mntinfo statistics
429*7c478bd9Sstevel@tonic-gate  */
430*7c478bd9Sstevel@tonic-gate struct mntinfo_kstat {
431*7c478bd9Sstevel@tonic-gate 	char		mik_proto[KNC_STRSIZE];
432*7c478bd9Sstevel@tonic-gate 	uint32_t	mik_vers;
433*7c478bd9Sstevel@tonic-gate 	uint_t		mik_flags;
434*7c478bd9Sstevel@tonic-gate 	uint_t		mik_secmod;
435*7c478bd9Sstevel@tonic-gate 	uint32_t	mik_curread;
436*7c478bd9Sstevel@tonic-gate 	uint32_t	mik_curwrite;
437*7c478bd9Sstevel@tonic-gate 	int		mik_timeo;
438*7c478bd9Sstevel@tonic-gate 	int		mik_retrans;
439*7c478bd9Sstevel@tonic-gate 	uint_t		mik_acregmin;
440*7c478bd9Sstevel@tonic-gate 	uint_t		mik_acregmax;
441*7c478bd9Sstevel@tonic-gate 	uint_t		mik_acdirmin;
442*7c478bd9Sstevel@tonic-gate 	uint_t		mik_acdirmax;
443*7c478bd9Sstevel@tonic-gate 	struct {
444*7c478bd9Sstevel@tonic-gate 		uint32_t srtt;
445*7c478bd9Sstevel@tonic-gate 		uint32_t deviate;
446*7c478bd9Sstevel@tonic-gate 		uint32_t rtxcur;
447*7c478bd9Sstevel@tonic-gate 	} mik_timers[NFS_CALLTYPES+1];
448*7c478bd9Sstevel@tonic-gate 	uint32_t	mik_noresponse;
449*7c478bd9Sstevel@tonic-gate 	uint32_t	mik_failover;
450*7c478bd9Sstevel@tonic-gate 	uint32_t	mik_remap;
451*7c478bd9Sstevel@tonic-gate 	char		mik_curserver[SYS_NMLN];
452*7c478bd9Sstevel@tonic-gate };
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate /*
455*7c478bd9Sstevel@tonic-gate  * Mark cached attributes as timed out
456*7c478bd9Sstevel@tonic-gate  *
457*7c478bd9Sstevel@tonic-gate  * The caller must not be holding the rnode r_statelock mutex.
458*7c478bd9Sstevel@tonic-gate  */
459*7c478bd9Sstevel@tonic-gate #define	PURGE_ATTRCACHE(vp)	{				\
460*7c478bd9Sstevel@tonic-gate 	rnode_t *rp = VTOR(vp);					\
461*7c478bd9Sstevel@tonic-gate 	mutex_enter(&rp->r_statelock);				\
462*7c478bd9Sstevel@tonic-gate 	PURGE_ATTRCACHE_LOCKED(rp);				\
463*7c478bd9Sstevel@tonic-gate 	mutex_exit(&rp->r_statelock);				\
464*7c478bd9Sstevel@tonic-gate }
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate #define	PURGE_ATTRCACHE_LOCKED(rp)	{			\
467*7c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&rp->r_statelock));			\
468*7c478bd9Sstevel@tonic-gate 	rp->r_attrtime = gethrtime();				\
469*7c478bd9Sstevel@tonic-gate 	rp->r_mtime = rp->r_attrtime;				\
470*7c478bd9Sstevel@tonic-gate }
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate /*
473*7c478bd9Sstevel@tonic-gate  * Is the attribute cache valid?
474*7c478bd9Sstevel@tonic-gate  */
475*7c478bd9Sstevel@tonic-gate #define	ATTRCACHE_VALID(vp)	(gethrtime() < VTOR(vp)->r_attrtime)
476*7c478bd9Sstevel@tonic-gate 
477*7c478bd9Sstevel@tonic-gate /*
478*7c478bd9Sstevel@tonic-gate  * Flags to indicate whether to purge the DNLC for non-directory vnodes
479*7c478bd9Sstevel@tonic-gate  * in a call to nfs_purge_caches.
480*7c478bd9Sstevel@tonic-gate  */
481*7c478bd9Sstevel@tonic-gate #define	NFS_NOPURGE_DNLC	0
482*7c478bd9Sstevel@tonic-gate #define	NFS_PURGE_DNLC		1
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate /*
485*7c478bd9Sstevel@tonic-gate  * If returned error is ESTALE flush all caches.
486*7c478bd9Sstevel@tonic-gate  */
487*7c478bd9Sstevel@tonic-gate #define	PURGE_STALE_FH(error, vp, cr)				\
488*7c478bd9Sstevel@tonic-gate 	if ((error) == ESTALE) {				\
489*7c478bd9Sstevel@tonic-gate 		struct rnode *rp = VTOR(vp);			\
490*7c478bd9Sstevel@tonic-gate 		if (vp->v_flag & VROOT) {			\
491*7c478bd9Sstevel@tonic-gate 			servinfo_t *svp = rp->r_server;		\
492*7c478bd9Sstevel@tonic-gate 			mutex_enter(&svp->sv_lock);		\
493*7c478bd9Sstevel@tonic-gate 			svp->sv_flags |= SV_ROOT_STALE;		\
494*7c478bd9Sstevel@tonic-gate 			mutex_exit(&svp->sv_lock);		\
495*7c478bd9Sstevel@tonic-gate 		}						\
496*7c478bd9Sstevel@tonic-gate 		mutex_enter(&rp->r_statelock);			\
497*7c478bd9Sstevel@tonic-gate 		rp->r_flags |= RSTALE;				\
498*7c478bd9Sstevel@tonic-gate 		if (!rp->r_error)				\
499*7c478bd9Sstevel@tonic-gate 			rp->r_error = (error);			\
500*7c478bd9Sstevel@tonic-gate 		mutex_exit(&rp->r_statelock);			\
501*7c478bd9Sstevel@tonic-gate 		if (vn_has_cached_data(vp))			\
502*7c478bd9Sstevel@tonic-gate 			nfs_invalidate_pages((vp), (u_offset_t)0, (cr)); \
503*7c478bd9Sstevel@tonic-gate 		nfs_purge_caches((vp), NFS_PURGE_DNLC, (cr));	\
504*7c478bd9Sstevel@tonic-gate 	}
505*7c478bd9Sstevel@tonic-gate 
506*7c478bd9Sstevel@tonic-gate /*
507*7c478bd9Sstevel@tonic-gate  * Is cache valid?
508*7c478bd9Sstevel@tonic-gate  * Swap is always valid, if no attributes (attrtime == 0) or
509*7c478bd9Sstevel@tonic-gate  * if mtime matches cached mtime it is valid
510*7c478bd9Sstevel@tonic-gate  * NOTE: mtime is now a timestruc_t.
511*7c478bd9Sstevel@tonic-gate  * Caller should be holding the rnode r_statelock mutex.
512*7c478bd9Sstevel@tonic-gate  */
513*7c478bd9Sstevel@tonic-gate #define	CACHE_VALID(rp, mtime, fsize)				\
514*7c478bd9Sstevel@tonic-gate 	((RTOV(rp)->v_flag & VISSWAP) == VISSWAP ||		\
515*7c478bd9Sstevel@tonic-gate 	(((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec &&	\
516*7c478bd9Sstevel@tonic-gate 	(mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) &&	\
517*7c478bd9Sstevel@tonic-gate 	((fsize) == (rp)->r_attr.va_size)))
518*7c478bd9Sstevel@tonic-gate 
519*7c478bd9Sstevel@tonic-gate /*
520*7c478bd9Sstevel@tonic-gate  * Macro to detect forced unmount or a zone shutdown.
521*7c478bd9Sstevel@tonic-gate  */
522*7c478bd9Sstevel@tonic-gate #define	FS_OR_ZONE_GONE(vfsp) \
523*7c478bd9Sstevel@tonic-gate 	(((vfsp)->vfs_flag & VFS_UNMOUNTED) || \
524*7c478bd9Sstevel@tonic-gate 	zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN)
525*7c478bd9Sstevel@tonic-gate 
526*7c478bd9Sstevel@tonic-gate /*
527*7c478bd9Sstevel@tonic-gate  * Convert NFS tunables to hrtime_t units, seconds to nanoseconds.
528*7c478bd9Sstevel@tonic-gate  */
529*7c478bd9Sstevel@tonic-gate #define	SEC2HR(sec)	((sec) * (long long)NANOSEC)
530*7c478bd9Sstevel@tonic-gate #define	HR2SEC(hr)	((hr) / (long long)NANOSEC)
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate /*
533*7c478bd9Sstevel@tonic-gate  * Structure to identify owner of a PC file share reservation.
534*7c478bd9Sstevel@tonic-gate  */
535*7c478bd9Sstevel@tonic-gate struct nfs_owner {
536*7c478bd9Sstevel@tonic-gate 	int	magic;		/* magic uniquifying number */
537*7c478bd9Sstevel@tonic-gate 	char	hname[16];	/* first 16 bytes of hostname */
538*7c478bd9Sstevel@tonic-gate 	char	lowner[8];	/* local owner from fcntl */
539*7c478bd9Sstevel@tonic-gate };
540*7c478bd9Sstevel@tonic-gate 
541*7c478bd9Sstevel@tonic-gate /*
542*7c478bd9Sstevel@tonic-gate  * Values for magic.
543*7c478bd9Sstevel@tonic-gate  */
544*7c478bd9Sstevel@tonic-gate #define	NFS_OWNER_MAGIC	0x1D81E
545*7c478bd9Sstevel@tonic-gate 
546*7c478bd9Sstevel@tonic-gate /*
547*7c478bd9Sstevel@tonic-gate  * Support for extended attributes
548*7c478bd9Sstevel@tonic-gate  */
549*7c478bd9Sstevel@tonic-gate #define	XATTR_DIR_NAME	"/@/"		/* used for DNLC entries */
550*7c478bd9Sstevel@tonic-gate #define	XATTR_RPATH	"ExTaTtR"	/* used for r_path for failover */
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate /*
553*7c478bd9Sstevel@tonic-gate  * Short hand for checking to see whether the file system was mounted
554*7c478bd9Sstevel@tonic-gate  * interruptible or not.
555*7c478bd9Sstevel@tonic-gate  */
556*7c478bd9Sstevel@tonic-gate #define	INTR(vp)	(VTOMI(vp)->mi_flags & MI_INT)
557*7c478bd9Sstevel@tonic-gate 
558*7c478bd9Sstevel@tonic-gate /*
559*7c478bd9Sstevel@tonic-gate  * Short hand for checking whether failover is enabled or not
560*7c478bd9Sstevel@tonic-gate  */
561*7c478bd9Sstevel@tonic-gate #define	FAILOVER_MOUNT(mi)	(mi->mi_servers->sv_next)
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate /*
564*7c478bd9Sstevel@tonic-gate  * How long will async threads wait for additional work.
565*7c478bd9Sstevel@tonic-gate  */
566*7c478bd9Sstevel@tonic-gate #define	NFS_ASYNC_TIMEOUT	(60 * 1 * hz)	/* 1 minute */
567*7c478bd9Sstevel@tonic-gate 
568*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL
569*7c478bd9Sstevel@tonic-gate extern int	clget(clinfo_t *, servinfo_t *, cred_t *, CLIENT **,
570*7c478bd9Sstevel@tonic-gate 		    struct chtab **);
571*7c478bd9Sstevel@tonic-gate extern void	clfree(CLIENT *, struct chtab *);
572*7c478bd9Sstevel@tonic-gate extern void	nfs_mi_zonelist_add(mntinfo_t *);
573*7c478bd9Sstevel@tonic-gate extern void	nfs_free_mi(mntinfo_t *);
574*7c478bd9Sstevel@tonic-gate extern void	nfs_mnt_kstat_init(struct vfs *);
575*7c478bd9Sstevel@tonic-gate #endif
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate /*
578*7c478bd9Sstevel@tonic-gate  * Per-zone data for managing client handles.  Included here solely for the
579*7c478bd9Sstevel@tonic-gate  * benefit of MDB.
580*7c478bd9Sstevel@tonic-gate  */
581*7c478bd9Sstevel@tonic-gate /*
582*7c478bd9Sstevel@tonic-gate  * client side statistics
583*7c478bd9Sstevel@tonic-gate  */
584*7c478bd9Sstevel@tonic-gate struct clstat {
585*7c478bd9Sstevel@tonic-gate 	kstat_named_t	calls;			/* client requests */
586*7c478bd9Sstevel@tonic-gate 	kstat_named_t	badcalls;		/* rpc failures */
587*7c478bd9Sstevel@tonic-gate 	kstat_named_t	clgets;			/* client handle gets */
588*7c478bd9Sstevel@tonic-gate 	kstat_named_t	cltoomany;		/* client handle cache misses */
589*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
590*7c478bd9Sstevel@tonic-gate 	kstat_named_t	clalloc;		/* number of client handles */
591*7c478bd9Sstevel@tonic-gate 	kstat_named_t	noresponse;		/* server not responding cnt */
592*7c478bd9Sstevel@tonic-gate 	kstat_named_t	failover;		/* server failover count */
593*7c478bd9Sstevel@tonic-gate 	kstat_named_t	remap;			/* server remap count */
594*7c478bd9Sstevel@tonic-gate #endif
595*7c478bd9Sstevel@tonic-gate };
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate struct nfs_clnt {
598*7c478bd9Sstevel@tonic-gate 	struct chhead	*nfscl_chtable;
599*7c478bd9Sstevel@tonic-gate 	kmutex_t	nfscl_chtable_lock;
600*7c478bd9Sstevel@tonic-gate 	zoneid_t	nfscl_zoneid;
601*7c478bd9Sstevel@tonic-gate 	list_node_t	nfscl_node;
602*7c478bd9Sstevel@tonic-gate 	struct clstat	nfscl_stat;
603*7c478bd9Sstevel@tonic-gate };
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
606*7c478bd9Sstevel@tonic-gate }
607*7c478bd9Sstevel@tonic-gate #endif
608*7c478bd9Sstevel@tonic-gate 
609*7c478bd9Sstevel@tonic-gate #endif	/* _NFS_NFS_CLNT_H */
610