xref: /illumos-gate/usr/src/uts/common/nfs/nfs_clnt.h (revision e010bda9)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50776f5e6SVallish Vaidyeshwara  * Common Development and Distribution License (the "License").
60776f5e6SVallish Vaidyeshwara  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22a19609f8Sjv  * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
26b4203d75SMarcel Telka /*	  All Rights Reserved	*/
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #ifndef	_NFS_NFS_CLNT_H
297c478bd9Sstevel@tonic-gate #define	_NFS_NFS_CLNT_H
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
327c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
337c478bd9Sstevel@tonic-gate #include <sys/time.h>
347c478bd9Sstevel@tonic-gate #include <vm/page.h>
357c478bd9Sstevel@tonic-gate #include <sys/thread.h>
367c478bd9Sstevel@tonic-gate #include <nfs/rnode.h>
377c478bd9Sstevel@tonic-gate #include <sys/list.h>
380776f5e6SVallish Vaidyeshwara #include <sys/condvar_impl.h>
39a19609f8Sjv #include <sys/zone.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
427c478bd9Sstevel@tonic-gate extern "C" {
437c478bd9Sstevel@tonic-gate #endif
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #define	HOSTNAMESZ	32
467c478bd9Sstevel@tonic-gate #define	ACREGMIN	3	/* min secs to hold cached file attr */
477c478bd9Sstevel@tonic-gate #define	ACREGMAX	60	/* max secs to hold cached file attr */
487c478bd9Sstevel@tonic-gate #define	ACDIRMIN	30	/* min secs to hold cached dir attr */
497c478bd9Sstevel@tonic-gate #define	ACDIRMAX	60	/* max secs to hold cached dir attr */
507c478bd9Sstevel@tonic-gate #define	ACMINMAX	3600	/* 1 hr is longest min timeout */
517c478bd9Sstevel@tonic-gate #define	ACMAXMAX	36000	/* 10 hr is longest max timeout */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #define	NFS_CALLTYPES	3	/* Lookups, Reads, Writes */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate  * rfscall() flags
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate #define	RFSCALL_SOFT	0x00000001	/* Do op as if fs was soft-mounted */
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate  * Fake errno passed back from rfscall to indicate transfer size adjustment
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate #define	ENFS_TRYAGAIN	999
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /*
660776f5e6SVallish Vaidyeshwara  * The NFS specific async_reqs structure. iotype is grouped to support two
670776f5e6SVallish Vaidyeshwara  * types of async thread pools, please read comments section of mntinfo_t
680776f5e6SVallish Vaidyeshwara  * definition for more information. Care should be taken while adding new
690776f5e6SVallish Vaidyeshwara  * members to this group.
707c478bd9Sstevel@tonic-gate  */
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate enum iotype {
737c478bd9Sstevel@tonic-gate 	NFS_PUTAPAGE,
747c478bd9Sstevel@tonic-gate 	NFS_PAGEIO,
757c478bd9Sstevel@tonic-gate 	NFS_COMMIT,
760776f5e6SVallish Vaidyeshwara 	NFS_READ_AHEAD,
770776f5e6SVallish Vaidyeshwara 	NFS_READDIR,
780776f5e6SVallish Vaidyeshwara 	NFS_INACTIVE,
790776f5e6SVallish Vaidyeshwara 	NFS_ASYNC_TYPES
800776f5e6SVallish Vaidyeshwara };
810776f5e6SVallish Vaidyeshwara #define	NFS_ASYNC_PGOPS_TYPES	(NFS_COMMIT + 1)
820776f5e6SVallish Vaidyeshwara 
830776f5e6SVallish Vaidyeshwara /*
840776f5e6SVallish Vaidyeshwara  * NFS async requests queue type.
850776f5e6SVallish Vaidyeshwara  */
860776f5e6SVallish Vaidyeshwara 
870776f5e6SVallish Vaidyeshwara enum ioqtype {
880776f5e6SVallish Vaidyeshwara 	NFS_ASYNC_QUEUE,
890776f5e6SVallish Vaidyeshwara 	NFS_ASYNC_PGOPS_QUEUE,
900776f5e6SVallish Vaidyeshwara 	NFS_MAX_ASYNC_QUEUES
917c478bd9Sstevel@tonic-gate };
920776f5e6SVallish Vaidyeshwara 
930776f5e6SVallish Vaidyeshwara /*
940776f5e6SVallish Vaidyeshwara  * Number of NFS async threads operating exclusively on page op requests.
950776f5e6SVallish Vaidyeshwara  */
960776f5e6SVallish Vaidyeshwara #define	NUM_ASYNC_PGOPS_THREADS	0x2
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate struct nfs_async_read_req {
997c478bd9Sstevel@tonic-gate 	void (*readahead)();		/* pointer to readahead function */
1007c478bd9Sstevel@tonic-gate 	u_offset_t blkoff;		/* offset in file */
1017c478bd9Sstevel@tonic-gate 	struct seg *seg;		/* segment to do i/o to */
1027c478bd9Sstevel@tonic-gate 	caddr_t addr;			/* address to do i/o to */
1037c478bd9Sstevel@tonic-gate };
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate struct nfs_pageio_req {
1067c478bd9Sstevel@tonic-gate 	int (*pageio)();		/* pointer to pageio function */
1077c478bd9Sstevel@tonic-gate 	page_t *pp;			/* page list */
1087c478bd9Sstevel@tonic-gate 	u_offset_t io_off;		/* offset in file */
1097c478bd9Sstevel@tonic-gate 	uint_t io_len;			/* size of request */
1107c478bd9Sstevel@tonic-gate 	int flags;
1117c478bd9Sstevel@tonic-gate };
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate struct nfs_readdir_req {
1147c478bd9Sstevel@tonic-gate 	int (*readdir)();		/* pointer to readdir function */
1157c478bd9Sstevel@tonic-gate 	struct rddir_cache *rdc;	/* pointer to cache entry to fill */
1167c478bd9Sstevel@tonic-gate };
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate struct nfs_commit_req {
1197c478bd9Sstevel@tonic-gate 	void (*commit)();		/* pointer to commit function */
1207c478bd9Sstevel@tonic-gate 	page_t *plist;			/* page list */
1217c478bd9Sstevel@tonic-gate 	offset3 offset;			/* starting offset */
1227c478bd9Sstevel@tonic-gate 	count3 count;			/* size of range to be commited */
1237c478bd9Sstevel@tonic-gate };
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate struct nfs_inactive_req {
1267c478bd9Sstevel@tonic-gate 	void (*inactive)();		/* pointer to inactive function */
1277c478bd9Sstevel@tonic-gate };
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate struct nfs_async_reqs {
1307c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs *a_next;	/* pointer to next arg struct */
1317c478bd9Sstevel@tonic-gate #ifdef DEBUG
1327c478bd9Sstevel@tonic-gate 	kthread_t *a_queuer;		/* thread id of queueing thread */
1337c478bd9Sstevel@tonic-gate #endif
1347c478bd9Sstevel@tonic-gate 	struct vnode *a_vp;		/* vnode pointer */
1357c478bd9Sstevel@tonic-gate 	struct cred *a_cred;		/* cred pointer */
1367c478bd9Sstevel@tonic-gate 	enum iotype a_io;		/* i/o type */
1377c478bd9Sstevel@tonic-gate 	union {
1387c478bd9Sstevel@tonic-gate 		struct nfs_async_read_req a_read_args;
1397c478bd9Sstevel@tonic-gate 		struct nfs_pageio_req a_pageio_args;
1407c478bd9Sstevel@tonic-gate 		struct nfs_readdir_req a_readdir_args;
1417c478bd9Sstevel@tonic-gate 		struct nfs_commit_req a_commit_args;
1427c478bd9Sstevel@tonic-gate 		struct nfs_inactive_req a_inactive_args;
1437c478bd9Sstevel@tonic-gate 	} a_args;
1447c478bd9Sstevel@tonic-gate };
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate #define	a_nfs_readahead a_args.a_read_args.readahead
1477c478bd9Sstevel@tonic-gate #define	a_nfs_blkoff a_args.a_read_args.blkoff
1487c478bd9Sstevel@tonic-gate #define	a_nfs_seg a_args.a_read_args.seg
1497c478bd9Sstevel@tonic-gate #define	a_nfs_addr a_args.a_read_args.addr
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate #define	a_nfs_putapage a_args.a_pageio_args.pageio
1527c478bd9Sstevel@tonic-gate #define	a_nfs_pageio a_args.a_pageio_args.pageio
1537c478bd9Sstevel@tonic-gate #define	a_nfs_pp a_args.a_pageio_args.pp
1547c478bd9Sstevel@tonic-gate #define	a_nfs_off a_args.a_pageio_args.io_off
1557c478bd9Sstevel@tonic-gate #define	a_nfs_len a_args.a_pageio_args.io_len
1567c478bd9Sstevel@tonic-gate #define	a_nfs_flags a_args.a_pageio_args.flags
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate #define	a_nfs_readdir a_args.a_readdir_args.readdir
1597c478bd9Sstevel@tonic-gate #define	a_nfs_rdc a_args.a_readdir_args.rdc
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate #define	a_nfs_commit a_args.a_commit_args.commit
1627c478bd9Sstevel@tonic-gate #define	a_nfs_plist a_args.a_commit_args.plist
1637c478bd9Sstevel@tonic-gate #define	a_nfs_offset a_args.a_commit_args.offset
1647c478bd9Sstevel@tonic-gate #define	a_nfs_count a_args.a_commit_args.count
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate #define	a_nfs_inactive a_args.a_inactive_args.inactive
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate /*
1697c478bd9Sstevel@tonic-gate  * Due to the way the address space callbacks are used to execute a delmap,
1707c478bd9Sstevel@tonic-gate  * we must keep track of how many times the same thread has called
1717c478bd9Sstevel@tonic-gate  * VOP_DELMAP()->nfs_delmap()/nfs3_delmap().  This is done by having a list of
1727c478bd9Sstevel@tonic-gate  * nfs_delmapcall_t's associated with each rnode_t.  This list is protected
1737c478bd9Sstevel@tonic-gate  * by the rnode_t's r_statelock.  The individual elements do not need to be
1747c478bd9Sstevel@tonic-gate  * protected as they will only ever be created, modified and destroyed by
1757c478bd9Sstevel@tonic-gate  * one thread (the call_id).
1767c478bd9Sstevel@tonic-gate  * See nfs_delmap()/nfs3_delmap() for further explanation.
1777c478bd9Sstevel@tonic-gate  */
1787c478bd9Sstevel@tonic-gate typedef struct nfs_delmapcall {
1797c478bd9Sstevel@tonic-gate 	kthread_t	*call_id;
1807c478bd9Sstevel@tonic-gate 	int		error;	/* error from delmap */
1817c478bd9Sstevel@tonic-gate 	list_node_t	call_node;
1827c478bd9Sstevel@tonic-gate } nfs_delmapcall_t;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate  * delmap address space callback args
1867c478bd9Sstevel@tonic-gate  */
1877c478bd9Sstevel@tonic-gate typedef struct nfs_delmap_args {
1887c478bd9Sstevel@tonic-gate 	vnode_t			*vp;
1897c478bd9Sstevel@tonic-gate 	offset_t		off;
1907c478bd9Sstevel@tonic-gate 	caddr_t			addr;
1917c478bd9Sstevel@tonic-gate 	size_t			len;
1927c478bd9Sstevel@tonic-gate 	uint_t			prot;
1937c478bd9Sstevel@tonic-gate 	uint_t			maxprot;
1947c478bd9Sstevel@tonic-gate 	uint_t			flags;
1957c478bd9Sstevel@tonic-gate 	cred_t			*cr;
1967c478bd9Sstevel@tonic-gate 	nfs_delmapcall_t	*caller; /* to retrieve errors from the cb */
1977c478bd9Sstevel@tonic-gate } nfs_delmap_args_t;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate #ifdef _KERNEL
2007c478bd9Sstevel@tonic-gate extern nfs_delmapcall_t	*nfs_init_delmapcall(void);
2017c478bd9Sstevel@tonic-gate extern void	nfs_free_delmapcall(nfs_delmapcall_t *);
2027c478bd9Sstevel@tonic-gate extern int	nfs_find_and_delete_delmapcall(rnode_t *, int *errp);
2037c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate /*
2067c478bd9Sstevel@tonic-gate  * The following structures, chhead and chtab,  make up the client handle
2077c478bd9Sstevel@tonic-gate  * cache.  chhead represents a quadruple(RPC program, RPC version, Protocol
2087c478bd9Sstevel@tonic-gate  * Family, and Transport).  For example, a chhead entry could represent
2097c478bd9Sstevel@tonic-gate  * NFS/V3/IPv4/TCP requests.  chhead nodes are linked together as a singly
2107c478bd9Sstevel@tonic-gate  * linked list and is referenced from chtable.
2117c478bd9Sstevel@tonic-gate  *
2127c478bd9Sstevel@tonic-gate  * chtab represents an allocated client handle bound to a particular
2137c478bd9Sstevel@tonic-gate  * quadruple. These nodes chain down from a chhead node.  chtab
2147c478bd9Sstevel@tonic-gate  * entries which are on the chain are considered free, so a thread may simply
2157c478bd9Sstevel@tonic-gate  * unlink the first node without traversing the chain.  When the thread is
2167c478bd9Sstevel@tonic-gate  * completed with its request, it puts the chtab node back on the chain.
2177c478bd9Sstevel@tonic-gate  */
2187c478bd9Sstevel@tonic-gate typedef struct chhead {
2197c478bd9Sstevel@tonic-gate 	struct chhead *ch_next;	/* next quadruple */
2207c478bd9Sstevel@tonic-gate 	struct chtab *ch_list;	/* pointer to free client handle(s) */
2217c478bd9Sstevel@tonic-gate 	uint64_t ch_timesused;	/* times this quadruple was requested */
2227c478bd9Sstevel@tonic-gate 	rpcprog_t ch_prog;	/* RPC program number */
2237c478bd9Sstevel@tonic-gate 	rpcvers_t ch_vers;	/* RPC version number */
2247c478bd9Sstevel@tonic-gate 	dev_t ch_dev;		/* pseudo device number (i.e. /dev/udp) */
2257c478bd9Sstevel@tonic-gate 	char *ch_protofmly;	/* protocol (i.e. NC_INET, NC_LOOPBACK) */
2267c478bd9Sstevel@tonic-gate } chhead_t;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate typedef struct chtab {
2297c478bd9Sstevel@tonic-gate 	struct chtab *ch_list;	/* next free client handle */
2307c478bd9Sstevel@tonic-gate 	struct chhead *ch_head;	/* associated quadruple */
2317c478bd9Sstevel@tonic-gate 	time_t ch_freed;	/* timestamp when freed */
2327c478bd9Sstevel@tonic-gate 	CLIENT *ch_client;	/* pointer to client handle */
2337c478bd9Sstevel@tonic-gate } chtab_t;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate /*
2367c478bd9Sstevel@tonic-gate  * clinfo is a structure which encapsulates data that is needed to
2377c478bd9Sstevel@tonic-gate  * obtain a client handle from the cache
2387c478bd9Sstevel@tonic-gate  */
2397c478bd9Sstevel@tonic-gate typedef struct clinfo {
2407c478bd9Sstevel@tonic-gate 	rpcprog_t cl_prog;	/* RPC program number */
2417c478bd9Sstevel@tonic-gate 	rpcvers_t cl_vers;	/* RPC version number */
2427c478bd9Sstevel@tonic-gate 	uint_t cl_readsize;	/* transfer size */
2437c478bd9Sstevel@tonic-gate 	int cl_retrans;		/* times to retry request */
2447c478bd9Sstevel@tonic-gate 	uint_t cl_flags;	/* info flags */
2457c478bd9Sstevel@tonic-gate } clinfo_t;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate /*
2487c478bd9Sstevel@tonic-gate  * Failover information, passed opaquely through rfscall()
2497c478bd9Sstevel@tonic-gate  */
2507c478bd9Sstevel@tonic-gate typedef struct failinfo {
2517c478bd9Sstevel@tonic-gate 	struct vnode	*vp;
2527c478bd9Sstevel@tonic-gate 	caddr_t		fhp;
2537c478bd9Sstevel@tonic-gate 	void (*copyproc)(caddr_t, vnode_t *);
2547c478bd9Sstevel@tonic-gate 	int (*lookupproc)(vnode_t *, char *, vnode_t **, struct pathname *,
2557c478bd9Sstevel@tonic-gate 			int, vnode_t *, struct cred *, int);
2567c478bd9Sstevel@tonic-gate 	int (*xattrdirproc)(vnode_t *, vnode_t **, bool_t, cred_t *, int);
2577c478bd9Sstevel@tonic-gate } failinfo_t;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate /*
2607c478bd9Sstevel@tonic-gate  * Static server information
2617c478bd9Sstevel@tonic-gate  *
2627c478bd9Sstevel@tonic-gate  * These fields are protected by sv_lock:
2637c478bd9Sstevel@tonic-gate  *	sv_flags
2647c478bd9Sstevel@tonic-gate  */
2657c478bd9Sstevel@tonic-gate typedef struct servinfo {
2667c478bd9Sstevel@tonic-gate 	struct knetconfig *sv_knconf;   /* bound TLI fd */
2677c478bd9Sstevel@tonic-gate 	struct knetconfig *sv_origknconf;	/* For RDMA save orig knconf */
2687c478bd9Sstevel@tonic-gate 	struct netbuf	sv_addr;	/* server's address */
2697c478bd9Sstevel@tonic-gate 	nfs_fhandle	sv_fhandle;	/* this server's filehandle */
2707c478bd9Sstevel@tonic-gate 	struct sec_data *sv_secdata;	/* security data for rpcsec module */
2717c478bd9Sstevel@tonic-gate 	char	*sv_hostname;		/* server's hostname */
2727c478bd9Sstevel@tonic-gate 	int	sv_hostnamelen;		/* server's hostname length */
2737c478bd9Sstevel@tonic-gate 	uint_t	sv_flags;		/* see below */
2747c478bd9Sstevel@tonic-gate 	struct servinfo	*sv_next;	/* next in list */
2757c478bd9Sstevel@tonic-gate 	kmutex_t sv_lock;
2767c478bd9Sstevel@tonic-gate } servinfo_t;
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate /*
2797c478bd9Sstevel@tonic-gate  * The values for sv_flags.
2807c478bd9Sstevel@tonic-gate  */
2817c478bd9Sstevel@tonic-gate #define	SV_ROOT_STALE	0x1		/* root vnode got ESTALE */
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate /*
2847c478bd9Sstevel@tonic-gate  * Switch from RDMA knconf to original mount knconf
2857c478bd9Sstevel@tonic-gate  */
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate #define	ORIG_KNCONF(mi) (mi->mi_curr_serv->sv_origknconf ? \
2887c478bd9Sstevel@tonic-gate 	mi->mi_curr_serv->sv_origknconf : mi->mi_curr_serv->sv_knconf)
2897c478bd9Sstevel@tonic-gate 
290a19609f8Sjv #if	defined(_KERNEL)
2917c478bd9Sstevel@tonic-gate /*
2927c478bd9Sstevel@tonic-gate  * NFS private data per mounted file system
2937c478bd9Sstevel@tonic-gate  *	The mi_lock mutex protects the following fields:
2947c478bd9Sstevel@tonic-gate  *		mi_flags
2957c478bd9Sstevel@tonic-gate  *		mi_printed
2967c478bd9Sstevel@tonic-gate  *		mi_down
2977c478bd9Sstevel@tonic-gate  *		mi_tsize
2987c478bd9Sstevel@tonic-gate  *		mi_stsize
2997c478bd9Sstevel@tonic-gate  *		mi_curread
3007c478bd9Sstevel@tonic-gate  *		mi_curwrite
3017c478bd9Sstevel@tonic-gate  *		mi_timers
3027c478bd9Sstevel@tonic-gate  *		mi_curr_serv
3037c478bd9Sstevel@tonic-gate  *		mi_readers
3047c478bd9Sstevel@tonic-gate  *		mi_klmconfig
3057c478bd9Sstevel@tonic-gate  *
3067c478bd9Sstevel@tonic-gate  *	The mi_async_lock mutex protects the following fields:
3077c478bd9Sstevel@tonic-gate  *		mi_async_reqs
3087c478bd9Sstevel@tonic-gate  *		mi_async_req_count
3097c478bd9Sstevel@tonic-gate  *		mi_async_tail
3100776f5e6SVallish Vaidyeshwara  *		mi_async_curr[NFS_MAX_ASYNC_QUEUES]
3117c478bd9Sstevel@tonic-gate  *		mi_async_clusters
3127c478bd9Sstevel@tonic-gate  *		mi_async_init_clusters
3130776f5e6SVallish Vaidyeshwara  *		mi_threads[NFS_MAX_ASYNC_QUEUES]
3147c478bd9Sstevel@tonic-gate  *		mi_manager_thread
3157c478bd9Sstevel@tonic-gate  *
3167c478bd9Sstevel@tonic-gate  *	Normally the netconfig information for the mount comes from
3177c478bd9Sstevel@tonic-gate  *	mi_curr_serv and mi_klmconfig is NULL.  If NLM calls need to use a
3187c478bd9Sstevel@tonic-gate  *	different transport, mi_klmconfig contains the necessary netconfig
3197c478bd9Sstevel@tonic-gate  *	information.
3207c478bd9Sstevel@tonic-gate  *
3217c478bd9Sstevel@tonic-gate  *	'mi_zone' is initialized at structure creation time, and never
3227c478bd9Sstevel@tonic-gate  *	changes; it may be read without a lock.
3237c478bd9Sstevel@tonic-gate  *
3247c478bd9Sstevel@tonic-gate  *	mi_zone_node is linkage into the mi4_globals.mig_list, and is
3257c478bd9Sstevel@tonic-gate  *	protected by mi4_globals.mig_list_lock.
3267c478bd9Sstevel@tonic-gate  *
3277c478bd9Sstevel@tonic-gate  *	Locking order:
3287c478bd9Sstevel@tonic-gate  *	  mi_globals::mig_lock > mi_async_lock > mi_lock
3297c478bd9Sstevel@tonic-gate  */
3307c478bd9Sstevel@tonic-gate typedef struct mntinfo {
3317c478bd9Sstevel@tonic-gate 	kmutex_t	mi_lock;	/* protects mntinfo fields */
3327c478bd9Sstevel@tonic-gate 	struct servinfo *mi_servers;    /* server list */
3337c478bd9Sstevel@tonic-gate 	struct servinfo *mi_curr_serv;  /* current server */
3347c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_failover_cv;	/* failover synchronization */
3357c478bd9Sstevel@tonic-gate 	int		mi_readers;	/* failover - users of mi_curr_serv */
3367c478bd9Sstevel@tonic-gate 	struct vfs	*mi_vfsp;	/* back pointer to vfs */
3377c478bd9Sstevel@tonic-gate 	enum vtype	mi_type;	/* file type of the root vnode */
3387c478bd9Sstevel@tonic-gate 	uint_t		mi_flags;	/* see below */
3397c478bd9Sstevel@tonic-gate 	uint_t		mi_tsize;	/* max read transfer size (bytes) */
3407c478bd9Sstevel@tonic-gate 	uint_t		mi_stsize;	/* max write transfer size (bytes) */
3417c478bd9Sstevel@tonic-gate 	int		mi_timeo;	/* inital timeout in 10th sec */
3427c478bd9Sstevel@tonic-gate 	int		mi_retrans;	/* times to retry request */
3437c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acregmin;	/* min time to hold cached file attr */
3447c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acregmax;	/* max time to hold cached file attr */
3457c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acdirmin;	/* min time to hold cached dir attr */
3467c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acdirmax;	/* max time to hold cached dir attr */
3477c478bd9Sstevel@tonic-gate 	len_t		mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */
3487c478bd9Sstevel@tonic-gate 	/*
3497c478bd9Sstevel@tonic-gate 	 * Extra fields for congestion control, one per NFS call type,
3507c478bd9Sstevel@tonic-gate 	 * plus one global one.
3517c478bd9Sstevel@tonic-gate 	 */
3527c478bd9Sstevel@tonic-gate 	struct rpc_timers mi_timers[NFS_CALLTYPES+1];
3537c478bd9Sstevel@tonic-gate 	int		mi_curread;	/* current read size */
3547c478bd9Sstevel@tonic-gate 	int		mi_curwrite;	/* current write size */
3557c478bd9Sstevel@tonic-gate 	/*
3560776f5e6SVallish Vaidyeshwara 	 * Async I/O management
3570776f5e6SVallish Vaidyeshwara 	 * We have 2 pools of threads working on async I/O:
3580776f5e6SVallish Vaidyeshwara 	 *	(i) Threads which work on all async queues. Default number of
3590776f5e6SVallish Vaidyeshwara 	 *	threads in this queue is 8. Threads in this pool work on async
3600776f5e6SVallish Vaidyeshwara 	 *	queue pointed by mi_async_curr[NFS_ASYNC_QUEUE]. Number of
3610776f5e6SVallish Vaidyeshwara 	 *	active threads in this pool is tracked by
3620776f5e6SVallish Vaidyeshwara 	 *	mi_threads[NFS_ASYNC_QUEUE].
3630776f5e6SVallish Vaidyeshwara 	 * 	(ii)Threads which work only on page op async queues.
3640776f5e6SVallish Vaidyeshwara 	 *	Page ops queue comprises of NFS_PUTAPAGE, NFS_PAGEIO &
3650776f5e6SVallish Vaidyeshwara 	 *	NFS_COMMIT. Default number of threads in this queue is 2
3660776f5e6SVallish Vaidyeshwara 	 *	(NUM_ASYNC_PGOPS_THREADS). Threads in this pool work on async
3670776f5e6SVallish Vaidyeshwara 	 *	queue pointed by mi_async_curr[NFS_ASYNC_PGOPS_QUEUE]. Number
3680776f5e6SVallish Vaidyeshwara 	 *	of active threads in this pool is tracked by
3690776f5e6SVallish Vaidyeshwara 	 *	mi_threads[NFS_ASYNC_PGOPS_QUEUE].
3707c478bd9Sstevel@tonic-gate 	 */
3717c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs *mi_async_reqs[NFS_ASYNC_TYPES];
3727c478bd9Sstevel@tonic-gate 	struct nfs_async_reqs *mi_async_tail[NFS_ASYNC_TYPES];
3730776f5e6SVallish Vaidyeshwara 	struct nfs_async_reqs **mi_async_curr[NFS_MAX_ASYNC_QUEUES];
3740776f5e6SVallish Vaidyeshwara 						/* current async queue */
3757c478bd9Sstevel@tonic-gate 	uint_t		mi_async_clusters[NFS_ASYNC_TYPES];
3767c478bd9Sstevel@tonic-gate 	uint_t		mi_async_init_clusters;
3777c478bd9Sstevel@tonic-gate 	uint_t		mi_async_req_count; /* # outstanding work requests */
3787c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_reqs_cv; /* signaled when there's work */
3790776f5e6SVallish Vaidyeshwara 	ushort_t	mi_threads[NFS_MAX_ASYNC_QUEUES];
3800776f5e6SVallish Vaidyeshwara 					/* number of active async threads */
3817c478bd9Sstevel@tonic-gate 	ushort_t	mi_max_threads;	/* max number of async worker threads */
3827c478bd9Sstevel@tonic-gate 	kthread_t	*mi_manager_thread;  /* async manager thread */
3837c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_cv; /* signaled when the last worker dies */
3840776f5e6SVallish Vaidyeshwara 	kcondvar_t	mi_async_work_cv[NFS_MAX_ASYNC_QUEUES];
3850776f5e6SVallish Vaidyeshwara 					/* tell workers to work */
3867c478bd9Sstevel@tonic-gate 	kmutex_t	mi_async_lock;	/* lock to protect async list */
3877c478bd9Sstevel@tonic-gate 	/*
3887c478bd9Sstevel@tonic-gate 	 * Other stuff
3897c478bd9Sstevel@tonic-gate 	 */
3907c478bd9Sstevel@tonic-gate 	struct pathcnf *mi_pathconf;	/* static pathconf kludge */
3917c478bd9Sstevel@tonic-gate 	rpcprog_t	mi_prog;	/* RPC program number */
3927c478bd9Sstevel@tonic-gate 	rpcvers_t	mi_vers;	/* RPC program version number */
3937c478bd9Sstevel@tonic-gate 	char		**mi_rfsnames;	/* mapping to proc names */
3947c478bd9Sstevel@tonic-gate 	kstat_named_t	*mi_reqs;	/* count of requests */
3957c478bd9Sstevel@tonic-gate 	uchar_t		*mi_call_type;	/* dynamic retrans call types */
3967c478bd9Sstevel@tonic-gate 	uchar_t		*mi_ss_call_type;	/* semisoft call type */
3977c478bd9Sstevel@tonic-gate 	uchar_t		*mi_timer_type;	/* dynamic retrans timer types */
3987c478bd9Sstevel@tonic-gate 	clock_t		mi_printftime;	/* last error printf time */
3997c478bd9Sstevel@tonic-gate 	/*
4007c478bd9Sstevel@tonic-gate 	 * ACL entries
4017c478bd9Sstevel@tonic-gate 	 */
4027c478bd9Sstevel@tonic-gate 	char		**mi_aclnames;	/* mapping to proc names */
4037c478bd9Sstevel@tonic-gate 	kstat_named_t	*mi_aclreqs;	/* count of acl requests */
4047c478bd9Sstevel@tonic-gate 	uchar_t		*mi_acl_call_type; /* dynamic retrans call types */
4057c478bd9Sstevel@tonic-gate 	uchar_t		*mi_acl_ss_call_type; /* semisoft call types */
4067c478bd9Sstevel@tonic-gate 	uchar_t		*mi_acl_timer_type; /* dynamic retrans timer types */
4077c478bd9Sstevel@tonic-gate 	/*
4087c478bd9Sstevel@tonic-gate 	 * Client Side Failover stats
4097c478bd9Sstevel@tonic-gate 	 */
4107c478bd9Sstevel@tonic-gate 	uint_t		mi_noresponse;	/* server not responding count */
4117c478bd9Sstevel@tonic-gate 	uint_t		mi_failover; 	/* failover to new server count */
4127c478bd9Sstevel@tonic-gate 	uint_t		mi_remap;	/* remap to new server count */
4137c478bd9Sstevel@tonic-gate 	/*
4147c478bd9Sstevel@tonic-gate 	 * Kstat statistics
4157c478bd9Sstevel@tonic-gate 	 */
4167c478bd9Sstevel@tonic-gate 	struct kstat	*mi_io_kstats;
4177c478bd9Sstevel@tonic-gate 	struct kstat	*mi_ro_kstats;
4187c478bd9Sstevel@tonic-gate 	struct knetconfig *mi_klmconfig;
4197c478bd9Sstevel@tonic-gate 	/*
4207c478bd9Sstevel@tonic-gate 	 * Zones support.
4217c478bd9Sstevel@tonic-gate 	 */
422a19609f8Sjv 	struct zone	*mi_zone;	/* Zone in which FS is mounted */
423a19609f8Sjv 	zone_ref_t	mi_zone_ref;	/* Reference to aforementioned zone */
4247c478bd9Sstevel@tonic-gate 	list_node_t	mi_zone_node;	/* Linkage into per-zone mi list */
425e8dc3b7dSvv 	/*
426e8dc3b7dSvv 	 * Serializes threads in failover_remap.
427e8dc3b7dSvv 	 * Need to acquire this lock first in failover_remap() function
428e8dc3b7dSvv 	 * before acquiring any other rnode lock.
429e8dc3b7dSvv 	 */
430e8dc3b7dSvv 	kmutex_t	mi_remap_lock;
431*e010bda9SMarcel Telka 	/*
432*e010bda9SMarcel Telka 	 * List of rnode_t structures that belongs to this mntinfo
433*e010bda9SMarcel Telka 	 */
434*e010bda9SMarcel Telka 	kmutex_t	mi_rnodes_lock;	/* protects the mi_rnodes list */
435*e010bda9SMarcel Telka 	list_t		mi_rnodes;	/* the list */
4367c478bd9Sstevel@tonic-gate } mntinfo_t;
437a19609f8Sjv #endif	/* _KERNEL */
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate /*
4407c478bd9Sstevel@tonic-gate  * vfs pointer to mount info
4417c478bd9Sstevel@tonic-gate  */
4427c478bd9Sstevel@tonic-gate #define	VFTOMI(vfsp)	((mntinfo_t *)((vfsp)->vfs_data))
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate /*
4457c478bd9Sstevel@tonic-gate  * vnode pointer to mount info
4467c478bd9Sstevel@tonic-gate  */
4477c478bd9Sstevel@tonic-gate #define	VTOMI(vp)	((mntinfo_t *)(((vp)->v_vfsp)->vfs_data))
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate /*
4507c478bd9Sstevel@tonic-gate  * The values for mi_flags.
4517c478bd9Sstevel@tonic-gate  */
4527c478bd9Sstevel@tonic-gate #define	MI_HARD		0x1		/* hard or soft mount */
4537c478bd9Sstevel@tonic-gate #define	MI_PRINTED	0x2		/* not responding message printed */
4547c478bd9Sstevel@tonic-gate #define	MI_INT		0x4		/* interrupts allowed on hard mount */
4557c478bd9Sstevel@tonic-gate #define	MI_DOWN		0x8		/* server is down */
4567c478bd9Sstevel@tonic-gate #define	MI_NOAC		0x10		/* don't cache attributes */
4577c478bd9Sstevel@tonic-gate #define	MI_NOCTO	0x20		/* no close-to-open consistency */
4587c478bd9Sstevel@tonic-gate #define	MI_DYNAMIC	0x40		/* dynamic transfer size adjustment */
4597c478bd9Sstevel@tonic-gate #define	MI_LLOCK	0x80		/* local locking only (no lockmgr) */
4607c478bd9Sstevel@tonic-gate #define	MI_GRPID	0x100		/* System V group id inheritance */
4617c478bd9Sstevel@tonic-gate #define	MI_RPCTIMESYNC	0x200		/* RPC time sync */
4627c478bd9Sstevel@tonic-gate #define	MI_LINK		0x400		/* server supports link */
4637c478bd9Sstevel@tonic-gate #define	MI_SYMLINK	0x800		/* server supports symlink */
4647c478bd9Sstevel@tonic-gate #define	MI_READDIRONLY	0x1000		/* use readdir instead of readdirplus */
4657c478bd9Sstevel@tonic-gate #define	MI_ACL		0x2000		/* server supports NFS_ACL */
4667c478bd9Sstevel@tonic-gate #define	MI_BINDINPROG	0x4000		/* binding to server is changing */
4677c478bd9Sstevel@tonic-gate #define	MI_LOOPBACK	0x8000		/* Set if this is a loopback mount */
4687c478bd9Sstevel@tonic-gate #define	MI_SEMISOFT	0x10000		/* soft reads, hard modify */
4697c478bd9Sstevel@tonic-gate #define	MI_NOPRINT	0x20000		/* don't print messages */
4707c478bd9Sstevel@tonic-gate #define	MI_DIRECTIO	0x40000		/* do direct I/O */
4717c478bd9Sstevel@tonic-gate #define	MI_EXTATTR	0x80000		/* server supports extended attrs */
4727c478bd9Sstevel@tonic-gate #define	MI_ASYNC_MGR_STOP	0x100000	/* tell async mgr to die */
4733fd6cc29Sthurlow #define	MI_DEAD		0x200000	/* mount has been terminated */
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate /*
4767c478bd9Sstevel@tonic-gate  * Read-only mntinfo statistics
4777c478bd9Sstevel@tonic-gate  */
4787c478bd9Sstevel@tonic-gate struct mntinfo_kstat {
4797c478bd9Sstevel@tonic-gate 	char		mik_proto[KNC_STRSIZE];
4807c478bd9Sstevel@tonic-gate 	uint32_t	mik_vers;
4817c478bd9Sstevel@tonic-gate 	uint_t		mik_flags;
4827c478bd9Sstevel@tonic-gate 	uint_t		mik_secmod;
4837c478bd9Sstevel@tonic-gate 	uint32_t	mik_curread;
4847c478bd9Sstevel@tonic-gate 	uint32_t	mik_curwrite;
4857c478bd9Sstevel@tonic-gate 	int		mik_timeo;
4867c478bd9Sstevel@tonic-gate 	int		mik_retrans;
4877c478bd9Sstevel@tonic-gate 	uint_t		mik_acregmin;
4887c478bd9Sstevel@tonic-gate 	uint_t		mik_acregmax;
4897c478bd9Sstevel@tonic-gate 	uint_t		mik_acdirmin;
4907c478bd9Sstevel@tonic-gate 	uint_t		mik_acdirmax;
4917c478bd9Sstevel@tonic-gate 	struct {
4927c478bd9Sstevel@tonic-gate 		uint32_t srtt;
4937c478bd9Sstevel@tonic-gate 		uint32_t deviate;
4947c478bd9Sstevel@tonic-gate 		uint32_t rtxcur;
4957c478bd9Sstevel@tonic-gate 	} mik_timers[NFS_CALLTYPES+1];
4967c478bd9Sstevel@tonic-gate 	uint32_t	mik_noresponse;
4977c478bd9Sstevel@tonic-gate 	uint32_t	mik_failover;
4987c478bd9Sstevel@tonic-gate 	uint32_t	mik_remap;
4997c478bd9Sstevel@tonic-gate 	char		mik_curserver[SYS_NMLN];
5007c478bd9Sstevel@tonic-gate };
5017c478bd9Sstevel@tonic-gate 
5020776f5e6SVallish Vaidyeshwara /*
5030776f5e6SVallish Vaidyeshwara  * Macro to wakeup sleeping async worker threads.
5040776f5e6SVallish Vaidyeshwara  */
5050776f5e6SVallish Vaidyeshwara #define	NFS_WAKE_ASYNC_WORKER(work_cv)	{				\
5060776f5e6SVallish Vaidyeshwara 	if (CV_HAS_WAITERS(&work_cv[NFS_ASYNC_QUEUE]))			\
5070776f5e6SVallish Vaidyeshwara 		cv_signal(&work_cv[NFS_ASYNC_QUEUE]);			\
5080776f5e6SVallish Vaidyeshwara 	else if (CV_HAS_WAITERS(&work_cv[NFS_ASYNC_PGOPS_QUEUE]))	\
5090776f5e6SVallish Vaidyeshwara 		cv_signal(&work_cv[NFS_ASYNC_PGOPS_QUEUE]);		\
5100776f5e6SVallish Vaidyeshwara }
5110776f5e6SVallish Vaidyeshwara 
5120776f5e6SVallish Vaidyeshwara #define	NFS_WAKEALL_ASYNC_WORKERS(work_cv) {				\
5130776f5e6SVallish Vaidyeshwara 	cv_broadcast(&work_cv[NFS_ASYNC_QUEUE]);			\
5140776f5e6SVallish Vaidyeshwara 	cv_broadcast(&work_cv[NFS_ASYNC_PGOPS_QUEUE]);			\
5150776f5e6SVallish Vaidyeshwara }
5160776f5e6SVallish Vaidyeshwara 
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate  * Mark cached attributes as timed out
5197c478bd9Sstevel@tonic-gate  *
5207c478bd9Sstevel@tonic-gate  * The caller must not be holding the rnode r_statelock mutex.
5217c478bd9Sstevel@tonic-gate  */
5227c478bd9Sstevel@tonic-gate #define	PURGE_ATTRCACHE(vp)	{				\
5237c478bd9Sstevel@tonic-gate 	rnode_t *rp = VTOR(vp);					\
5247c478bd9Sstevel@tonic-gate 	mutex_enter(&rp->r_statelock);				\
5257c478bd9Sstevel@tonic-gate 	PURGE_ATTRCACHE_LOCKED(rp);				\
5267c478bd9Sstevel@tonic-gate 	mutex_exit(&rp->r_statelock);				\
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate #define	PURGE_ATTRCACHE_LOCKED(rp)	{			\
5307c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&rp->r_statelock));			\
5317c478bd9Sstevel@tonic-gate 	rp->r_attrtime = gethrtime();				\
5327c478bd9Sstevel@tonic-gate 	rp->r_mtime = rp->r_attrtime;				\
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate /*
5367c478bd9Sstevel@tonic-gate  * Is the attribute cache valid?
5377c478bd9Sstevel@tonic-gate  */
5387c478bd9Sstevel@tonic-gate #define	ATTRCACHE_VALID(vp)	(gethrtime() < VTOR(vp)->r_attrtime)
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate /*
5417c478bd9Sstevel@tonic-gate  * Flags to indicate whether to purge the DNLC for non-directory vnodes
5427c478bd9Sstevel@tonic-gate  * in a call to nfs_purge_caches.
5437c478bd9Sstevel@tonic-gate  */
5447c478bd9Sstevel@tonic-gate #define	NFS_NOPURGE_DNLC	0
5457c478bd9Sstevel@tonic-gate #define	NFS_PURGE_DNLC		1
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate /*
5487c478bd9Sstevel@tonic-gate  * If returned error is ESTALE flush all caches.
5497c478bd9Sstevel@tonic-gate  */
5507c478bd9Sstevel@tonic-gate #define	PURGE_STALE_FH(error, vp, cr)				\
5517c478bd9Sstevel@tonic-gate 	if ((error) == ESTALE) {				\
5527c478bd9Sstevel@tonic-gate 		struct rnode *rp = VTOR(vp);			\
5537c478bd9Sstevel@tonic-gate 		if (vp->v_flag & VROOT) {			\
5547c478bd9Sstevel@tonic-gate 			servinfo_t *svp = rp->r_server;		\
5557c478bd9Sstevel@tonic-gate 			mutex_enter(&svp->sv_lock);		\
5567c478bd9Sstevel@tonic-gate 			svp->sv_flags |= SV_ROOT_STALE;		\
5577c478bd9Sstevel@tonic-gate 			mutex_exit(&svp->sv_lock);		\
5587c478bd9Sstevel@tonic-gate 		}						\
5597c478bd9Sstevel@tonic-gate 		mutex_enter(&rp->r_statelock);			\
5607c478bd9Sstevel@tonic-gate 		rp->r_flags |= RSTALE;				\
5617c478bd9Sstevel@tonic-gate 		if (!rp->r_error)				\
5627c478bd9Sstevel@tonic-gate 			rp->r_error = (error);			\
5637c478bd9Sstevel@tonic-gate 		mutex_exit(&rp->r_statelock);			\
5647c478bd9Sstevel@tonic-gate 		if (vn_has_cached_data(vp))			\
5657c478bd9Sstevel@tonic-gate 			nfs_invalidate_pages((vp), (u_offset_t)0, (cr)); \
5667c478bd9Sstevel@tonic-gate 		nfs_purge_caches((vp), NFS_PURGE_DNLC, (cr));	\
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate /*
5707c478bd9Sstevel@tonic-gate  * Is cache valid?
5717c478bd9Sstevel@tonic-gate  * Swap is always valid, if no attributes (attrtime == 0) or
5727c478bd9Sstevel@tonic-gate  * if mtime matches cached mtime it is valid
5737c478bd9Sstevel@tonic-gate  * NOTE: mtime is now a timestruc_t.
5747c478bd9Sstevel@tonic-gate  * Caller should be holding the rnode r_statelock mutex.
5757c478bd9Sstevel@tonic-gate  */
5767c478bd9Sstevel@tonic-gate #define	CACHE_VALID(rp, mtime, fsize)				\
5777c478bd9Sstevel@tonic-gate 	((RTOV(rp)->v_flag & VISSWAP) == VISSWAP ||		\
5787c478bd9Sstevel@tonic-gate 	(((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec &&	\
5797c478bd9Sstevel@tonic-gate 	(mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) &&	\
5807c478bd9Sstevel@tonic-gate 	((fsize) == (rp)->r_attr.va_size)))
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate /*
5837c478bd9Sstevel@tonic-gate  * Macro to detect forced unmount or a zone shutdown.
5847c478bd9Sstevel@tonic-gate  */
5857c478bd9Sstevel@tonic-gate #define	FS_OR_ZONE_GONE(vfsp) \
5867c478bd9Sstevel@tonic-gate 	(((vfsp)->vfs_flag & VFS_UNMOUNTED) || \
5877c478bd9Sstevel@tonic-gate 	zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN)
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate /*
5907c478bd9Sstevel@tonic-gate  * Convert NFS tunables to hrtime_t units, seconds to nanoseconds.
5917c478bd9Sstevel@tonic-gate  */
5927c478bd9Sstevel@tonic-gate #define	SEC2HR(sec)	((sec) * (long long)NANOSEC)
5937c478bd9Sstevel@tonic-gate #define	HR2SEC(hr)	((hr) / (long long)NANOSEC)
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate /*
5967c478bd9Sstevel@tonic-gate  * Structure to identify owner of a PC file share reservation.
5977c478bd9Sstevel@tonic-gate  */
5987c478bd9Sstevel@tonic-gate struct nfs_owner {
5997c478bd9Sstevel@tonic-gate 	int	magic;		/* magic uniquifying number */
6007c478bd9Sstevel@tonic-gate 	char	hname[16];	/* first 16 bytes of hostname */
6017c478bd9Sstevel@tonic-gate 	char	lowner[8];	/* local owner from fcntl */
6027c478bd9Sstevel@tonic-gate };
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate /*
6057c478bd9Sstevel@tonic-gate  * Values for magic.
6067c478bd9Sstevel@tonic-gate  */
6077c478bd9Sstevel@tonic-gate #define	NFS_OWNER_MAGIC	0x1D81E
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate /*
6107c478bd9Sstevel@tonic-gate  * Support for extended attributes
6117c478bd9Sstevel@tonic-gate  */
6127c478bd9Sstevel@tonic-gate #define	XATTR_DIR_NAME	"/@/"		/* used for DNLC entries */
6137c478bd9Sstevel@tonic-gate #define	XATTR_RPATH	"ExTaTtR"	/* used for r_path for failover */
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate /*
6167c478bd9Sstevel@tonic-gate  * Short hand for checking to see whether the file system was mounted
6177c478bd9Sstevel@tonic-gate  * interruptible or not.
6187c478bd9Sstevel@tonic-gate  */
6197c478bd9Sstevel@tonic-gate #define	INTR(vp)	(VTOMI(vp)->mi_flags & MI_INT)
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate /*
6227c478bd9Sstevel@tonic-gate  * Short hand for checking whether failover is enabled or not
6237c478bd9Sstevel@tonic-gate  */
6247c478bd9Sstevel@tonic-gate #define	FAILOVER_MOUNT(mi)	(mi->mi_servers->sv_next)
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate /*
6277c478bd9Sstevel@tonic-gate  * How long will async threads wait for additional work.
6287c478bd9Sstevel@tonic-gate  */
6297c478bd9Sstevel@tonic-gate #define	NFS_ASYNC_TIMEOUT	(60 * 1 * hz)	/* 1 minute */
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate #ifdef _KERNEL
6327c478bd9Sstevel@tonic-gate extern int	clget(clinfo_t *, servinfo_t *, cred_t *, CLIENT **,
6337c478bd9Sstevel@tonic-gate 		    struct chtab **);
6347c478bd9Sstevel@tonic-gate extern void	clfree(CLIENT *, struct chtab *);
6357c478bd9Sstevel@tonic-gate extern void	nfs_mi_zonelist_add(mntinfo_t *);
6367c478bd9Sstevel@tonic-gate extern void	nfs_free_mi(mntinfo_t *);
6377c478bd9Sstevel@tonic-gate extern void	nfs_mnt_kstat_init(struct vfs *);
6387c478bd9Sstevel@tonic-gate #endif
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate /*
6417c478bd9Sstevel@tonic-gate  * Per-zone data for managing client handles.  Included here solely for the
6427c478bd9Sstevel@tonic-gate  * benefit of MDB.
6437c478bd9Sstevel@tonic-gate  */
6447c478bd9Sstevel@tonic-gate /*
6457c478bd9Sstevel@tonic-gate  * client side statistics
6467c478bd9Sstevel@tonic-gate  */
6477c478bd9Sstevel@tonic-gate struct clstat {
6487c478bd9Sstevel@tonic-gate 	kstat_named_t	calls;			/* client requests */
6497c478bd9Sstevel@tonic-gate 	kstat_named_t	badcalls;		/* rpc failures */
6507c478bd9Sstevel@tonic-gate 	kstat_named_t	clgets;			/* client handle gets */
6517c478bd9Sstevel@tonic-gate 	kstat_named_t	cltoomany;		/* client handle cache misses */
6527c478bd9Sstevel@tonic-gate #ifdef DEBUG
6537c478bd9Sstevel@tonic-gate 	kstat_named_t	clalloc;		/* number of client handles */
6547c478bd9Sstevel@tonic-gate 	kstat_named_t	noresponse;		/* server not responding cnt */
6557c478bd9Sstevel@tonic-gate 	kstat_named_t	failover;		/* server failover count */
6567c478bd9Sstevel@tonic-gate 	kstat_named_t	remap;			/* server remap count */
6577c478bd9Sstevel@tonic-gate #endif
6587c478bd9Sstevel@tonic-gate };
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate struct nfs_clnt {
6617c478bd9Sstevel@tonic-gate 	struct chhead	*nfscl_chtable;
6627c478bd9Sstevel@tonic-gate 	kmutex_t	nfscl_chtable_lock;
6637c478bd9Sstevel@tonic-gate 	zoneid_t	nfscl_zoneid;
6647c478bd9Sstevel@tonic-gate 	list_node_t	nfscl_node;
6657c478bd9Sstevel@tonic-gate 	struct clstat	nfscl_stat;
6667c478bd9Sstevel@tonic-gate };
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
6697c478bd9Sstevel@tonic-gate }
6707c478bd9Sstevel@tonic-gate #endif
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate #endif	/* _NFS_NFS_CLNT_H */
673