xref: /illumos-gate/usr/src/uts/common/nfs/nfs4_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
5f86c6ccaSdm  * Common Development and Distribution License (the "License").
6f86c6ccaSdm  * 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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
267c478bd9Sstevel@tonic-gate /*	All Rights Reserved   */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
307c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #ifndef _NFS4_CLNT_H
347c478bd9Sstevel@tonic-gate #define	_NFS4_CLNT_H
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <sys/errno.h>
377c478bd9Sstevel@tonic-gate #include <sys/types.h>
387c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
397c478bd9Sstevel@tonic-gate #include <sys/time.h>
407c478bd9Sstevel@tonic-gate #include <sys/flock.h>
417c478bd9Sstevel@tonic-gate #include <vm/page.h>
427c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h>
437c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
447c478bd9Sstevel@tonic-gate #include <nfs/rnode.h>
457c478bd9Sstevel@tonic-gate #include <sys/avl.h>
467c478bd9Sstevel@tonic-gate #include <sys/list.h>
47b9238976Sth #include <rpc/auth.h>
482f172c55SRobert Thurlow #include <sys/door.h>
490776f5e6SVallish Vaidyeshwara #include <sys/condvar_impl.h>
50a19609f8Sjv #include <sys/zone.h>
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
537c478bd9Sstevel@tonic-gate extern "C" {
547c478bd9Sstevel@tonic-gate #endif
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #define	NFS4_SIZE_OK(size)	((size) <= MAXOFFSET_T)
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /* Four states of nfs4_server's lease_valid */
597c478bd9Sstevel@tonic-gate #define	NFS4_LEASE_INVALID		0
607c478bd9Sstevel@tonic-gate #define	NFS4_LEASE_VALID		1
617c478bd9Sstevel@tonic-gate #define	NFS4_LEASE_UNINITIALIZED	2
627c478bd9Sstevel@tonic-gate #define	NFS4_LEASE_NOT_STARTED		3
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate /* flag to tell the renew thread it should exit */
657c478bd9Sstevel@tonic-gate #define	NFS4_THREAD_EXIT	1
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /* Default number of seconds to wait on GRACE and DELAY errors */
687c478bd9Sstevel@tonic-gate #define	NFS4ERR_DELAY_TIME	10
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate /* Number of hash buckets for open owners for each nfs4_server */
717c478bd9Sstevel@tonic-gate #define	NFS4_NUM_OO_BUCKETS	53
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /* Number of freed open owners (per mntinfo4_t) to keep around */
747c478bd9Sstevel@tonic-gate #define	NFS4_NUM_FREED_OPEN_OWNERS	8
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */
777c478bd9Sstevel@tonic-gate #define	NFS4_RETRY_SCLID_DELAY	10
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */
807c478bd9Sstevel@tonic-gate #define	NFS4_NUM_SCLID_RETRIES	3
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */
837c478bd9Sstevel@tonic-gate #define	NFS4_NUM_RETRY_BAD_SEQID	3
847c478bd9Sstevel@tonic-gate 
850776f5e6SVallish Vaidyeshwara /*
860776f5e6SVallish Vaidyeshwara  * Macro to wakeup sleeping async worker threads.
870776f5e6SVallish Vaidyeshwara  */
880776f5e6SVallish Vaidyeshwara #define	NFS4_WAKE_ASYNC_WORKER(work_cv)	{				\
890776f5e6SVallish Vaidyeshwara 	if (CV_HAS_WAITERS(&work_cv[NFS4_ASYNC_QUEUE])) 		\
900776f5e6SVallish Vaidyeshwara 		cv_signal(&work_cv[NFS4_ASYNC_QUEUE]);			\
910776f5e6SVallish Vaidyeshwara 	else if (CV_HAS_WAITERS(&work_cv[NFS4_ASYNC_PGOPS_QUEUE])) 	\
920776f5e6SVallish Vaidyeshwara 		cv_signal(&work_cv[NFS4_ASYNC_PGOPS_QUEUE]);		\
930776f5e6SVallish Vaidyeshwara }
940776f5e6SVallish Vaidyeshwara 
950776f5e6SVallish Vaidyeshwara #define	NFS4_WAKEALL_ASYNC_WORKERS(work_cv) {				\
960776f5e6SVallish Vaidyeshwara 		cv_broadcast(&work_cv[NFS4_ASYNC_QUEUE]);		\
970776f5e6SVallish Vaidyeshwara 		cv_broadcast(&work_cv[NFS4_ASYNC_PGOPS_QUEUE]);		\
980776f5e6SVallish Vaidyeshwara }
990776f5e6SVallish Vaidyeshwara 
1007c478bd9Sstevel@tonic-gate /*
1017c478bd9Sstevel@tonic-gate  * Is the attribute cache valid?  If client holds a delegation, then attrs
1027c478bd9Sstevel@tonic-gate  * are by definition valid.  If not, then check to see if attrs have timed out.
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate #define	ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \
1057c478bd9Sstevel@tonic-gate 	gethrtime() < VTOR4(vp)->r_time_attr_inval)
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate  * Flags to indicate whether to purge the DNLC for non-directory vnodes
1097c478bd9Sstevel@tonic-gate  * in a call to nfs_purge_caches.
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate #define	NFS4_NOPURGE_DNLC	0
1127c478bd9Sstevel@tonic-gate #define	NFS4_PURGE_DNLC		1
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate /*
1157c478bd9Sstevel@tonic-gate  * Is cache valid?
1167c478bd9Sstevel@tonic-gate  * Swap is always valid, if no attributes (attrtime == 0) or
1177c478bd9Sstevel@tonic-gate  * if mtime matches cached mtime it is valid
1187c478bd9Sstevel@tonic-gate  * NOTE: mtime is now a timestruc_t.
1197c478bd9Sstevel@tonic-gate  * Caller should be holding the rnode r_statelock mutex.
1207c478bd9Sstevel@tonic-gate  */
1217c478bd9Sstevel@tonic-gate #define	CACHE4_VALID(rp, mtime, fsize)				\
1227c478bd9Sstevel@tonic-gate 	((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP ||		\
1237c478bd9Sstevel@tonic-gate 	(((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec &&	\
1247c478bd9Sstevel@tonic-gate 	(mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) &&	\
1257c478bd9Sstevel@tonic-gate 	((fsize) == (rp)->r_attr.va_size)))
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate /*
1287c478bd9Sstevel@tonic-gate  * Macro to detect forced unmount or a zone shutdown.
1297c478bd9Sstevel@tonic-gate  */
1307c478bd9Sstevel@tonic-gate #define	FS_OR_ZONE_GONE4(vfsp) \
1317c478bd9Sstevel@tonic-gate 	(((vfsp)->vfs_flag & VFS_UNMOUNTED) || \
1327c478bd9Sstevel@tonic-gate 	zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN)
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate /*
1357c478bd9Sstevel@tonic-gate  * Macro to help determine whether a request failed because the underlying
1367c478bd9Sstevel@tonic-gate  * filesystem has been forcibly unmounted or because of zone shutdown.
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate #define	NFS4_FRC_UNMT_ERR(err, vfsp) \
1397c478bd9Sstevel@tonic-gate 	((err) == EIO && FS_OR_ZONE_GONE4((vfsp)))
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate  * Due to the way the address space callbacks are used to execute a delmap,
1437c478bd9Sstevel@tonic-gate  * we must keep track of how many times the same thread has called
1447c478bd9Sstevel@tonic-gate  * VOP_DELMAP()->nfs4_delmap().  This is done by having a list of
1457c478bd9Sstevel@tonic-gate  * nfs4_delmapcall_t's associated with each rnode4_t.  This list is protected
1467c478bd9Sstevel@tonic-gate  * by the rnode4_t's r_statelock.  The individual elements do not need to be
1477c478bd9Sstevel@tonic-gate  * protected as they will only ever be created, modified and destroyed by
1487c478bd9Sstevel@tonic-gate  * one thread (the call_id).
1497c478bd9Sstevel@tonic-gate  * See nfs4_delmap() for further explanation.
1507c478bd9Sstevel@tonic-gate  */
1517c478bd9Sstevel@tonic-gate typedef struct nfs4_delmapcall {
1527c478bd9Sstevel@tonic-gate 	kthread_t	*call_id;
1537c478bd9Sstevel@tonic-gate 	int		error;	/* error from delmap */
1547c478bd9Sstevel@tonic-gate 	list_node_t	call_node;
1557c478bd9Sstevel@tonic-gate } nfs4_delmapcall_t;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate /*
1587c478bd9Sstevel@tonic-gate  * delmap address space callback args
1597c478bd9Sstevel@tonic-gate  */
1607c478bd9Sstevel@tonic-gate typedef struct nfs4_delmap_args {
1617c478bd9Sstevel@tonic-gate 	vnode_t			*vp;
1627c478bd9Sstevel@tonic-gate 	offset_t		off;
1637c478bd9Sstevel@tonic-gate 	caddr_t			addr;
1647c478bd9Sstevel@tonic-gate 	size_t			len;
1657c478bd9Sstevel@tonic-gate 	uint_t			prot;
1667c478bd9Sstevel@tonic-gate 	uint_t			maxprot;
1677c478bd9Sstevel@tonic-gate 	uint_t			flags;
1687c478bd9Sstevel@tonic-gate 	cred_t			*cr;
1697c478bd9Sstevel@tonic-gate 	nfs4_delmapcall_t	*caller; /* to retrieve errors from the cb */
1707c478bd9Sstevel@tonic-gate } nfs4_delmap_args_t;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate  * client side statistics
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate  * Per-zone counters
1777c478bd9Sstevel@tonic-gate  */
1787c478bd9Sstevel@tonic-gate struct clstat4 {
1797c478bd9Sstevel@tonic-gate 	kstat_named_t	calls;			/* client requests */
1807c478bd9Sstevel@tonic-gate 	kstat_named_t	badcalls;		/* rpc failures */
1812f172c55SRobert Thurlow 	kstat_named_t	referrals;		/* referrals */
1822f172c55SRobert Thurlow 	kstat_named_t	referlinks;		/* referrals as symlinks */
1837c478bd9Sstevel@tonic-gate 	kstat_named_t	clgets;			/* client handle gets */
1847c478bd9Sstevel@tonic-gate 	kstat_named_t	cltoomany;		/* client handle cache misses */
1857c478bd9Sstevel@tonic-gate #ifdef DEBUG
1867c478bd9Sstevel@tonic-gate 	kstat_named_t	clalloc;		/* number of client handles */
1877c478bd9Sstevel@tonic-gate 	kstat_named_t	noresponse;		/* server not responding cnt */
1887c478bd9Sstevel@tonic-gate 	kstat_named_t	failover;		/* server failover count */
1897c478bd9Sstevel@tonic-gate 	kstat_named_t	remap;			/* server remap count */
1907c478bd9Sstevel@tonic-gate #endif
1917c478bd9Sstevel@tonic-gate };
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #ifdef DEBUG
1947c478bd9Sstevel@tonic-gate /*
1957c478bd9Sstevel@tonic-gate  * The following are statistics that describe the behavior of the system as a
1967c478bd9Sstevel@tonic-gate  * whole and don't correspond to any particular zone.
1977c478bd9Sstevel@tonic-gate  */
1987c478bd9Sstevel@tonic-gate struct clstat4_debug {
1997c478bd9Sstevel@tonic-gate 	kstat_named_t	nrnode;			/* number of allocated rnodes */
2007c478bd9Sstevel@tonic-gate 	kstat_named_t	access;			/* size of access cache */
2017c478bd9Sstevel@tonic-gate 	kstat_named_t	dirent;			/* size of readdir cache */
2027c478bd9Sstevel@tonic-gate 	kstat_named_t	dirents;		/* size of readdir buf cache */
2037c478bd9Sstevel@tonic-gate 	kstat_named_t	reclaim;		/* number of reclaims */
2047c478bd9Sstevel@tonic-gate 	kstat_named_t	clreclaim;		/* number of cl reclaims */
2057c478bd9Sstevel@tonic-gate 	kstat_named_t	f_reclaim;		/* number of free reclaims */
2067c478bd9Sstevel@tonic-gate 	kstat_named_t	a_reclaim;		/* number of active reclaims */
2077c478bd9Sstevel@tonic-gate 	kstat_named_t	r_reclaim;		/* number of rnode reclaims */
2087c478bd9Sstevel@tonic-gate 	kstat_named_t	rpath;			/* bytes used to store rpaths */
2097c478bd9Sstevel@tonic-gate };
2107c478bd9Sstevel@tonic-gate extern struct clstat4_debug clstat4_debug;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate #endif
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate /*
2150776f5e6SVallish Vaidyeshwara  * The NFS specific async_reqs structure. iotype4 is grouped to support two
2160776f5e6SVallish Vaidyeshwara  * types of async thread pools, please read comments section of mntinfo4_t
2170776f5e6SVallish Vaidyeshwara  * definition for more information. Care should be taken while adding new
2180776f5e6SVallish Vaidyeshwara  * members to this group.
2197c478bd9Sstevel@tonic-gate  */
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate enum iotype4 {
2227c478bd9Sstevel@tonic-gate 	NFS4_PUTAPAGE,
2237c478bd9Sstevel@tonic-gate 	NFS4_PAGEIO,
2240776f5e6SVallish Vaidyeshwara 	NFS4_COMMIT,
2250776f5e6SVallish Vaidyeshwara 	NFS4_READ_AHEAD,
2267c478bd9Sstevel@tonic-gate 	NFS4_READDIR,
2277c478bd9Sstevel@tonic-gate 	NFS4_INACTIVE,
2280776f5e6SVallish Vaidyeshwara 	NFS4_ASYNC_TYPES
2297c478bd9Sstevel@tonic-gate };
2300776f5e6SVallish Vaidyeshwara #define	NFS4_ASYNC_PGOPS_TYPES	(NFS4_COMMIT + 1)
2310776f5e6SVallish Vaidyeshwara 
2320776f5e6SVallish Vaidyeshwara /*
2330776f5e6SVallish Vaidyeshwara  * NFS async requests queue type.
2340776f5e6SVallish Vaidyeshwara  */
2350776f5e6SVallish Vaidyeshwara enum ioqtype4 {
2360776f5e6SVallish Vaidyeshwara 	NFS4_ASYNC_QUEUE,
2370776f5e6SVallish Vaidyeshwara 	NFS4_ASYNC_PGOPS_QUEUE,
2380776f5e6SVallish Vaidyeshwara 	NFS4_MAX_ASYNC_QUEUES
2390776f5e6SVallish Vaidyeshwara };
2400776f5e6SVallish Vaidyeshwara 
2410776f5e6SVallish Vaidyeshwara /*
2420776f5e6SVallish Vaidyeshwara  * Number of NFS async threads operating exclusively on page op requests.
2430776f5e6SVallish Vaidyeshwara  */
2440776f5e6SVallish Vaidyeshwara #define	NUM_ASYNC_PGOPS_THREADS	0x2
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate struct nfs4_async_read_req {
2477c478bd9Sstevel@tonic-gate 	void (*readahead)();		/* pointer to readahead function */
2487c478bd9Sstevel@tonic-gate 	u_offset_t blkoff;		/* offset in file */
2497c478bd9Sstevel@tonic-gate 	struct seg *seg;		/* segment to do i/o to */
2507c478bd9Sstevel@tonic-gate 	caddr_t addr;			/* address to do i/o to */
2517c478bd9Sstevel@tonic-gate };
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate struct nfs4_pageio_req {
2547c478bd9Sstevel@tonic-gate 	int (*pageio)();		/* pointer to pageio function */
2557c478bd9Sstevel@tonic-gate 	page_t *pp;			/* page list */
2567c478bd9Sstevel@tonic-gate 	u_offset_t io_off;		/* offset in file */
2577c478bd9Sstevel@tonic-gate 	uint_t io_len;			/* size of request */
2587c478bd9Sstevel@tonic-gate 	int flags;
2597c478bd9Sstevel@tonic-gate };
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate struct nfs4_readdir_req {
2627c478bd9Sstevel@tonic-gate 	int (*readdir)();		/* pointer to readdir function */
2637c478bd9Sstevel@tonic-gate 	struct rddir4_cache *rdc;	/* pointer to cache entry to fill */
2647c478bd9Sstevel@tonic-gate };
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate struct nfs4_commit_req {
2677c478bd9Sstevel@tonic-gate 	void (*commit)();		/* pointer to commit function */
2687c478bd9Sstevel@tonic-gate 	page_t *plist;			/* page list */
2697c478bd9Sstevel@tonic-gate 	offset4 offset;			/* starting offset */
2707c478bd9Sstevel@tonic-gate 	count4 count;			/* size of range to be commited */
2717c478bd9Sstevel@tonic-gate };
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate struct nfs4_async_reqs {
2747c478bd9Sstevel@tonic-gate 	struct nfs4_async_reqs *a_next;	/* pointer to next arg struct */
2757c478bd9Sstevel@tonic-gate #ifdef DEBUG
2767c478bd9Sstevel@tonic-gate 	kthread_t *a_queuer;		/* thread id of queueing thread */
2777c478bd9Sstevel@tonic-gate #endif
2787c478bd9Sstevel@tonic-gate 	struct vnode *a_vp;		/* vnode pointer */
2797c478bd9Sstevel@tonic-gate 	struct cred *a_cred;		/* cred pointer */
2807c478bd9Sstevel@tonic-gate 	enum iotype4 a_io;		/* i/o type */
2817c478bd9Sstevel@tonic-gate 	union {
2827c478bd9Sstevel@tonic-gate 		struct nfs4_async_read_req a_read_args;
2837c478bd9Sstevel@tonic-gate 		struct nfs4_pageio_req a_pageio_args;
2847c478bd9Sstevel@tonic-gate 		struct nfs4_readdir_req a_readdir_args;
2857c478bd9Sstevel@tonic-gate 		struct nfs4_commit_req a_commit_args;
2867c478bd9Sstevel@tonic-gate 	} a_args;
2877c478bd9Sstevel@tonic-gate };
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate #define	a_nfs4_readahead a_args.a_read_args.readahead
2907c478bd9Sstevel@tonic-gate #define	a_nfs4_blkoff a_args.a_read_args.blkoff
2917c478bd9Sstevel@tonic-gate #define	a_nfs4_seg a_args.a_read_args.seg
2927c478bd9Sstevel@tonic-gate #define	a_nfs4_addr a_args.a_read_args.addr
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate #define	a_nfs4_putapage a_args.a_pageio_args.pageio
2957c478bd9Sstevel@tonic-gate #define	a_nfs4_pageio a_args.a_pageio_args.pageio
2967c478bd9Sstevel@tonic-gate #define	a_nfs4_pp a_args.a_pageio_args.pp
2977c478bd9Sstevel@tonic-gate #define	a_nfs4_off a_args.a_pageio_args.io_off
2987c478bd9Sstevel@tonic-gate #define	a_nfs4_len a_args.a_pageio_args.io_len
2997c478bd9Sstevel@tonic-gate #define	a_nfs4_flags a_args.a_pageio_args.flags
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate #define	a_nfs4_readdir a_args.a_readdir_args.readdir
3027c478bd9Sstevel@tonic-gate #define	a_nfs4_rdc a_args.a_readdir_args.rdc
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate #define	a_nfs4_commit a_args.a_commit_args.commit
3057c478bd9Sstevel@tonic-gate #define	a_nfs4_plist a_args.a_commit_args.plist
3067c478bd9Sstevel@tonic-gate #define	a_nfs4_offset a_args.a_commit_args.offset
3077c478bd9Sstevel@tonic-gate #define	a_nfs4_count a_args.a_commit_args.count
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate /*
3107c478bd9Sstevel@tonic-gate  * Security information
3117c478bd9Sstevel@tonic-gate  */
3127c478bd9Sstevel@tonic-gate typedef struct sv_secinfo {
3137c478bd9Sstevel@tonic-gate 	uint_t		count;	/* how many sdata there are */
3147c478bd9Sstevel@tonic-gate 	uint_t		index;	/* which sdata[index] */
3157c478bd9Sstevel@tonic-gate 	struct sec_data	*sdata;
3167c478bd9Sstevel@tonic-gate } sv_secinfo_t;
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate /*
3197c478bd9Sstevel@tonic-gate  * Hash bucket for the mi's open owner list (mi_oo_list).
3207c478bd9Sstevel@tonic-gate  */
3217c478bd9Sstevel@tonic-gate typedef struct nfs4_oo_hash_bucket {
3227c478bd9Sstevel@tonic-gate 	list_t			b_oo_hash_list;
3237c478bd9Sstevel@tonic-gate 	kmutex_t		b_lock;
3247c478bd9Sstevel@tonic-gate } nfs4_oo_hash_bucket_t;
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate /*
3277c478bd9Sstevel@tonic-gate  * Global array of ctags.
3287c478bd9Sstevel@tonic-gate  */
3297c478bd9Sstevel@tonic-gate extern ctag_t nfs4_ctags[];
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate typedef enum nfs4_tag_type {
3327c478bd9Sstevel@tonic-gate 	TAG_NONE,
3337c478bd9Sstevel@tonic-gate 	TAG_ACCESS,
3347c478bd9Sstevel@tonic-gate 	TAG_CLOSE,
3357c478bd9Sstevel@tonic-gate 	TAG_CLOSE_LOST,
3367c478bd9Sstevel@tonic-gate 	TAG_CLOSE_UNDO,
3377c478bd9Sstevel@tonic-gate 	TAG_COMMIT,
3387c478bd9Sstevel@tonic-gate 	TAG_DELEGRETURN,
3397c478bd9Sstevel@tonic-gate 	TAG_FSINFO,
3407c478bd9Sstevel@tonic-gate 	TAG_GET_SYMLINK,
3417c478bd9Sstevel@tonic-gate 	TAG_GETATTR,
3422f172c55SRobert Thurlow 	TAG_GETATTR_FSLOCATION,
3437c478bd9Sstevel@tonic-gate 	TAG_INACTIVE,
3447c478bd9Sstevel@tonic-gate 	TAG_LINK,
3457c478bd9Sstevel@tonic-gate 	TAG_LOCK,
3467c478bd9Sstevel@tonic-gate 	TAG_LOCK_RECLAIM,
3477c478bd9Sstevel@tonic-gate 	TAG_LOCK_RESEND,
3487c478bd9Sstevel@tonic-gate 	TAG_LOCK_REINSTATE,
3497c478bd9Sstevel@tonic-gate 	TAG_LOCK_UNKNOWN,
3507c478bd9Sstevel@tonic-gate 	TAG_LOCKT,
3517c478bd9Sstevel@tonic-gate 	TAG_LOCKU,
3527c478bd9Sstevel@tonic-gate 	TAG_LOCKU_RESEND,
3537c478bd9Sstevel@tonic-gate 	TAG_LOCKU_REINSTATE,
3547c478bd9Sstevel@tonic-gate 	TAG_LOOKUP,
3557c478bd9Sstevel@tonic-gate 	TAG_LOOKUP_PARENT,
3567c478bd9Sstevel@tonic-gate 	TAG_LOOKUP_VALID,
3577c478bd9Sstevel@tonic-gate 	TAG_LOOKUP_VPARENT,
3587c478bd9Sstevel@tonic-gate 	TAG_MKDIR,
3597c478bd9Sstevel@tonic-gate 	TAG_MKNOD,
3607c478bd9Sstevel@tonic-gate 	TAG_MOUNT,
3617c478bd9Sstevel@tonic-gate 	TAG_OPEN,
3627c478bd9Sstevel@tonic-gate 	TAG_OPEN_CONFIRM,
3637c478bd9Sstevel@tonic-gate 	TAG_OPEN_CONFIRM_LOST,
3647c478bd9Sstevel@tonic-gate 	TAG_OPEN_DG,
3657c478bd9Sstevel@tonic-gate 	TAG_OPEN_DG_LOST,
3667c478bd9Sstevel@tonic-gate 	TAG_OPEN_LOST,
3677c478bd9Sstevel@tonic-gate 	TAG_OPENATTR,
3687c478bd9Sstevel@tonic-gate 	TAG_PATHCONF,
3697c478bd9Sstevel@tonic-gate 	TAG_PUTROOTFH,
3707c478bd9Sstevel@tonic-gate 	TAG_READ,
3717c478bd9Sstevel@tonic-gate 	TAG_READAHEAD,
3727c478bd9Sstevel@tonic-gate 	TAG_READDIR,
3737c478bd9Sstevel@tonic-gate 	TAG_READLINK,
3747c478bd9Sstevel@tonic-gate 	TAG_RELOCK,
3757c478bd9Sstevel@tonic-gate 	TAG_REMAP_LOOKUP,
3767c478bd9Sstevel@tonic-gate 	TAG_REMAP_LOOKUP_AD,
3777c478bd9Sstevel@tonic-gate 	TAG_REMAP_LOOKUP_NA,
3787c478bd9Sstevel@tonic-gate 	TAG_REMAP_MOUNT,
3797c478bd9Sstevel@tonic-gate 	TAG_RMDIR,
3807c478bd9Sstevel@tonic-gate 	TAG_REMOVE,
3817c478bd9Sstevel@tonic-gate 	TAG_RENAME,
3827c478bd9Sstevel@tonic-gate 	TAG_RENAME_VFH,
3837c478bd9Sstevel@tonic-gate 	TAG_RENEW,
3847c478bd9Sstevel@tonic-gate 	TAG_REOPEN,
3857c478bd9Sstevel@tonic-gate 	TAG_REOPEN_LOST,
3867c478bd9Sstevel@tonic-gate 	TAG_SECINFO,
3877c478bd9Sstevel@tonic-gate 	TAG_SETATTR,
3887c478bd9Sstevel@tonic-gate 	TAG_SETCLIENTID,
3897c478bd9Sstevel@tonic-gate 	TAG_SETCLIENTID_CF,
3907c478bd9Sstevel@tonic-gate 	TAG_SYMLINK,
3917c478bd9Sstevel@tonic-gate 	TAG_WRITE
3927c478bd9Sstevel@tonic-gate } nfs4_tag_type_t;
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate #define	NFS4_TAG_INITIALIZER	{				\
3957c478bd9Sstevel@tonic-gate 		{TAG_NONE,		"",			\
3967c478bd9Sstevel@tonic-gate 			{0x20202020, 0x20202020, 0x20202020}},	\
3977c478bd9Sstevel@tonic-gate 		{TAG_ACCESS,		"access",		\
3987c478bd9Sstevel@tonic-gate 			{0x61636365, 0x73732020, 0x20202020}},	\
3997c478bd9Sstevel@tonic-gate 		{TAG_CLOSE,		"close",		\
4007c478bd9Sstevel@tonic-gate 			{0x636c6f73, 0x65202020, 0x20202020}},	\
4017c478bd9Sstevel@tonic-gate 		{TAG_CLOSE_LOST,	"lost close",		\
4027c478bd9Sstevel@tonic-gate 			{0x6c6f7374, 0x20636c6f, 0x73652020}},	\
4037c478bd9Sstevel@tonic-gate 		{TAG_CLOSE_UNDO,	"undo close",		\
4047c478bd9Sstevel@tonic-gate 			{0x756e646f, 0x20636c6f, 0x73652020}},	\
4057c478bd9Sstevel@tonic-gate 		{TAG_COMMIT,		"commit",		\
4067c478bd9Sstevel@tonic-gate 			{0x636f6d6d, 0x69742020, 0x20202020}},	\
4077c478bd9Sstevel@tonic-gate 		{TAG_DELEGRETURN,	"delegreturn",		\
4087c478bd9Sstevel@tonic-gate 			{0x64656c65, 0x67726574, 0x75726e20}},	\
4097c478bd9Sstevel@tonic-gate 		{TAG_FSINFO,		"fsinfo",		\
4107c478bd9Sstevel@tonic-gate 			{0x6673696e, 0x666f2020, 0x20202020}},	\
4117c478bd9Sstevel@tonic-gate 		{TAG_GET_SYMLINK,	"get symlink text",	\
4127c478bd9Sstevel@tonic-gate 			{0x67657420, 0x736c6e6b, 0x20747874}},	\
4137c478bd9Sstevel@tonic-gate 		{TAG_GETATTR,		"getattr",		\
4147c478bd9Sstevel@tonic-gate 			{0x67657461, 0x74747220, 0x20202020}},	\
4152f172c55SRobert Thurlow 		{TAG_GETATTR_FSLOCATION, "getattr fslocation",	\
4162f172c55SRobert Thurlow 			{0x67657461, 0x74747220, 0x66736c6f}},	\
4177c478bd9Sstevel@tonic-gate 		{TAG_INACTIVE,		"inactive",		\
4187c478bd9Sstevel@tonic-gate 			{0x696e6163, 0x74697665, 0x20202020}},	\
4197c478bd9Sstevel@tonic-gate 		{TAG_LINK,		"link",			\
4207c478bd9Sstevel@tonic-gate 			{0x6c696e6b, 0x20202020, 0x20202020}},	\
4217c478bd9Sstevel@tonic-gate 		{TAG_LOCK,		"lock",			\
4227c478bd9Sstevel@tonic-gate 			{0x6c6f636b, 0x20202020, 0x20202020}},	\
4237c478bd9Sstevel@tonic-gate 		{TAG_LOCK_RECLAIM,	"reclaim lock",		\
4247c478bd9Sstevel@tonic-gate 			{0x7265636c, 0x61696d20, 0x6c6f636b}},	\
4257c478bd9Sstevel@tonic-gate 		{TAG_LOCK_RESEND,	"resend lock",		\
4267c478bd9Sstevel@tonic-gate 			{0x72657365, 0x6e64206c, 0x6f636b20}},	\
4277c478bd9Sstevel@tonic-gate 		{TAG_LOCK_REINSTATE,	"reinstate lock",	\
4287c478bd9Sstevel@tonic-gate 			{0x7265696e, 0x7374206c, 0x6f636b20}},	\
4297c478bd9Sstevel@tonic-gate 		{TAG_LOCK_UNKNOWN,	"unknown lock",		\
4307c478bd9Sstevel@tonic-gate 			{0x756e6b6e, 0x6f776e20, 0x6c6f636b}},	\
4317c478bd9Sstevel@tonic-gate 		{TAG_LOCKT,		"lock test",		\
4327c478bd9Sstevel@tonic-gate 			{0x6c6f636b, 0x5f746573, 0x74202020}},	\
4337c478bd9Sstevel@tonic-gate 		{TAG_LOCKU,		"unlock",		\
4347c478bd9Sstevel@tonic-gate 			{0x756e6c6f, 0x636b2020, 0x20202020}},	\
4357c478bd9Sstevel@tonic-gate 		{TAG_LOCKU_RESEND,	"resend locku",		\
4367c478bd9Sstevel@tonic-gate 			{0x72657365, 0x6e64206c, 0x6f636b75}},	\
4377c478bd9Sstevel@tonic-gate 		{TAG_LOCKU_REINSTATE,	"reinstate unlock",	\
4387c478bd9Sstevel@tonic-gate 			{0x7265696e, 0x73742075, 0x6e6c636b}},	\
4397c478bd9Sstevel@tonic-gate 		{TAG_LOOKUP,		"lookup",		\
4407c478bd9Sstevel@tonic-gate 			{0x6c6f6f6b, 0x75702020, 0x20202020}},	\
4417c478bd9Sstevel@tonic-gate 		{TAG_LOOKUP_PARENT,	"lookup parent",	\
4427c478bd9Sstevel@tonic-gate 			{0x6c6f6f6b, 0x75702070, 0x6172656e}},	\
4437c478bd9Sstevel@tonic-gate 		{TAG_LOOKUP_VALID,	"lookup valid",		\
4447c478bd9Sstevel@tonic-gate 			{0x6c6f6f6b, 0x75702076, 0x616c6964}},	\
4457c478bd9Sstevel@tonic-gate 		{TAG_LOOKUP_VPARENT,	"lookup valid parent",	\
4467c478bd9Sstevel@tonic-gate 			{0x6c6f6f6b, 0x766c6420, 0x7061726e}},	\
4477c478bd9Sstevel@tonic-gate 		{TAG_MKDIR,		"mkdir",		\
4487c478bd9Sstevel@tonic-gate 			{0x6d6b6469, 0x72202020, 0x20202020}},	\
4497c478bd9Sstevel@tonic-gate 		{TAG_MKNOD,		"mknod",		\
4507c478bd9Sstevel@tonic-gate 			{0x6d6b6e6f, 0x64202020, 0x20202020}},	\
4517c478bd9Sstevel@tonic-gate 		{TAG_MOUNT,		"mount",		\
4527c478bd9Sstevel@tonic-gate 			{0x6d6f756e, 0x74202020, 0x20202020}},	\
4537c478bd9Sstevel@tonic-gate 		{TAG_OPEN,		"open",			\
4547c478bd9Sstevel@tonic-gate 			{0x6f70656e, 0x20202020, 0x20202020}},	\
4557c478bd9Sstevel@tonic-gate 		{TAG_OPEN_CONFIRM,	"open confirm",		\
4567c478bd9Sstevel@tonic-gate 			{0x6f70656e, 0x5f636f6e, 0x6669726d}},	\
4577c478bd9Sstevel@tonic-gate 		{TAG_OPEN_CONFIRM_LOST,	"lost open confirm",	\
4587c478bd9Sstevel@tonic-gate 			{0x6c6f7374, 0x206f7065, 0x6e5f636f}},	\
4597c478bd9Sstevel@tonic-gate 		{TAG_OPEN_DG,		"open downgrade",	\
4607c478bd9Sstevel@tonic-gate 			{0x6f70656e, 0x20646772, 0x61646520}},	\
4617c478bd9Sstevel@tonic-gate 		{TAG_OPEN_DG_LOST,	"lost open downgrade",	\
4627c478bd9Sstevel@tonic-gate 			{0x6c737420, 0x6f70656e, 0x20646772}},	\
4637c478bd9Sstevel@tonic-gate 		{TAG_OPEN_LOST,		"lost open",		\
4647c478bd9Sstevel@tonic-gate 			{0x6c6f7374, 0x206f7065, 0x6e202020}},	\
4657c478bd9Sstevel@tonic-gate 		{TAG_OPENATTR,		"openattr",		\
4667c478bd9Sstevel@tonic-gate 			{0x6f70656e, 0x61747472, 0x20202020}},	\
4673731b537SBart Coddens 		{TAG_PATHCONF,		"pathconf",		\
4687c478bd9Sstevel@tonic-gate 			{0x70617468, 0x636f6e66, 0x20202020}},	\
4697c478bd9Sstevel@tonic-gate 		{TAG_PUTROOTFH,		"putrootfh",		\
4707c478bd9Sstevel@tonic-gate 			{0x70757472, 0x6f6f7466, 0x68202020}},	\
4717c478bd9Sstevel@tonic-gate 		{TAG_READ,		"read",			\
4727c478bd9Sstevel@tonic-gate 			{0x72656164, 0x20202020, 0x20202020}},	\
4737c478bd9Sstevel@tonic-gate 		{TAG_READAHEAD,		"readahead",		\
4747c478bd9Sstevel@tonic-gate 			{0x72656164, 0x61686561, 0x64202020}},	\
4757c478bd9Sstevel@tonic-gate 		{TAG_READDIR,		"readdir",		\
4767c478bd9Sstevel@tonic-gate 			{0x72656164, 0x64697220, 0x20202020}},	\
4777c478bd9Sstevel@tonic-gate 		{TAG_READLINK,		"readlink",		\
4787c478bd9Sstevel@tonic-gate 			{0x72656164, 0x6c696e6b, 0x20202020}},	\
4797c478bd9Sstevel@tonic-gate 		{TAG_RELOCK,		"relock",		\
4807c478bd9Sstevel@tonic-gate 			{0x72656c6f, 0x636b2020, 0x20202020}},	\
4817c478bd9Sstevel@tonic-gate 		{TAG_REMAP_LOOKUP,	"remap lookup",		\
4827c478bd9Sstevel@tonic-gate 			{0x72656d61, 0x70206c6f, 0x6f6b7570}},	\
4837c478bd9Sstevel@tonic-gate 		{TAG_REMAP_LOOKUP_AD,	"remap lookup attr dir",	\
4847c478bd9Sstevel@tonic-gate 			{0x72656d70, 0x206c6b75, 0x70206164}},	\
4857c478bd9Sstevel@tonic-gate 		{TAG_REMAP_LOOKUP_NA,	"remap lookup named attrs",	\
4867c478bd9Sstevel@tonic-gate 			{0x72656d70, 0x206c6b75, 0x70206e61}},	\
4877c478bd9Sstevel@tonic-gate 		{TAG_REMAP_MOUNT,	"remap mount",		\
4887c478bd9Sstevel@tonic-gate 			{0x72656d61, 0x70206d6f, 0x756e7420}},	\
4897c478bd9Sstevel@tonic-gate 		{TAG_RMDIR,		"rmdir",		\
4907c478bd9Sstevel@tonic-gate 			{0x726d6469, 0x72202020, 0x20202020}},	\
4917c478bd9Sstevel@tonic-gate 		{TAG_REMOVE,		"remove",		\
4927c478bd9Sstevel@tonic-gate 			{0x72656d6f, 0x76652020, 0x20202020}},	\
4937c478bd9Sstevel@tonic-gate 		{TAG_RENAME,		"rename",		\
4947c478bd9Sstevel@tonic-gate 			{0x72656e61, 0x6d652020, 0x20202020}},	\
4957c478bd9Sstevel@tonic-gate 		{TAG_RENAME_VFH,	"rename volatile fh",	\
4967c478bd9Sstevel@tonic-gate 			{0x72656e61, 0x6d652028, 0x76666829}},	\
4977c478bd9Sstevel@tonic-gate 		{TAG_RENEW,		"renew",		\
4987c478bd9Sstevel@tonic-gate 			{0x72656e65, 0x77202020, 0x20202020}},	\
4997c478bd9Sstevel@tonic-gate 		{TAG_REOPEN,		"reopen",		\
5007c478bd9Sstevel@tonic-gate 			{0x72656f70, 0x656e2020, 0x20202020}},	\
5017c478bd9Sstevel@tonic-gate 		{TAG_REOPEN_LOST,	"lost reopen",		\
5027c478bd9Sstevel@tonic-gate 			{0x6c6f7374, 0x2072656f, 0x70656e20}},	\
5037c478bd9Sstevel@tonic-gate 		{TAG_SECINFO,		"secinfo",		\
5047c478bd9Sstevel@tonic-gate 			{0x73656369, 0x6e666f20, 0x20202020}},	\
5057c478bd9Sstevel@tonic-gate 		{TAG_SETATTR,		"setattr",		\
5067c478bd9Sstevel@tonic-gate 			{0x73657461, 0x74747220, 0x20202020}},	\
5077c478bd9Sstevel@tonic-gate 		{TAG_SETCLIENTID,	"setclientid",		\
5087c478bd9Sstevel@tonic-gate 			{0x73657463, 0x6c69656e, 0x74696420}},	\
5097c478bd9Sstevel@tonic-gate 		{TAG_SETCLIENTID_CF,	"setclientid_confirm",	\
5107c478bd9Sstevel@tonic-gate 			{0x73636c6e, 0x7469645f, 0x636f6e66}},	\
5117c478bd9Sstevel@tonic-gate 		{TAG_SYMLINK,		"symlink",		\
5127c478bd9Sstevel@tonic-gate 			{0x73796d6c, 0x696e6b20, 0x20202020}},	\
5137c478bd9Sstevel@tonic-gate 		{TAG_WRITE,		"write",		\
5147c478bd9Sstevel@tonic-gate 			{0x77726974, 0x65202020, 0x20202020}}	\
5157c478bd9Sstevel@tonic-gate 	}
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate  * These flags are for differentiating the search criterian for
5197c478bd9Sstevel@tonic-gate  * find_open_owner().  The comparison is done with the open_owners's
5207c478bd9Sstevel@tonic-gate  * 'oo_just_created' flag.
5217c478bd9Sstevel@tonic-gate  */
5227c478bd9Sstevel@tonic-gate #define	NFS4_PERM_CREATED	0x0
5237c478bd9Sstevel@tonic-gate #define	NFS4_JUST_CREATED	0x1
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate /*
5267c478bd9Sstevel@tonic-gate  * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw'
5277c478bd9Sstevel@tonic-gate  * is stored upon a successful OPEN.  This is needed when the user's effective
5287c478bd9Sstevel@tonic-gate  * and real uid's don't match.  The 'oo_cred_otw' overrides the credential
5297c478bd9Sstevel@tonic-gate  * passed down by VFS for async read/write, commit, lock, and close operations.
5307c478bd9Sstevel@tonic-gate  *
5317c478bd9Sstevel@tonic-gate  * The oo_ref_count keeps track the number of active references on this
5327c478bd9Sstevel@tonic-gate  * data structure + number of nfs4_open_streams point to this structure.
5337c478bd9Sstevel@tonic-gate  *
5347c478bd9Sstevel@tonic-gate  * 'oo_valid' tells whether this stuct is about to be freed or not.
5357c478bd9Sstevel@tonic-gate  *
5367c478bd9Sstevel@tonic-gate  * 'oo_just_created' tells us whether this struct has just been created but
5377c478bd9Sstevel@tonic-gate  * not been fully finalized (that is created upon an OPEN request and
5387c478bd9Sstevel@tonic-gate  * finalized upon the OPEN success).
5397c478bd9Sstevel@tonic-gate  *
5407c478bd9Sstevel@tonic-gate  * The 'oo_seqid_inuse' is for the open seqid synchronization.  If a thread
5417c478bd9Sstevel@tonic-gate  * is currently using the open owner and it's open_seqid, then it sets the
5427c478bd9Sstevel@tonic-gate  * oo_seqid_inuse to true if it currently is not set.  If it is set then it
5437c478bd9Sstevel@tonic-gate  * does a cv_wait on the oo_cv_seqid_sync condition variable.  When the thread
5447c478bd9Sstevel@tonic-gate  * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process
5457c478bd9Sstevel@tonic-gate  * waiting on the condition variable.
5467c478bd9Sstevel@tonic-gate  *
5477c478bd9Sstevel@tonic-gate  * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW,
5487c478bd9Sstevel@tonic-gate  * and 'oo_last_good_op' is the operation that issued the last valid seqid.
5497c478bd9Sstevel@tonic-gate  *
5507c478bd9Sstevel@tonic-gate  * Lock ordering:
5517c478bd9Sstevel@tonic-gate  *	mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list)
5527c478bd9Sstevel@tonic-gate  *
5537c478bd9Sstevel@tonic-gate  *	oo_seqid_inuse > mntinfo4_t::mi_lock
5547c478bd9Sstevel@tonic-gate  *	oo_seqid_inuse > rnode4_t::r_statelock
5557c478bd9Sstevel@tonic-gate  *	oo_seqid_inuse > rnode4_t::r_statev4_lock
5567c478bd9Sstevel@tonic-gate  *	oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock
5577c478bd9Sstevel@tonic-gate  *
5587c478bd9Sstevel@tonic-gate  * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects:
5597c478bd9Sstevel@tonic-gate  *	oo_last_good_op
5607c478bd9Sstevel@tonic-gate  *	oo_last_good_seqid
5617c478bd9Sstevel@tonic-gate  *	oo_name
5627c478bd9Sstevel@tonic-gate  *	oo_seqid
5637c478bd9Sstevel@tonic-gate  *
5647c478bd9Sstevel@tonic-gate  * The 'oo_lock' protects:
5657c478bd9Sstevel@tonic-gate  *	oo_cred
5667c478bd9Sstevel@tonic-gate  *	oo_cred_otw
5677c478bd9Sstevel@tonic-gate  *	oo_foo_node
5687c478bd9Sstevel@tonic-gate  *	oo_hash_node
5697c478bd9Sstevel@tonic-gate  *	oo_just_created
5707c478bd9Sstevel@tonic-gate  *	oo_ref_count
5717c478bd9Sstevel@tonic-gate  *	oo_valid
5727c478bd9Sstevel@tonic-gate  */
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate typedef struct nfs4_open_owner {
5757c478bd9Sstevel@tonic-gate 	cred_t			*oo_cred;
5767c478bd9Sstevel@tonic-gate 	int			oo_ref_count;
5777c478bd9Sstevel@tonic-gate 	int			oo_valid;
5787c478bd9Sstevel@tonic-gate 	int			oo_just_created;
5797c478bd9Sstevel@tonic-gate 	seqid4			oo_seqid;
5807c478bd9Sstevel@tonic-gate 	seqid4			oo_last_good_seqid;
5817c478bd9Sstevel@tonic-gate 	nfs4_tag_type_t		oo_last_good_op;
5827c478bd9Sstevel@tonic-gate 	unsigned		oo_seqid_inuse:1;
5837c478bd9Sstevel@tonic-gate 	cred_t			*oo_cred_otw;
5847c478bd9Sstevel@tonic-gate 	kcondvar_t		oo_cv_seqid_sync;
5857c478bd9Sstevel@tonic-gate 	/*
5867c478bd9Sstevel@tonic-gate 	 * Fix this to always be 8 bytes
5877c478bd9Sstevel@tonic-gate 	 */
5887c478bd9Sstevel@tonic-gate 	uint64_t		oo_name;
5897c478bd9Sstevel@tonic-gate 	list_node_t		oo_hash_node;
5907c478bd9Sstevel@tonic-gate 	list_node_t		oo_foo_node;
5917c478bd9Sstevel@tonic-gate 	kmutex_t		oo_lock;
5927c478bd9Sstevel@tonic-gate } nfs4_open_owner_t;
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate /*
5957c478bd9Sstevel@tonic-gate  * Static server information.
5962f172c55SRobert Thurlow  * These fields are read-only once they are initialized; sv_lock
5972f172c55SRobert Thurlow  * should be held as writer if they are changed during mount:
5987c478bd9Sstevel@tonic-gate  *	sv_addr
5997c478bd9Sstevel@tonic-gate  *	sv_dhsec
6007c478bd9Sstevel@tonic-gate  *	sv_hostname
6017c478bd9Sstevel@tonic-gate  *	sv_hostnamelen
6027c478bd9Sstevel@tonic-gate  *	sv_knconf
6037c478bd9Sstevel@tonic-gate  *	sv_next
6047c478bd9Sstevel@tonic-gate  *	sv_origknconf
6057c478bd9Sstevel@tonic-gate  *
6067c478bd9Sstevel@tonic-gate  * These fields are protected by sv_lock:
6077c478bd9Sstevel@tonic-gate  *	sv_currsec
6087c478bd9Sstevel@tonic-gate  *	sv_fhandle
6097c478bd9Sstevel@tonic-gate  *	sv_flags
6107c478bd9Sstevel@tonic-gate  *	sv_fsid
6117c478bd9Sstevel@tonic-gate  *	sv_path
6127c478bd9Sstevel@tonic-gate  *	sv_pathlen
6137c478bd9Sstevel@tonic-gate  *	sv_pfhandle
6147c478bd9Sstevel@tonic-gate  *	sv_save_secinfo
6157c478bd9Sstevel@tonic-gate  *	sv_savesec
6167c478bd9Sstevel@tonic-gate  *	sv_secdata
6177c478bd9Sstevel@tonic-gate  *	sv_secinfo
6187c478bd9Sstevel@tonic-gate  *	sv_supp_attrs
6197c478bd9Sstevel@tonic-gate  *
6207c478bd9Sstevel@tonic-gate  * Lock ordering:
6217c478bd9Sstevel@tonic-gate  * nfs_rtable4_lock > sv_lock
6227c478bd9Sstevel@tonic-gate  * rnode4_t::r_statelock > sv_lock
6237c478bd9Sstevel@tonic-gate  */
6247c478bd9Sstevel@tonic-gate typedef struct servinfo4 {
6257c478bd9Sstevel@tonic-gate 	struct knetconfig *sv_knconf;   /* bound TLI fd */
6267c478bd9Sstevel@tonic-gate 	struct knetconfig *sv_origknconf;	/* For RDMA save orig knconf */
6277c478bd9Sstevel@tonic-gate 	struct netbuf	   sv_addr;	/* server's address */
6287c478bd9Sstevel@tonic-gate 	nfs4_fhandle_t	   sv_fhandle;	/* this server's filehandle */
6297c478bd9Sstevel@tonic-gate 	nfs4_fhandle_t	   sv_pfhandle; /* parent dir filehandle */
6307c478bd9Sstevel@tonic-gate 	int		   sv_pathlen;	/* Length of server path */
6317c478bd9Sstevel@tonic-gate 	char		  *sv_path;	/* Path name on server */
6327c478bd9Sstevel@tonic-gate 	uint32_t	   sv_flags;	/* flags for this server */
6337c478bd9Sstevel@tonic-gate 	sec_data_t	  *sv_secdata;	/* client initiated security data */
6347c478bd9Sstevel@tonic-gate 	sv_secinfo_t	  *sv_secinfo;	/* server security information */
6357c478bd9Sstevel@tonic-gate 	sec_data_t	  *sv_currsec;	/* security data currently used; */
6367c478bd9Sstevel@tonic-gate 					/* points to one of the sec_data */
6377c478bd9Sstevel@tonic-gate 					/* entries in sv_secinfo */
6387c478bd9Sstevel@tonic-gate 	sv_secinfo_t	  *sv_save_secinfo; /* saved secinfo */
6397c478bd9Sstevel@tonic-gate 	sec_data_t	  *sv_savesec;	/* saved security data */
6407c478bd9Sstevel@tonic-gate 	sec_data_t	  *sv_dhsec;    /* AUTH_DH data from the user land */
6417c478bd9Sstevel@tonic-gate 	char		  *sv_hostname;	/* server's hostname */
6427c478bd9Sstevel@tonic-gate 	int		   sv_hostnamelen;  /* server's hostname length */
6437c478bd9Sstevel@tonic-gate 	fattr4_fsid		sv_fsid;    /* fsid of shared obj	*/
6447c478bd9Sstevel@tonic-gate 	fattr4_supported_attrs	sv_supp_attrs;
6457c478bd9Sstevel@tonic-gate 	struct servinfo4  *sv_next;	/* next in list */
6467c478bd9Sstevel@tonic-gate 	nfs_rwlock_t	   sv_lock;
6477c478bd9Sstevel@tonic-gate } servinfo4_t;
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate /* sv_flags fields */
6507c478bd9Sstevel@tonic-gate #define	SV4_TRYSECINFO		0x001	/* try secinfo data from the server */
6517c478bd9Sstevel@tonic-gate #define	SV4_TRYSECDEFAULT	0x002	/* try a default flavor */
6527c478bd9Sstevel@tonic-gate #define	SV4_NOTINUSE		0x004	/* servinfo4_t had fatal errors */
6537c478bd9Sstevel@tonic-gate #define	SV4_ROOT_STALE		0x008	/* root vnode got ESTALE */
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate /*
6567c478bd9Sstevel@tonic-gate  * Lock call types.  See nfs4frlock().
6577c478bd9Sstevel@tonic-gate  */
6587c478bd9Sstevel@tonic-gate typedef enum nfs4_lock_call_type {
6597c478bd9Sstevel@tonic-gate 	NFS4_LCK_CTYPE_NORM,
6607c478bd9Sstevel@tonic-gate 	NFS4_LCK_CTYPE_RECLAIM,
6617c478bd9Sstevel@tonic-gate 	NFS4_LCK_CTYPE_RESEND,
6627c478bd9Sstevel@tonic-gate 	NFS4_LCK_CTYPE_REINSTATE
6637c478bd9Sstevel@tonic-gate } nfs4_lock_call_type_t;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate /*
6667c478bd9Sstevel@tonic-gate  * This structure holds the information for a lost open/close/open downgrade/
6677c478bd9Sstevel@tonic-gate  * lock/locku request.  It is also used for requests that are queued up so
6687c478bd9Sstevel@tonic-gate  * that the recovery thread can release server state after a forced
6697c478bd9Sstevel@tonic-gate  * unmount.
6707c478bd9Sstevel@tonic-gate  * "lr_op" is 0 if the struct is uninitialized.  Otherwise, it is set to
6717c478bd9Sstevel@tonic-gate  * the proper OP_* nfs_opnum4 number.  The other fields contain information
6727c478bd9Sstevel@tonic-gate  * to reconstruct the call.
6737c478bd9Sstevel@tonic-gate  *
6747c478bd9Sstevel@tonic-gate  * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the
6757c478bd9Sstevel@tonic-gate  * parent directroy without relying on vtodv (since we may not have a vp
6767c478bd9Sstevel@tonic-gate  * for the file we wish to create).
6777c478bd9Sstevel@tonic-gate  *
6787c478bd9Sstevel@tonic-gate  * lr_putfirst means that the request should go to the front of the resend
6797c478bd9Sstevel@tonic-gate  * queue, rather than the end.
6807c478bd9Sstevel@tonic-gate  */
6817c478bd9Sstevel@tonic-gate typedef struct nfs4_lost_rqst {
6827c478bd9Sstevel@tonic-gate 	list_node_t			lr_node;
6837c478bd9Sstevel@tonic-gate 	nfs_opnum4			lr_op;
6847c478bd9Sstevel@tonic-gate 	vnode_t				*lr_vp;
6857c478bd9Sstevel@tonic-gate 	vnode_t				*lr_dvp;
6867c478bd9Sstevel@tonic-gate 	nfs4_open_owner_t		*lr_oop;
6877c478bd9Sstevel@tonic-gate 	struct nfs4_open_stream		*lr_osp;
6887c478bd9Sstevel@tonic-gate 	struct nfs4_lock_owner		*lr_lop;
6897c478bd9Sstevel@tonic-gate 	cred_t				*lr_cr;
6907c478bd9Sstevel@tonic-gate 	flock64_t			*lr_flk;
6917c478bd9Sstevel@tonic-gate 	bool_t				lr_putfirst;
6927c478bd9Sstevel@tonic-gate 	union {
6937c478bd9Sstevel@tonic-gate 		struct {
6947c478bd9Sstevel@tonic-gate 			nfs4_lock_call_type_t lru_ctype;
6957c478bd9Sstevel@tonic-gate 			nfs_lock_type4	lru_locktype;
6967c478bd9Sstevel@tonic-gate 		} lru_lockargs;		/* LOCK, LOCKU */
6977c478bd9Sstevel@tonic-gate 		struct {
6987c478bd9Sstevel@tonic-gate 			uint32_t		lru_oaccess;
6997c478bd9Sstevel@tonic-gate 			uint32_t		lru_odeny;
7007c478bd9Sstevel@tonic-gate 			enum open_claim_type4	lru_oclaim;
7017c478bd9Sstevel@tonic-gate 			stateid4		lru_ostateid; /* reopen only */
7027c478bd9Sstevel@tonic-gate 			component4		lru_ofile;
7037c478bd9Sstevel@tonic-gate 		} lru_open_args;
7047c478bd9Sstevel@tonic-gate 		struct {
7057c478bd9Sstevel@tonic-gate 			uint32_t	lru_dg_access;
7067c478bd9Sstevel@tonic-gate 			uint32_t	lru_dg_deny;
7077c478bd9Sstevel@tonic-gate 		} lru_open_dg_args;
7087c478bd9Sstevel@tonic-gate 	} nfs4_lr_u;
7097c478bd9Sstevel@tonic-gate } nfs4_lost_rqst_t;
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate #define	lr_oacc		nfs4_lr_u.lru_open_args.lru_oaccess
7127c478bd9Sstevel@tonic-gate #define	lr_odeny	nfs4_lr_u.lru_open_args.lru_odeny
7137c478bd9Sstevel@tonic-gate #define	lr_oclaim	nfs4_lr_u.lru_open_args.lru_oclaim
7147c478bd9Sstevel@tonic-gate #define	lr_ostateid	nfs4_lr_u.lru_open_args.lru_ostateid
7157c478bd9Sstevel@tonic-gate #define	lr_ofile	nfs4_lr_u.lru_open_args.lru_ofile
7167c478bd9Sstevel@tonic-gate #define	lr_dg_acc	nfs4_lr_u.lru_open_dg_args.lru_dg_access
7177c478bd9Sstevel@tonic-gate #define	lr_dg_deny	nfs4_lr_u.lru_open_dg_args.lru_dg_deny
7187c478bd9Sstevel@tonic-gate #define	lr_ctype	nfs4_lr_u.lru_lockargs.lru_ctype
7197c478bd9Sstevel@tonic-gate #define	lr_locktype	nfs4_lr_u.lru_lockargs.lru_locktype
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate /*
7227c478bd9Sstevel@tonic-gate  * Recovery actions.  Some actions can imply further recovery using a
7237c478bd9Sstevel@tonic-gate  * different recovery action (e.g., recovering the clientid leads to
7247c478bd9Sstevel@tonic-gate  * recovering open files and locks).
7257c478bd9Sstevel@tonic-gate  */
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate typedef enum {
7287c478bd9Sstevel@tonic-gate 	NR_UNUSED,
7297c478bd9Sstevel@tonic-gate 	NR_CLIENTID,
7307c478bd9Sstevel@tonic-gate 	NR_OPENFILES,
7317c478bd9Sstevel@tonic-gate 	NR_FHEXPIRED,
7327c478bd9Sstevel@tonic-gate 	NR_FAILOVER,
7337c478bd9Sstevel@tonic-gate 	NR_WRONGSEC,
7347c478bd9Sstevel@tonic-gate 	NR_EXPIRED,
7357c478bd9Sstevel@tonic-gate 	NR_BAD_STATEID,
7367c478bd9Sstevel@tonic-gate 	NR_BADHANDLE,
7377c478bd9Sstevel@tonic-gate 	NR_BAD_SEQID,
7387c478bd9Sstevel@tonic-gate 	NR_OLDSTATEID,
7397c478bd9Sstevel@tonic-gate 	NR_GRACE,
7407c478bd9Sstevel@tonic-gate 	NR_DELAY,
7417c478bd9Sstevel@tonic-gate 	NR_LOST_LOCK,
7427c478bd9Sstevel@tonic-gate 	NR_LOST_STATE_RQST,
7432f172c55SRobert Thurlow 	NR_STALE,
7442f172c55SRobert Thurlow 	NR_MOVED
7457c478bd9Sstevel@tonic-gate } nfs4_recov_t;
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate /*
7487c478bd9Sstevel@tonic-gate  * Administrative and debug message framework.
7497c478bd9Sstevel@tonic-gate  */
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate #define	NFS4_MSG_MAX	100
7527c478bd9Sstevel@tonic-gate extern int nfs4_msg_max;
7537c478bd9Sstevel@tonic-gate 
7542f172c55SRobert Thurlow #define	NFS4_REFERRAL_LOOP_MAX	20
7552f172c55SRobert Thurlow 
7567c478bd9Sstevel@tonic-gate typedef enum {
7577c478bd9Sstevel@tonic-gate 	RE_BAD_SEQID,
7587c478bd9Sstevel@tonic-gate 	RE_BADHANDLE,
7597c478bd9Sstevel@tonic-gate 	RE_CLIENTID,
7607c478bd9Sstevel@tonic-gate 	RE_DEAD_FILE,
7617c478bd9Sstevel@tonic-gate 	RE_END,
7627c478bd9Sstevel@tonic-gate 	RE_FAIL_RELOCK,
7637c478bd9Sstevel@tonic-gate 	RE_FAIL_REMAP_LEN,
7647c478bd9Sstevel@tonic-gate 	RE_FAIL_REMAP_OP,
7657c478bd9Sstevel@tonic-gate 	RE_FAILOVER,
7667c478bd9Sstevel@tonic-gate 	RE_FILE_DIFF,
7677c478bd9Sstevel@tonic-gate 	RE_LOST_STATE,
7687c478bd9Sstevel@tonic-gate 	RE_OPENS_CHANGED,
7697c478bd9Sstevel@tonic-gate 	RE_SIGLOST,
7707c478bd9Sstevel@tonic-gate 	RE_SIGLOST_NO_DUMP,
7717c478bd9Sstevel@tonic-gate 	RE_START,
7727c478bd9Sstevel@tonic-gate 	RE_UNEXPECTED_ACTION,
7737c478bd9Sstevel@tonic-gate 	RE_UNEXPECTED_ERRNO,
7747c478bd9Sstevel@tonic-gate 	RE_UNEXPECTED_STATUS,
7757c478bd9Sstevel@tonic-gate 	RE_WRONGSEC,
7762f172c55SRobert Thurlow 	RE_LOST_STATE_BAD_OP,
7772f172c55SRobert Thurlow 	RE_REFERRAL
7787c478bd9Sstevel@tonic-gate } nfs4_event_type_t;
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate typedef enum {
7817c478bd9Sstevel@tonic-gate 	RFS_NO_INSPECT,
7827c478bd9Sstevel@tonic-gate 	RFS_INSPECT
7837c478bd9Sstevel@tonic-gate } nfs4_fact_status_t;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate typedef enum {
7867c478bd9Sstevel@tonic-gate 	RF_BADOWNER,
7877c478bd9Sstevel@tonic-gate 	RF_ERR,
7887c478bd9Sstevel@tonic-gate 	RF_RENEW_EXPIRED,
7897c478bd9Sstevel@tonic-gate 	RF_SRV_NOT_RESPOND,
7907c478bd9Sstevel@tonic-gate 	RF_SRV_OK,
7917c478bd9Sstevel@tonic-gate 	RF_SRVS_NOT_RESPOND,
7927c478bd9Sstevel@tonic-gate 	RF_SRVS_OK,
793e280ed37SDai Ngo 	RF_DELMAP_CB_ERR,
794e280ed37SDai Ngo 	RF_SENDQ_FULL
7957c478bd9Sstevel@tonic-gate } nfs4_fact_type_t;
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate typedef enum {
7987c478bd9Sstevel@tonic-gate 	NFS4_MS_DUMP,
7997c478bd9Sstevel@tonic-gate 	NFS4_MS_NO_DUMP
8007c478bd9Sstevel@tonic-gate } nfs4_msg_status_t;
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate typedef struct nfs4_rfact {
8037c478bd9Sstevel@tonic-gate 	nfs4_fact_type_t	rf_type;
8047c478bd9Sstevel@tonic-gate 	nfs4_fact_status_t	rf_status;
8057c478bd9Sstevel@tonic-gate 	bool_t			rf_reboot;
8067c478bd9Sstevel@tonic-gate 	nfs4_recov_t		rf_action;
8077c478bd9Sstevel@tonic-gate 	nfs_opnum4		rf_op;
8087c478bd9Sstevel@tonic-gate 	nfsstat4		rf_stat4;
8097c478bd9Sstevel@tonic-gate 	timespec_t		rf_time;
8107c478bd9Sstevel@tonic-gate 	int			rf_error;
8117c478bd9Sstevel@tonic-gate 	struct rnode4		*rf_rp1;
8127c478bd9Sstevel@tonic-gate 	char			*rf_char1;
8137c478bd9Sstevel@tonic-gate } nfs4_rfact_t;
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate typedef struct nfs4_revent {
8167c478bd9Sstevel@tonic-gate 	nfs4_event_type_t	re_type;
8177c478bd9Sstevel@tonic-gate 	nfsstat4		re_stat4;
8187c478bd9Sstevel@tonic-gate 	uint_t			re_uint;
8197c478bd9Sstevel@tonic-gate 	pid_t			re_pid;
8207c478bd9Sstevel@tonic-gate 	struct mntinfo4		*re_mi;
8217c478bd9Sstevel@tonic-gate 	struct rnode4		*re_rp1;
8227c478bd9Sstevel@tonic-gate 	struct rnode4		*re_rp2;
8237c478bd9Sstevel@tonic-gate 	char			*re_char1;
8247c478bd9Sstevel@tonic-gate 	char			*re_char2;
8257c478bd9Sstevel@tonic-gate 	nfs4_tag_type_t		re_tag1;
8267c478bd9Sstevel@tonic-gate 	nfs4_tag_type_t		re_tag2;
8277c478bd9Sstevel@tonic-gate 	seqid4			re_seqid1;
8287c478bd9Sstevel@tonic-gate 	seqid4			re_seqid2;
8297c478bd9Sstevel@tonic-gate } nfs4_revent_t;
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate typedef enum {
8327c478bd9Sstevel@tonic-gate 	RM_EVENT,
8337c478bd9Sstevel@tonic-gate 	RM_FACT
8347c478bd9Sstevel@tonic-gate } nfs4_msg_type_t;
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate typedef struct nfs4_debug_msg {
8377c478bd9Sstevel@tonic-gate 	timespec_t		msg_time;
8387c478bd9Sstevel@tonic-gate 	nfs4_msg_type_t		msg_type;
8397c478bd9Sstevel@tonic-gate 	char			*msg_srv;
8407c478bd9Sstevel@tonic-gate 	char			*msg_mntpt;
8417c478bd9Sstevel@tonic-gate 	union {
8427c478bd9Sstevel@tonic-gate 		nfs4_rfact_t	msg_fact;
8437c478bd9Sstevel@tonic-gate 		nfs4_revent_t	msg_event;
8447c478bd9Sstevel@tonic-gate 	} rmsg_u;
8457c478bd9Sstevel@tonic-gate 	nfs4_msg_status_t	msg_status;
8467c478bd9Sstevel@tonic-gate 	list_node_t		msg_node;
8477c478bd9Sstevel@tonic-gate } nfs4_debug_msg_t;
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate /*
8507c478bd9Sstevel@tonic-gate  * NFS private data per mounted file system
8517c478bd9Sstevel@tonic-gate  *	The mi_lock mutex protects the following fields:
8527c478bd9Sstevel@tonic-gate  *		mi_flags
8537c478bd9Sstevel@tonic-gate  *		mi_in_recovery
8547c478bd9Sstevel@tonic-gate  *		mi_recovflags
8557c478bd9Sstevel@tonic-gate  *		mi_recovthread
8567c478bd9Sstevel@tonic-gate  *		mi_error
8577c478bd9Sstevel@tonic-gate  *		mi_printed
8587c478bd9Sstevel@tonic-gate  *		mi_down
8597c478bd9Sstevel@tonic-gate  *		mi_stsize
8607c478bd9Sstevel@tonic-gate  *		mi_curread
8617c478bd9Sstevel@tonic-gate  *		mi_curwrite
8627c478bd9Sstevel@tonic-gate  *		mi_timers
8637c478bd9Sstevel@tonic-gate  *		mi_curr_serv
8647c478bd9Sstevel@tonic-gate  *		mi_klmconfig
8657c478bd9Sstevel@tonic-gate  *		mi_oo_list
8667c478bd9Sstevel@tonic-gate  *		mi_foo_list
8677c478bd9Sstevel@tonic-gate  *		mi_foo_num
8687c478bd9Sstevel@tonic-gate  *		mi_foo_max
8697c478bd9Sstevel@tonic-gate  *		mi_lost_state
8707c478bd9Sstevel@tonic-gate  *		mi_bseqid_list
871b9238976Sth  *		mi_ephemeral
872b9238976Sth  *		mi_ephemeral_tree
8737c478bd9Sstevel@tonic-gate  *
8747c478bd9Sstevel@tonic-gate  *	Normally the netconfig information for the mount comes from
8757c478bd9Sstevel@tonic-gate  *	mi_curr_serv and mi_klmconfig is NULL.  If NLM calls need to use a
8767c478bd9Sstevel@tonic-gate  *	different transport, mi_klmconfig contains the necessary netconfig
8777c478bd9Sstevel@tonic-gate  *	information.
8787c478bd9Sstevel@tonic-gate  *
8797c478bd9Sstevel@tonic-gate  *	The mi_async_lock mutex protects the following fields:
8807c478bd9Sstevel@tonic-gate  *		mi_async_reqs
8817c478bd9Sstevel@tonic-gate  *		mi_async_req_count
8823b895386SPavel Filipensky  *		mi_async_tail
8830776f5e6SVallish Vaidyeshwara  *		mi_async_curr[NFS4_MAX_ASYNC_QUEUES]
8847c478bd9Sstevel@tonic-gate  *		mi_async_clusters
8857c478bd9Sstevel@tonic-gate  *		mi_async_init_clusters
8860776f5e6SVallish Vaidyeshwara  *		mi_threads[NFS4_MAX_ASYNC_QUEUES]
8877c478bd9Sstevel@tonic-gate  *		mi_inactive_thread
8887c478bd9Sstevel@tonic-gate  *		mi_manager_thread
8897c478bd9Sstevel@tonic-gate  *
8907c478bd9Sstevel@tonic-gate  *	The nfs4_server_t::s_lock protects the following fields:
8917c478bd9Sstevel@tonic-gate  *		mi_clientid
8927c478bd9Sstevel@tonic-gate  *		mi_clientid_next
8937c478bd9Sstevel@tonic-gate  *		mi_clientid_prev
8947c478bd9Sstevel@tonic-gate  *		mi_open_files
8957c478bd9Sstevel@tonic-gate  *
896a092743bSek  *	The mntinfo4_t::mi_recovlock protects the following fields:
897a092743bSek  *		mi_srvsettime
8983b895386SPavel Filipensky  *		mi_srvset_cnt
8993b895386SPavel Filipensky  *		mi_srv
9003b895386SPavel Filipensky  *
9013b895386SPavel Filipensky  * Changing mi_srv from one nfs4_server_t to a different one requires
9023b895386SPavel Filipensky  * holding the mi_recovlock as RW_WRITER.
9033b895386SPavel Filipensky  * Exception: setting mi_srv the first time in mount/mountroot is done
9043b895386SPavel Filipensky  * holding the mi_recovlock as RW_READER.
905a092743bSek  *
9067c478bd9Sstevel@tonic-gate  *	Locking order:
9077c478bd9Sstevel@tonic-gate  *	  mi4_globals::mig_lock > mi_async_lock
9087c478bd9Sstevel@tonic-gate  *	  mi_async_lock > nfs4_server_t::s_lock > mi_lock
9097c478bd9Sstevel@tonic-gate  *	  mi_recovlock > mi_rename_lock > nfs_rtable4_lock
9107c478bd9Sstevel@tonic-gate  *	  nfs4_server_t::s_recovlock > mi_recovlock
9117c478bd9Sstevel@tonic-gate  *	  rnode4_t::r_rwlock > mi_rename_lock
9127c478bd9Sstevel@tonic-gate  *	  nfs_rtable4_lock > mi_lock
9137c478bd9Sstevel@tonic-gate  *	  nfs4_server_t::s_lock > mi_msg_list_lock
914a092743bSek  *	  mi_recovlock > nfs4_server_t::s_lock
915a092743bSek  *	  mi_recovlock > nfs4_server_lst_lock
9167c478bd9Sstevel@tonic-gate  *
9177c478bd9Sstevel@tonic-gate  * The 'mi_oo_list' represents the hash buckets that contain the
9187c478bd9Sstevel@tonic-gate  * nfs4_open_owenrs for this particular mntinfo4.
9197c478bd9Sstevel@tonic-gate  *
9207c478bd9Sstevel@tonic-gate  * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4.
9217c478bd9Sstevel@tonic-gate  * 'mi_foo_num' is the current number of freed open owners on the list,
9227c478bd9Sstevel@tonic-gate  * 'mi_foo_max' is the maximum number of freed open owners that are allowable
9237c478bd9Sstevel@tonic-gate  * on the list.
9247c478bd9Sstevel@tonic-gate  *
9257c478bd9Sstevel@tonic-gate  * mi_rootfh and mi_srvparentfh are read-only once created, but that just
9267c478bd9Sstevel@tonic-gate  * refers to the pointer.  The contents must be updated to keep in sync
9277c478bd9Sstevel@tonic-gate  * with mi_curr_serv.
9287c478bd9Sstevel@tonic-gate  *
9297c478bd9Sstevel@tonic-gate  * The mi_msg_list_lock protects against adding/deleting entries to the
9307c478bd9Sstevel@tonic-gate  * mi_msg_list, and also the updating/retrieving of mi_lease_period;
9317c478bd9Sstevel@tonic-gate  *
9327c478bd9Sstevel@tonic-gate  * 'mi_zone' is initialized at structure creation time, and never
9337c478bd9Sstevel@tonic-gate  * changes; it may be read without a lock.
9347c478bd9Sstevel@tonic-gate  *
9357c478bd9Sstevel@tonic-gate  * mi_zone_node is linkage into the mi4_globals.mig_list, and is
9367c478bd9Sstevel@tonic-gate  * protected by mi4_globals.mig_list_lock.
937b9238976Sth  *
938b9238976Sth  * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an
939b9238976Sth  * ephemeral structure for this ephemeral mount point. It can not be
940b9238976Sth  * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral
941b9238976Sth  * tree.
942b9238976Sth  *
943b9238976Sth  * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has
944b9238976Sth  * to be NULL. If mi_ephemeral_tree is non-NULL, then this node
945b9238976Sth  * is the enclosing mntinfo4 for the ephemeral tree.
9467c478bd9Sstevel@tonic-gate  */
9477c478bd9Sstevel@tonic-gate struct zone;
948b9238976Sth struct nfs4_ephemeral;
949b9238976Sth struct nfs4_ephemeral_tree;
9503b895386SPavel Filipensky struct nfs4_server;
9517c478bd9Sstevel@tonic-gate typedef struct mntinfo4 {
9527c478bd9Sstevel@tonic-gate 	kmutex_t	mi_lock;	/* protects mntinfo4 fields */
9537c478bd9Sstevel@tonic-gate 	struct servinfo4 *mi_servers;   /* server list */
9547c478bd9Sstevel@tonic-gate 	struct servinfo4 *mi_curr_serv; /* current server */
9557c478bd9Sstevel@tonic-gate 	struct nfs4_sharedfh *mi_rootfh; /* root filehandle */
9567c478bd9Sstevel@tonic-gate 	struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */
9577c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_failover_cv;	/* failover synchronization */
9587c478bd9Sstevel@tonic-gate 	struct vfs	*mi_vfsp;	/* back pointer to vfs */
9597c478bd9Sstevel@tonic-gate 	enum vtype	mi_type;	/* file type of the root vnode */
9607c478bd9Sstevel@tonic-gate 	uint_t		mi_flags;	/* see below */
9617c478bd9Sstevel@tonic-gate 	uint_t		mi_recovflags;	/* if recovery active; see below */
9627c478bd9Sstevel@tonic-gate 	kthread_t	*mi_recovthread; /* active recov thread or NULL */
9637c478bd9Sstevel@tonic-gate 	uint_t		mi_error;	/* only set/valid when MI4_RECOV_FAIL */
9647c478bd9Sstevel@tonic-gate 					/* is set in mi_flags */
9657c478bd9Sstevel@tonic-gate 	int		mi_tsize;	/* transfer size (bytes) */
9667c478bd9Sstevel@tonic-gate 					/* really read size */
9677c478bd9Sstevel@tonic-gate 	int		mi_stsize;	/* server's max transfer size (bytes) */
9687c478bd9Sstevel@tonic-gate 					/* really write size */
9697c478bd9Sstevel@tonic-gate 	int		mi_timeo;	/* inital timeout in 10th sec */
9707c478bd9Sstevel@tonic-gate 	int		mi_retrans;	/* times to retry request */
9717c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acregmin;	/* min time to hold cached file attr */
9727c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acregmax;	/* max time to hold cached file attr */
9737c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acdirmin;	/* min time to hold cached dir attr */
9747c478bd9Sstevel@tonic-gate 	hrtime_t	mi_acdirmax;	/* max time to hold cached dir attr */
9757c478bd9Sstevel@tonic-gate 	len_t		mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */
9767c478bd9Sstevel@tonic-gate 	int		mi_curread;	/* current read size */
9777c478bd9Sstevel@tonic-gate 	int		mi_curwrite;	/* current write size */
97850a83466Sjwahlig 	uint_t 		mi_count; 	/* ref count */
9797c478bd9Sstevel@tonic-gate 	/*
9800776f5e6SVallish Vaidyeshwara 	 * Async I/O management
9810776f5e6SVallish Vaidyeshwara 	 * We have 2 pools of threads working on async I/O:
9820776f5e6SVallish Vaidyeshwara 	 * 	(1) Threads which work on all async queues. Default number of
9830776f5e6SVallish Vaidyeshwara 	 *	threads in this queue is 8. Threads in this pool work on async
9840776f5e6SVallish Vaidyeshwara 	 *	queue pointed by mi_async_curr[NFS4_ASYNC_QUEUE]. Number of
9850776f5e6SVallish Vaidyeshwara 	 *	active threads in this pool is tracked by
9860776f5e6SVallish Vaidyeshwara 	 *	mi_threads[NFS4_ASYNC_QUEUE].
9870776f5e6SVallish Vaidyeshwara 	 * 	(ii)Threads which work only on page op async queues.
9880776f5e6SVallish Vaidyeshwara 	 *	Page ops queue comprises of NFS4_PUTAPAGE, NFS4_PAGEIO &
9890776f5e6SVallish Vaidyeshwara 	 *	NFS4_COMMIT. Default number of threads in this queue is 2
9900776f5e6SVallish Vaidyeshwara 	 *	(NUM_ASYNC_PGOPS_THREADS). Threads in this pool work on async
9910776f5e6SVallish Vaidyeshwara 	 *	queue pointed by mi_async_curr[NFS4_ASYNC_PGOPS_QUEUE]. Number
9920776f5e6SVallish Vaidyeshwara 	 *	of active threads in this pool is tracked by
9930776f5e6SVallish Vaidyeshwara 	 *	mi_threads[NFS4_ASYNC_PGOPS_QUEUE].
9940776f5e6SVallish Vaidyeshwara 	 *
9950776f5e6SVallish Vaidyeshwara 	 * In addition to above two pools, there is always one thread that
9960776f5e6SVallish Vaidyeshwara 	 * handles over-the-wire requests for VOP_INACTIVE.
9977c478bd9Sstevel@tonic-gate 	 */
9987c478bd9Sstevel@tonic-gate 	struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES];
9997c478bd9Sstevel@tonic-gate 	struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES];
10000776f5e6SVallish Vaidyeshwara 	struct nfs4_async_reqs **mi_async_curr[NFS4_MAX_ASYNC_QUEUES];
10010776f5e6SVallish Vaidyeshwara 						/* current async queue */
10027c478bd9Sstevel@tonic-gate 	uint_t		mi_async_clusters[NFS4_ASYNC_TYPES];
10037c478bd9Sstevel@tonic-gate 	uint_t		mi_async_init_clusters;
10047c478bd9Sstevel@tonic-gate 	uint_t		mi_async_req_count; /* # outstanding work requests */
10057c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_reqs_cv; /* signaled when there's work */
10060776f5e6SVallish Vaidyeshwara 	ushort_t	mi_threads[NFS4_MAX_ASYNC_QUEUES];
10070776f5e6SVallish Vaidyeshwara 					/* number of active async threads */
10087c478bd9Sstevel@tonic-gate 	ushort_t	mi_max_threads;	/* max number of async threads */
10097c478bd9Sstevel@tonic-gate 	kthread_t	*mi_manager_thread; /* async manager thread id */
10107c478bd9Sstevel@tonic-gate 	kthread_t	*mi_inactive_thread; /* inactive thread id */
10117c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_inact_req_cv; /* notify VOP_INACTIVE thread */
10120776f5e6SVallish Vaidyeshwara 	kcondvar_t	mi_async_work_cv[NFS4_MAX_ASYNC_QUEUES];
10130776f5e6SVallish Vaidyeshwara 					/* tell workers to work */
10147c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_async_cv;	/* all pool threads exited */
10157c478bd9Sstevel@tonic-gate 	kmutex_t	mi_async_lock;
10167c478bd9Sstevel@tonic-gate 	/*
10177c478bd9Sstevel@tonic-gate 	 * Other stuff
10187c478bd9Sstevel@tonic-gate 	 */
10197c478bd9Sstevel@tonic-gate 	struct pathcnf	*mi_pathconf;	/* static pathconf kludge */
10207c478bd9Sstevel@tonic-gate 	rpcprog_t	mi_prog;	/* RPC program number */
10217c478bd9Sstevel@tonic-gate 	rpcvers_t	mi_vers;	/* RPC program version number */
10227c478bd9Sstevel@tonic-gate 	char		**mi_rfsnames;	/* mapping to proc names */
10237c478bd9Sstevel@tonic-gate 	kstat_named_t	*mi_reqs;	/* count of requests */
10247c478bd9Sstevel@tonic-gate 	clock_t		mi_printftime;	/* last error printf time */
10257c478bd9Sstevel@tonic-gate 	nfs_rwlock_t	mi_recovlock;	/* separate ops from recovery (v4) */
10267c478bd9Sstevel@tonic-gate 	time_t		mi_grace_wait;	/* non-zero represents time to wait */
10273b895386SPavel Filipensky 	/* when we switched nfs4_server_t - only for observability purposes */
10283b895386SPavel Filipensky 	time_t		mi_srvsettime;
10297c478bd9Sstevel@tonic-gate 	nfs_rwlock_t	mi_rename_lock;	/* atomic volfh rename  */
10307c478bd9Sstevel@tonic-gate 	struct nfs4_fname *mi_fname;	/* root fname */
10317c478bd9Sstevel@tonic-gate 	list_t		mi_lost_state;	/* resend list */
10327c478bd9Sstevel@tonic-gate 	list_t		mi_bseqid_list; /* bad seqid list */
10337c478bd9Sstevel@tonic-gate 	/*
10347c478bd9Sstevel@tonic-gate 	 * Client Side Failover stats
10357c478bd9Sstevel@tonic-gate 	 */
10367c478bd9Sstevel@tonic-gate 	uint_t		mi_noresponse;	/* server not responding count */
10377c478bd9Sstevel@tonic-gate 	uint_t		mi_failover; 	/* failover to new server count */
10387c478bd9Sstevel@tonic-gate 	uint_t		mi_remap;	/* remap to new server count */
10397c478bd9Sstevel@tonic-gate 	/*
10407c478bd9Sstevel@tonic-gate 	 * Kstat statistics
10417c478bd9Sstevel@tonic-gate 	 */
10427c478bd9Sstevel@tonic-gate 	struct kstat	*mi_io_kstats;
10437c478bd9Sstevel@tonic-gate 	struct kstat	*mi_ro_kstats;
10447c478bd9Sstevel@tonic-gate 	kstat_t		*mi_recov_ksp;	/* ptr to the recovery kstat */
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 	/*
10477c478bd9Sstevel@tonic-gate 	 * Volatile fh flags (nfsv4)
10487c478bd9Sstevel@tonic-gate 	 */
10497c478bd9Sstevel@tonic-gate 	uint32_t	mi_fh_expire_type;
10507c478bd9Sstevel@tonic-gate 	/*
10517c478bd9Sstevel@tonic-gate 	 * Lease Management
10527c478bd9Sstevel@tonic-gate 	 */
10537c478bd9Sstevel@tonic-gate 	struct mntinfo4	*mi_clientid_next;
10547c478bd9Sstevel@tonic-gate 	struct mntinfo4	*mi_clientid_prev;
10557c478bd9Sstevel@tonic-gate 	clientid4	mi_clientid; /* redundant info found in nfs4_server */
10567c478bd9Sstevel@tonic-gate 	int		mi_open_files;	/* count of open files */
10577c478bd9Sstevel@tonic-gate 	int		mi_in_recovery;	/* count of recovery instances */
10587c478bd9Sstevel@tonic-gate 	kcondvar_t	mi_cv_in_recov; /* cv for recovery threads */
10597c478bd9Sstevel@tonic-gate 	/*
10607c478bd9Sstevel@tonic-gate 	 * Open owner stuff.
10617c478bd9Sstevel@tonic-gate 	 */
10627c478bd9Sstevel@tonic-gate 	struct nfs4_oo_hash_bucket	mi_oo_list[NFS4_NUM_OO_BUCKETS];
10637c478bd9Sstevel@tonic-gate 	list_t				mi_foo_list;
10647c478bd9Sstevel@tonic-gate 	int				mi_foo_num;
10657c478bd9Sstevel@tonic-gate 	int				mi_foo_max;
10667c478bd9Sstevel@tonic-gate 	/*
10677c478bd9Sstevel@tonic-gate 	 * Shared filehandle pool.
10687c478bd9Sstevel@tonic-gate 	 */
10697c478bd9Sstevel@tonic-gate 	nfs_rwlock_t			mi_fh_lock;
10707c478bd9Sstevel@tonic-gate 	avl_tree_t			mi_filehandles;
10717c478bd9Sstevel@tonic-gate 
10727c478bd9Sstevel@tonic-gate 	/*
10737c478bd9Sstevel@tonic-gate 	 * Debug message queue.
10747c478bd9Sstevel@tonic-gate 	 */
10757c478bd9Sstevel@tonic-gate 	list_t			mi_msg_list;
10767c478bd9Sstevel@tonic-gate 	int			mi_msg_count;
10777c478bd9Sstevel@tonic-gate 	time_t			mi_lease_period;
10787c478bd9Sstevel@tonic-gate 					/*
10797c478bd9Sstevel@tonic-gate 					 * not guaranteed to be accurate.
10807c478bd9Sstevel@tonic-gate 					 * only should be used by debug queue.
10817c478bd9Sstevel@tonic-gate 					 */
10827c478bd9Sstevel@tonic-gate 	kmutex_t		mi_msg_list_lock;
10837c478bd9Sstevel@tonic-gate 	/*
10847c478bd9Sstevel@tonic-gate 	 * Zones support.
10857c478bd9Sstevel@tonic-gate 	 */
1086a19609f8Sjv 	struct zone	*mi_zone;	/* Zone in which FS is mounted */
1087a19609f8Sjv 	zone_ref_t	mi_zone_ref;	/* Reference to aforementioned zone */
10887c478bd9Sstevel@tonic-gate 	list_node_t	mi_zone_node;  /* linkage into per-zone mi list */
1089b9238976Sth 
1090b9238976Sth 	/*
1091b9238976Sth 	 * Links for unmounting ephemeral mounts.
1092b9238976Sth 	 */
1093b9238976Sth 	struct nfs4_ephemeral		*mi_ephemeral;
1094b9238976Sth 	struct nfs4_ephemeral_tree	*mi_ephemeral_tree;
10953b895386SPavel Filipensky 
10963b895386SPavel Filipensky 	uint_t mi_srvset_cnt; /* increment when changing the nfs4_server_t */
10973b895386SPavel Filipensky 	struct nfs4_server *mi_srv; /* backpointer to nfs4_server_t */
10982f172c55SRobert Thurlow 	/*
10992f172c55SRobert Thurlow 	 * Referral related info.
11002f172c55SRobert Thurlow 	 */
11012f172c55SRobert Thurlow 	int		mi_vfs_referral_loop_cnt;
1102*e010bda9SMarcel Telka 	/*
1103*e010bda9SMarcel Telka 	 * List of rnode4_t structures that belongs to this mntinfo4
1104*e010bda9SMarcel Telka 	 */
1105*e010bda9SMarcel Telka 	kmutex_t	mi_rnodes_lock;	/* protects the mi_rnodes list */
1106*e010bda9SMarcel Telka 	list_t		mi_rnodes;	/* the list */
11077c478bd9Sstevel@tonic-gate } mntinfo4_t;
11087c478bd9Sstevel@tonic-gate 
11097c478bd9Sstevel@tonic-gate /*
11107c478bd9Sstevel@tonic-gate  * The values for mi_flags.
11117c478bd9Sstevel@tonic-gate  *
11127c478bd9Sstevel@tonic-gate  *	MI4_HARD		 hard or soft mount
11137c478bd9Sstevel@tonic-gate  *	MI4_PRINTED		 responding message printed
11147c478bd9Sstevel@tonic-gate  *	MI4_INT			 allow INTR on hard mount
11157c478bd9Sstevel@tonic-gate  * 	MI4_DOWN		 server is down
11167c478bd9Sstevel@tonic-gate  *	MI4_NOAC		 don't cache attributes
11177c478bd9Sstevel@tonic-gate  *	MI4_NOCTO		 no close-to-open consistency
11187c478bd9Sstevel@tonic-gate  *	MI4_LLOCK		 local locking only (no lockmgr)
11197c478bd9Sstevel@tonic-gate  *	MI4_GRPID		 System V group id inheritance
11207c478bd9Sstevel@tonic-gate  *	MI4_SHUTDOWN		 System is rebooting or shutting down
11217c478bd9Sstevel@tonic-gate  *	MI4_LINK		 server supports link
11227c478bd9Sstevel@tonic-gate  *	MI4_SYMLINK		 server supports symlink
1123b9238976Sth  *	MI4_EPHEMERAL_RECURSED	 an ephemeral mount being unmounted
1124b9238976Sth  *				 due to a recursive call - no need
1125b9238976Sth  *				 for additional recursion
11267c478bd9Sstevel@tonic-gate  *	MI4_ACL			 server supports NFSv4 ACLs
1127b9238976Sth  *	MI4_MIRRORMOUNT		 is a mirrormount
11287c478bd9Sstevel@tonic-gate  *	MI4_NOPRINT		 don't print messages
11297c478bd9Sstevel@tonic-gate  *	MI4_DIRECTIO		 do direct I/O
11307c478bd9Sstevel@tonic-gate  *	MI4_RECOV_ACTIV		 filesystem has recovery a thread
11317c478bd9Sstevel@tonic-gate  *	MI4_REMOVE_ON_LAST_CLOSE remove from server's list
11327c478bd9Sstevel@tonic-gate  *	MI4_RECOV_FAIL		 client recovery failed
11337c478bd9Sstevel@tonic-gate  *	MI4_PUBLIC		 public/url option used
11347c478bd9Sstevel@tonic-gate  *	MI4_MOUNTING		 mount in progress, don't failover
11357c478bd9Sstevel@tonic-gate  *	MI4_POSIX_LOCK		 if server is using POSIX locking
11367c478bd9Sstevel@tonic-gate  *	MI4_LOCK_DEBUG		 cmn_err'd posix lock err msg
113750a83466Sjwahlig  *	MI4_DEAD		 zone has released it
11387c478bd9Sstevel@tonic-gate  *	MI4_INACTIVE_IDLE	 inactive thread idle
11397c478bd9Sstevel@tonic-gate  *	MI4_BADOWNER_DEBUG	 badowner error msg per mount
11407c478bd9Sstevel@tonic-gate  *	MI4_ASYNC_MGR_STOP	 tell async manager to die
11417c478bd9Sstevel@tonic-gate  *	MI4_TIMEDOUT		 saw a timeout during zone shutdown
1142b9238976Sth  *	MI4_EPHEMERAL		 is an ephemeral mount
11437c478bd9Sstevel@tonic-gate  */
11447c478bd9Sstevel@tonic-gate #define	MI4_HARD		 0x1
11457c478bd9Sstevel@tonic-gate #define	MI4_PRINTED		 0x2
11467c478bd9Sstevel@tonic-gate #define	MI4_INT			 0x4
11477c478bd9Sstevel@tonic-gate #define	MI4_DOWN		 0x8
11487c478bd9Sstevel@tonic-gate #define	MI4_NOAC		 0x10
11497c478bd9Sstevel@tonic-gate #define	MI4_NOCTO		 0x20
11507c478bd9Sstevel@tonic-gate #define	MI4_LLOCK		 0x80
11517c478bd9Sstevel@tonic-gate #define	MI4_GRPID		 0x100
11527c478bd9Sstevel@tonic-gate #define	MI4_SHUTDOWN		 0x200
11537c478bd9Sstevel@tonic-gate #define	MI4_LINK		 0x400
11547c478bd9Sstevel@tonic-gate #define	MI4_SYMLINK		 0x800
1155b9238976Sth #define	MI4_EPHEMERAL_RECURSED	 0x1000
11567c478bd9Sstevel@tonic-gate #define	MI4_ACL			 0x2000
1157b9238976Sth /* MI4_MIRRORMOUNT is also defined in nfsstat.c */
1158b9238976Sth #define	MI4_MIRRORMOUNT		 0x4000
11592f172c55SRobert Thurlow #define	MI4_REFERRAL		 0x8000
11607c478bd9Sstevel@tonic-gate /* 0x10000 is available */
11617c478bd9Sstevel@tonic-gate #define	MI4_NOPRINT		 0x20000
11627c478bd9Sstevel@tonic-gate #define	MI4_DIRECTIO		 0x40000
11637c478bd9Sstevel@tonic-gate /* 0x80000 is available */
11647c478bd9Sstevel@tonic-gate #define	MI4_RECOV_ACTIV		 0x100000
11657c478bd9Sstevel@tonic-gate #define	MI4_REMOVE_ON_LAST_CLOSE 0x200000
11667c478bd9Sstevel@tonic-gate #define	MI4_RECOV_FAIL		 0x400000
11677c478bd9Sstevel@tonic-gate #define	MI4_PUBLIC		 0x800000
11687c478bd9Sstevel@tonic-gate #define	MI4_MOUNTING		 0x1000000
11697c478bd9Sstevel@tonic-gate #define	MI4_POSIX_LOCK		 0x2000000
11707c478bd9Sstevel@tonic-gate #define	MI4_LOCK_DEBUG		 0x4000000
11717c478bd9Sstevel@tonic-gate #define	MI4_DEAD		 0x8000000
11727c478bd9Sstevel@tonic-gate #define	MI4_INACTIVE_IDLE	 0x10000000
11737c478bd9Sstevel@tonic-gate #define	MI4_BADOWNER_DEBUG	 0x20000000
11747c478bd9Sstevel@tonic-gate #define	MI4_ASYNC_MGR_STOP	 0x40000000
11757c478bd9Sstevel@tonic-gate #define	MI4_TIMEDOUT		 0x80000000
11767c478bd9Sstevel@tonic-gate 
11772f172c55SRobert Thurlow #define	MI4_EPHEMERAL		(MI4_MIRRORMOUNT | MI4_REFERRAL)
1178b9238976Sth 
11797c478bd9Sstevel@tonic-gate #define	INTR4(vp)	(VTOMI4(vp)->mi_flags & MI4_INT)
11807c478bd9Sstevel@tonic-gate 
11817c478bd9Sstevel@tonic-gate #define	FAILOVER_MOUNT4(mi)	(mi->mi_servers->sv_next)
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate /*
11847c478bd9Sstevel@tonic-gate  * Recovery flags.
11857c478bd9Sstevel@tonic-gate  *
11867c478bd9Sstevel@tonic-gate  * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag
11877c478bd9Sstevel@tonic-gate  * that's important), but some flag is needed to indicate that recovery is
11887c478bd9Sstevel@tonic-gate  * going on for the filesystem.
11897c478bd9Sstevel@tonic-gate  */
11907c478bd9Sstevel@tonic-gate #define	MI4R_NEED_CLIENTID	0x1
11917c478bd9Sstevel@tonic-gate #define	MI4R_REOPEN_FILES	0x2
11927c478bd9Sstevel@tonic-gate #define	MI4R_NEED_SECINFO	0x4
11937c478bd9Sstevel@tonic-gate #define	MI4R_NEED_NEW_SERVER	0x8
11947c478bd9Sstevel@tonic-gate #define	MI4R_REMAP_FILES	0x10
11957c478bd9Sstevel@tonic-gate #define	MI4R_SRV_REBOOT		0x20	/* server has rebooted */
11967c478bd9Sstevel@tonic-gate #define	MI4R_LOST_STATE		0x40
11977c478bd9Sstevel@tonic-gate #define	MI4R_BAD_SEQID		0x80
11982f172c55SRobert Thurlow #define	MI4R_MOVED		0x100
11997c478bd9Sstevel@tonic-gate 
120050a83466Sjwahlig #define	MI4_HOLD(mi) {		\
120150a83466Sjwahlig 	mi_hold(mi);		\
120250a83466Sjwahlig }
120350a83466Sjwahlig 
120450a83466Sjwahlig #define	MI4_RELE(mi) {		\
120550a83466Sjwahlig 	mi_rele(mi);		\
120650a83466Sjwahlig }
120750a83466Sjwahlig 
12087c478bd9Sstevel@tonic-gate /*
12097c478bd9Sstevel@tonic-gate  * vfs pointer to mount info
12107c478bd9Sstevel@tonic-gate  */
12117c478bd9Sstevel@tonic-gate #define	VFTOMI4(vfsp)	((mntinfo4_t *)((vfsp)->vfs_data))
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate /*
12147c478bd9Sstevel@tonic-gate  * vnode pointer to mount info
12157c478bd9Sstevel@tonic-gate  */
12167c478bd9Sstevel@tonic-gate #define	VTOMI4(vp)	((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data))
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate /*
12197c478bd9Sstevel@tonic-gate  * Lease Management
12207c478bd9Sstevel@tonic-gate  *
12217c478bd9Sstevel@tonic-gate  * lease_valid is initially set to NFS4_LEASE_NOT_STARTED.  This is when the
12227c478bd9Sstevel@tonic-gate  * nfs4_server is first created.  lease_valid is then set to
12237c478bd9Sstevel@tonic-gate  * NFS4_LEASE_UNITIALIZED when the renew thread is started.  The extra state of
12247c478bd9Sstevel@tonic-gate  * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread
12257c478bd9Sstevel@tonic-gate  * already exists when we do SETCLIENTID).  lease_valid is then set to
12267c478bd9Sstevel@tonic-gate  * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating
12277c478bd9Sstevel@tonic-gate  * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as
12287c478bd9Sstevel@tonic-gate  * the lease is renewed.  It is set to NFS4_LEASE_INVALID when the lease
12297c478bd9Sstevel@tonic-gate  * expires.  Client recovery is needed to set the lease back to
12307c478bd9Sstevel@tonic-gate  * NFS4_LEASE_VALID from NFS4_LEASE_INVALID.
12317c478bd9Sstevel@tonic-gate  *
12327c478bd9Sstevel@tonic-gate  * The s_cred is the credential used to mount the first file system for this
12337c478bd9Sstevel@tonic-gate  * server.  It used as the credential for the renew thread's calls to the
12347c478bd9Sstevel@tonic-gate  * server.
12357c478bd9Sstevel@tonic-gate  *
12367c478bd9Sstevel@tonic-gate  * The renew thread waits on the condition variable cv_thread_exit.  If the cv
12377c478bd9Sstevel@tonic-gate  * is signalled, then the thread knows it must check s_thread_exit to see if
12387c478bd9Sstevel@tonic-gate  * it should exit.  The cv is signaled when the last file system is unmounted
12397c478bd9Sstevel@tonic-gate  * from a particular server.  s_thread_exit is set to 0 upon thread startup,
12407c478bd9Sstevel@tonic-gate  * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby
12417c478bd9Sstevel@tonic-gate  * telling the thread to exit.  s_thread_exit is needed to avoid spurious
12427c478bd9Sstevel@tonic-gate  * wakeups.
12437c478bd9Sstevel@tonic-gate  *
12447c478bd9Sstevel@tonic-gate  * state_ref_count is incremented every time a new file is opened and
12457c478bd9Sstevel@tonic-gate  * decremented every time a file is closed otw.  This keeps track of whether
12467c478bd9Sstevel@tonic-gate  * the nfs4_server has state associated with it or not.
12477c478bd9Sstevel@tonic-gate  *
12487c478bd9Sstevel@tonic-gate  * s_refcnt is the reference count for storage management of the struct
12497c478bd9Sstevel@tonic-gate  * itself.
12507c478bd9Sstevel@tonic-gate  *
12517c478bd9Sstevel@tonic-gate  * mntinfo4_list points to the doubly linked list of mntinfo4s that share
12527c478bd9Sstevel@tonic-gate  * this nfs4_server (ie: <clientid, saddr> pair) in the current zone.  This is
12537c478bd9Sstevel@tonic-gate  * needed for a nfs4_server to get a mntinfo4 for use in rfs4call.
12547c478bd9Sstevel@tonic-gate  *
12557c478bd9Sstevel@tonic-gate  * s_recovlock is used to synchronize recovery operations.  The thread
12567c478bd9Sstevel@tonic-gate  * that is recovering the client must acquire it as a writer.  If the
12577c478bd9Sstevel@tonic-gate  * thread is using the clientid (including recovery operations on other
12587c478bd9Sstevel@tonic-gate  * state), acquire it as a reader.
12597c478bd9Sstevel@tonic-gate  *
12607c478bd9Sstevel@tonic-gate  * The 's_otw_call_count' keeps track of the number of outstanding over the
12617c478bd9Sstevel@tonic-gate  * wire requests for this structure.  The struct will not go away as long
12627c478bd9Sstevel@tonic-gate  * as this is non-zero (or s_refcnt is non-zero).
12637c478bd9Sstevel@tonic-gate  *
12647c478bd9Sstevel@tonic-gate  * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count'
12657c478bd9Sstevel@tonic-gate  * variable to let the renew thread when an outstanding otw request has
12667c478bd9Sstevel@tonic-gate  * finished.
12677c478bd9Sstevel@tonic-gate  *
12687c478bd9Sstevel@tonic-gate  * 'zoneid' and 'zone_globals' are set at creation of this structure
12697c478bd9Sstevel@tonic-gate  * and are read-only after that; no lock is required to read them.
12707c478bd9Sstevel@tonic-gate  *
12717c478bd9Sstevel@tonic-gate  * s_lock protects: everything except cv_thread_exit and s_recovlock.
12727c478bd9Sstevel@tonic-gate  *
12737c478bd9Sstevel@tonic-gate  * s_program is used as the index into the nfs4_callback_globals's
12747c478bd9Sstevel@tonic-gate  * nfs4prog2server table.  When a callback request comes in, we can
12757c478bd9Sstevel@tonic-gate  * use that request's program number (minus NFS4_CALLBACK) as an index
12767c478bd9Sstevel@tonic-gate  * into the nfs4prog2server.  That entry will hold the nfs4_server_t ptr.
12777c478bd9Sstevel@tonic-gate  * We can then access that nfs4_server_t and its 's_deleg_list' (its list of
12787c478bd9Sstevel@tonic-gate  * delegated rnode4_ts).
12797c478bd9Sstevel@tonic-gate  *
12807c478bd9Sstevel@tonic-gate  * Lock order:
12817c478bd9Sstevel@tonic-gate  * nfs4_server::s_lock > mntinfo4::mi_lock
12827c478bd9Sstevel@tonic-gate  * nfs_rtable4_lock > s_lock
12837c478bd9Sstevel@tonic-gate  * nfs4_server_lst_lock > s_lock
12847c478bd9Sstevel@tonic-gate  * s_recovlock > s_lock
12857c478bd9Sstevel@tonic-gate  */
12867c478bd9Sstevel@tonic-gate struct nfs4_callback_globals;
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate typedef struct nfs4_server {
12897c478bd9Sstevel@tonic-gate 	struct nfs4_server	*forw;
12907c478bd9Sstevel@tonic-gate 	struct nfs4_server	*back;
12917c478bd9Sstevel@tonic-gate 	struct netbuf		saddr;
12927c478bd9Sstevel@tonic-gate 	uint_t			s_flags; /* see below */
12937c478bd9Sstevel@tonic-gate 	uint_t			s_refcnt;
12947c478bd9Sstevel@tonic-gate 	clientid4		clientid;	/* what we get from server */
12957c478bd9Sstevel@tonic-gate 	nfs_client_id4		clidtosend;	/* what we send to server */
12967c478bd9Sstevel@tonic-gate 	mntinfo4_t		*mntinfo4_list;
12977c478bd9Sstevel@tonic-gate 	int			lease_valid;
12987c478bd9Sstevel@tonic-gate 	time_t			s_lease_time;
12997c478bd9Sstevel@tonic-gate 	time_t			last_renewal_time;
13007c478bd9Sstevel@tonic-gate 	timespec_t		propagation_delay;
13017c478bd9Sstevel@tonic-gate 	cred_t			*s_cred;
13027c478bd9Sstevel@tonic-gate 	kcondvar_t		cv_thread_exit;
13037c478bd9Sstevel@tonic-gate 	int			s_thread_exit;
13047c478bd9Sstevel@tonic-gate 	int			state_ref_count;
13057c478bd9Sstevel@tonic-gate 	int			s_otw_call_count;
13067c478bd9Sstevel@tonic-gate 	kcondvar_t		s_cv_otw_count;
1307f86c6ccaSdm 	kcondvar_t		s_clientid_pend;
13087c478bd9Sstevel@tonic-gate 	kmutex_t		s_lock;
13097c478bd9Sstevel@tonic-gate 	list_t			s_deleg_list;
13107c478bd9Sstevel@tonic-gate 	rpcprog_t		s_program;
13117c478bd9Sstevel@tonic-gate 	nfs_rwlock_t		s_recovlock;
13127c478bd9Sstevel@tonic-gate 	kcondvar_t		wait_cb_null; /* used to wait for CB_NULL */
13137c478bd9Sstevel@tonic-gate 	zoneid_t		zoneid;	/* zone using this nfs4_server_t */
13147c478bd9Sstevel@tonic-gate 	struct nfs4_callback_globals *zone_globals;	/* globals */
13157c478bd9Sstevel@tonic-gate } nfs4_server_t;
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate /* nfs4_server flags */
13187c478bd9Sstevel@tonic-gate #define	N4S_CLIENTID_SET	1	/* server has our clientid */
1319f86c6ccaSdm #define	N4S_CLIENTID_PEND	0x2	/* server doesn't have clientid */
13207c478bd9Sstevel@tonic-gate #define	N4S_CB_PINGED		0x4	/* server has sent us a CB_NULL */
13217c478bd9Sstevel@tonic-gate #define	N4S_CB_WAITER		0x8	/* is/has wait{ing/ed} for cb_null */
1322f64c4ae1Sdm #define	N4S_INSERTED		0x10	/* list has reference for server */
1323f64c4ae1Sdm #define	N4S_BADOWNER_DEBUG	0x20	/* bad owner err msg per client */
13247c478bd9Sstevel@tonic-gate 
13257c478bd9Sstevel@tonic-gate #define	N4S_CB_PAUSE_TIME	10000	/* Amount of time to pause (10ms) */
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate struct lease_time_arg {
13287c478bd9Sstevel@tonic-gate 	time_t	lease_time;
13297c478bd9Sstevel@tonic-gate };
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate enum nfs4_delegreturn_policy {
13327c478bd9Sstevel@tonic-gate 	IMMEDIATE,
13337c478bd9Sstevel@tonic-gate 	FIRSTCLOSE,
13347c478bd9Sstevel@tonic-gate 	LASTCLOSE,
13357c478bd9Sstevel@tonic-gate 	INACTIVE
13367c478bd9Sstevel@tonic-gate };
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate /*
13397c478bd9Sstevel@tonic-gate  * Operation hints for the recovery framework (mostly).
13407c478bd9Sstevel@tonic-gate  *
13417c478bd9Sstevel@tonic-gate  * EXCEPTIONS:
13427c478bd9Sstevel@tonic-gate  * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR
13437c478bd9Sstevel@tonic-gate  *	These hints exist to allow user visit/readdir a R4SRVSTUB dir.
13447c478bd9Sstevel@tonic-gate  *	(dir represents the root of a server fs that has not yet been
13457c478bd9Sstevel@tonic-gate  *	mounted at client)
13467c478bd9Sstevel@tonic-gate  */
13477c478bd9Sstevel@tonic-gate typedef enum {
13487c478bd9Sstevel@tonic-gate 	OH_OTHER,
13497c478bd9Sstevel@tonic-gate 	OH_READ,
13507c478bd9Sstevel@tonic-gate 	OH_WRITE,
13517c478bd9Sstevel@tonic-gate 	OH_COMMIT,
13527c478bd9Sstevel@tonic-gate 	OH_VFH_RENAME,
13537c478bd9Sstevel@tonic-gate 	OH_MOUNT,
13547c478bd9Sstevel@tonic-gate 	OH_CLOSE,
13557c478bd9Sstevel@tonic-gate 	OH_LOCKU,
13567c478bd9Sstevel@tonic-gate 	OH_DELEGRETURN,
13577c478bd9Sstevel@tonic-gate 	OH_ACCESS,
13587c478bd9Sstevel@tonic-gate 	OH_GETACL,
13597c478bd9Sstevel@tonic-gate 	OH_GETATTR,
13607c478bd9Sstevel@tonic-gate 	OH_LOOKUP,
13617c478bd9Sstevel@tonic-gate 	OH_READDIR
13627c478bd9Sstevel@tonic-gate } nfs4_op_hint_t;
13637c478bd9Sstevel@tonic-gate 
1364b9238976Sth /*
1365b9238976Sth  * This data structure is used to track ephemeral mounts for both
1366b9238976Sth  * mirror mounts and referrals.
1367b9238976Sth  *
1368b9238976Sth  * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral
1369b9238976Sth  * pointing at it. So we don't need two backpointers to walk
1370b9238976Sth  * back up the tree.
1371b9238976Sth  *
1372b9238976Sth  * An ephemeral tree is pointed to by an enclosing non-ephemeral
1373b9238976Sth  * mntinfo4. The root is also pointed to by its ephemeral
1374b9238976Sth  * mntinfo4. ne_child will get us back to it, while ne_prior
1375b9238976Sth  * will get us back to the non-ephemeral mntinfo4. This is an
1376b9238976Sth  * edge case we will need to be wary of when walking back up the
1377b9238976Sth  * tree.
1378b9238976Sth  *
1379b9238976Sth  * The way we handle this edge case is to have ne_prior be NULL
1380b9238976Sth  * for the root nfs4_ephemeral node.
1381b9238976Sth  */
1382b9238976Sth typedef struct nfs4_ephemeral {
1383b9238976Sth 	mntinfo4_t		*ne_mount;	/* who encloses us */
1384b9238976Sth 	struct nfs4_ephemeral	*ne_child;	/* first child node */
1385b9238976Sth 	struct nfs4_ephemeral	*ne_peer;	/* next sibling */
1386b9238976Sth 	struct nfs4_ephemeral	*ne_prior;	/* who points at us */
1387b9238976Sth 	time_t			ne_ref_time;	/* time last referenced */
1388b9238976Sth 	uint_t			ne_mount_to;	/* timeout at */
1389b9238976Sth 	int			ne_state;	/* used to traverse */
1390b9238976Sth } nfs4_ephemeral_t;
1391b9238976Sth 
1392b9238976Sth /*
1393b9238976Sth  * State for the node (set in ne_state):
1394b9238976Sth  */
1395b9238976Sth #define	NFS4_EPHEMERAL_OK		0x0
1396b9238976Sth #define	NFS4_EPHEMERAL_VISIT_CHILD	0x1
1397b9238976Sth #define	NFS4_EPHEMERAL_VISIT_SIBLING	0x2
1398b9238976Sth #define	NFS4_EPHEMERAL_PROCESS_ME	0x4
1399b9238976Sth #define	NFS4_EPHEMERAL_CHILD_ERROR	0x8
1400b9238976Sth #define	NFS4_EPHEMERAL_PEER_ERROR	0x10
1401b9238976Sth 
1402b9238976Sth /*
1403b9238976Sth  * These are the locks used in processing ephemeral data:
1404b9238976Sth  *
1405b9238976Sth  * mi->mi_lock
1406b9238976Sth  *
1407b9238976Sth  * net->net_tree_lock
1408b9238976Sth  *     This lock is used to gate all tree operations.
1409b9238976Sth  *     If it is held, then no other process may
1410b9238976Sth  *     traverse the tree. This allows us to not
1411b9238976Sth  *     throw a hold on each vfs_t in the tree.
1412b9238976Sth  *     Can be held for a "long" time.
1413b9238976Sth  *
1414b9238976Sth  * net->net_cnt_lock
1415b9238976Sth  *     Used to protect refcnt and status.
1416b9238976Sth  *     Must be held for a really short time.
1417b9238976Sth  *
1418b9238976Sth  * nfs4_ephemeral_thread_lock
1419b9238976Sth  *     Is only held to create the harvester for the zone.
1420b9238976Sth  *     There is no ordering imposed on it.
1421b9238976Sth  *     Held for a really short time.
1422b9238976Sth  *
1423b9238976Sth  * Some further detail on the interactions:
1424b9238976Sth  *
1425b9238976Sth  * net_tree_lock controls access to net_root. Access needs to first be
1426b9238976Sth  * attempted in a non-blocking check.
1427b9238976Sth  *
1428b9238976Sth  * net_cnt_lock controls access to net_refcnt and net_status. It must only be
1429b9238976Sth  * held for very short periods of time, unless the refcnt is 0 and the status
1430b9238976Sth  * is INVALID.
1431b9238976Sth  *
1432b9238976Sth  * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock
1433b9238976Sth  * to bump the net_refcnt. It then releases it and does the action specific
1434b9238976Sth  * algorithm to get the net_tree_lock. Once it has that, then it is okay to
1435b9238976Sth  * grab the net_cnt_lock and change the status. The status can only be
1436b9238976Sth  * changed if the caller has the net_tree_lock held as well.
1437b9238976Sth  *
1438eabd0450Sth  * Note that the initial grab of net_cnt_lock must occur whilst
1439eabd0450Sth  * mi_lock is being held. This prevents stale data in that if the
1440eabd0450Sth  * ephemeral tree is non-NULL, then the harvester can not remove
1441eabd0450Sth  * the tree from the mntinfo node until it grabs that lock. I.e.,
1442eabd0450Sth  * we get the pointer to the tree and hold the lock atomically
1443eabd0450Sth  * with respect to being in mi_lock.
1444eabd0450Sth  *
1445b9238976Sth  * When a caller is done with net_tree_lock, it can decrement the net_refcnt
1446b9238976Sth  * either before it releases net_tree_lock or after.
1447b9238976Sth  *
1448b9238976Sth  * In either event, to decrement net_refcnt, it must hold net_cnt_lock.
1449b9238976Sth  *
1450b9238976Sth  * Note that the overall locking scheme for the nodes is to control access
1451b9238976Sth  * via the tree. The current scheme could easily be extended such that
1452b9238976Sth  * the enclosing root referenced a "forest" of trees. The underlying trees
1453b9238976Sth  * would be autonomous with respect to locks.
1454b9238976Sth  *
1455b9238976Sth  * Note that net_next is controlled by external locks
1456b9238976Sth  * particular to the data structure that the tree is being added to.
1457b9238976Sth  */
1458b9238976Sth typedef struct nfs4_ephemeral_tree {
1459b9238976Sth 	mntinfo4_t			*net_mount;
1460b9238976Sth 	nfs4_ephemeral_t		*net_root;
1461b9238976Sth 	struct nfs4_ephemeral_tree	*net_next;
1462b9238976Sth 	kmutex_t			net_tree_lock;
1463b9238976Sth 	kmutex_t			net_cnt_lock;
1464b9238976Sth 	uint_t				net_status;
1465b9238976Sth 	uint_t				net_refcnt;
1466b9238976Sth } nfs4_ephemeral_tree_t;
1467b9238976Sth 
1468b9238976Sth /*
1469b9238976Sth  * State for the tree (set in net_status):
1470b9238976Sth  */
1471b9238976Sth #define	NFS4_EPHEMERAL_TREE_OK		0x0
1472b9238976Sth #define	NFS4_EPHEMERAL_TREE_BUILDING	0x1
1473b9238976Sth #define	NFS4_EPHEMERAL_TREE_DEROOTING	0x2
1474b9238976Sth #define	NFS4_EPHEMERAL_TREE_INVALID	0x4
1475b9238976Sth #define	NFS4_EPHEMERAL_TREE_MOUNTING	0x8
1476b9238976Sth #define	NFS4_EPHEMERAL_TREE_UMOUNTING	0x10
1477b9238976Sth #define	NFS4_EPHEMERAL_TREE_LOCKED	0x20
1478b9238976Sth 
1479d3a14591SThomas Haynes #define	NFS4_EPHEMERAL_TREE_PROCESSING	(NFS4_EPHEMERAL_TREE_DEROOTING | \
1480d3a14591SThomas Haynes 	NFS4_EPHEMERAL_TREE_INVALID | NFS4_EPHEMERAL_TREE_UMOUNTING | \
1481d3a14591SThomas Haynes 	NFS4_EPHEMERAL_TREE_LOCKED)
1482d3a14591SThomas Haynes 
14837c478bd9Sstevel@tonic-gate /*
14847c478bd9Sstevel@tonic-gate  * This macro evaluates to non-zero if the given op releases state at the
14857c478bd9Sstevel@tonic-gate  * server.
14867c478bd9Sstevel@tonic-gate  */
14877c478bd9Sstevel@tonic-gate #define	OH_IS_STATE_RELE(op)	((op) == OH_CLOSE || (op) == OH_LOCKU || \
14887c478bd9Sstevel@tonic-gate 				(op) == OH_DELEGRETURN)
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate #ifdef _KERNEL
14917c478bd9Sstevel@tonic-gate 
14927c478bd9Sstevel@tonic-gate extern void	nfs4_async_manager(struct vfs *);
14937c478bd9Sstevel@tonic-gate extern void	nfs4_async_manager_stop(struct vfs *);
14947c478bd9Sstevel@tonic-gate extern void	nfs4_async_stop(struct vfs *);
14957c478bd9Sstevel@tonic-gate extern int	nfs4_async_stop_sig(struct vfs *);
14967c478bd9Sstevel@tonic-gate extern int	nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t,
14977c478bd9Sstevel@tonic-gate 				struct seg *, cred_t *,
14987c478bd9Sstevel@tonic-gate 				void (*)(vnode_t *, u_offset_t,
14997c478bd9Sstevel@tonic-gate 				caddr_t, struct seg *, cred_t *));
15007c478bd9Sstevel@tonic-gate extern int	nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t,
15017c478bd9Sstevel@tonic-gate 				int, cred_t *, int (*)(vnode_t *, page_t *,
15027c478bd9Sstevel@tonic-gate 				u_offset_t, size_t, int, cred_t *));
15037c478bd9Sstevel@tonic-gate extern int	nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t,
15047c478bd9Sstevel@tonic-gate 				int, cred_t *, int (*)(vnode_t *, page_t *,
15057c478bd9Sstevel@tonic-gate 				u_offset_t, size_t, int, cred_t *));
15067c478bd9Sstevel@tonic-gate extern void	nfs4_async_commit(vnode_t *, page_t *, offset3, count3,
15077c478bd9Sstevel@tonic-gate 				cred_t *, void (*)(vnode_t *, page_t *,
15087c478bd9Sstevel@tonic-gate 				offset3, count3, cred_t *));
15097c478bd9Sstevel@tonic-gate extern void	nfs4_async_inactive(vnode_t *, cred_t *);
15107c478bd9Sstevel@tonic-gate extern void	nfs4_inactive_thread(mntinfo4_t *mi);
15117c478bd9Sstevel@tonic-gate extern void	nfs4_inactive_otw(vnode_t *, cred_t *);
15127c478bd9Sstevel@tonic-gate extern int	nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *);
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate extern int	nfs4_setopts(vnode_t *, model_t, struct nfs_args *);
15157c478bd9Sstevel@tonic-gate extern void	nfs4_mnt_kstat_init(struct vfs *);
15167c478bd9Sstevel@tonic-gate 
15177c478bd9Sstevel@tonic-gate extern void	rfs4call(struct mntinfo4 *, struct COMPOUND4args_clnt *,
15187c478bd9Sstevel@tonic-gate 			struct COMPOUND4res_clnt *, cred_t *, int *, int,
15197c478bd9Sstevel@tonic-gate 			nfs4_error_t *);
15207c478bd9Sstevel@tonic-gate extern void	nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *);
15217c478bd9Sstevel@tonic-gate extern int	nfs4_attr_otw(vnode_t *, nfs4_tag_type_t,
15227c478bd9Sstevel@tonic-gate 				nfs4_ga_res_t *, bitmap4, cred_t *);
15237c478bd9Sstevel@tonic-gate 
15247c478bd9Sstevel@tonic-gate extern void	nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t);
15257c478bd9Sstevel@tonic-gate extern void	nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *,
15267c478bd9Sstevel@tonic-gate 				hrtime_t, cred_t *, int,
15277c478bd9Sstevel@tonic-gate 				change_info4 *);
15287c478bd9Sstevel@tonic-gate extern void	nfs4_purge_rddir_cache(vnode_t *);
15297c478bd9Sstevel@tonic-gate extern void	nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *);
15307c478bd9Sstevel@tonic-gate extern void	nfs4_purge_caches(vnode_t *, int, cred_t *, int);
15317c478bd9Sstevel@tonic-gate extern void	nfs4_purge_stale_fh(int, vnode_t *, cred_t *);
1532d55e25c3SPavel Filipensky extern void	nfs4_flush_pages(vnode_t *vp, cred_t *cr);
15337c478bd9Sstevel@tonic-gate 
15347c478bd9Sstevel@tonic-gate extern void	nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *);
15357c478bd9Sstevel@tonic-gate extern void	nfs4_update_paths(vnode_t *, char *, vnode_t *, char *,
15367c478bd9Sstevel@tonic-gate 			vnode_t *);
15377c478bd9Sstevel@tonic-gate 
15387c478bd9Sstevel@tonic-gate extern void	nfs4args_lookup_free(nfs_argop4 *, int);
15397c478bd9Sstevel@tonic-gate extern void	nfs4args_copen_free(OPEN4cargs *);
15407c478bd9Sstevel@tonic-gate 
15417c478bd9Sstevel@tonic-gate extern void	nfs4_printfhandle(nfs4_fhandle_t *);
15427c478bd9Sstevel@tonic-gate 
15437c478bd9Sstevel@tonic-gate extern void	nfs_free_mi4(mntinfo4_t *);
15447c478bd9Sstevel@tonic-gate extern void	sv4_free(servinfo4_t *);
15457c478bd9Sstevel@tonic-gate extern void	nfs4_mi_zonelist_add(mntinfo4_t *);
154650a83466Sjwahlig extern int	nfs4_mi_zonelist_remove(mntinfo4_t *);
15477c478bd9Sstevel@tonic-gate extern int 	nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *);
15487c478bd9Sstevel@tonic-gate extern void	nfs4_secinfo_init(void);
15497c478bd9Sstevel@tonic-gate extern void	nfs4_secinfo_fini(void);
15507c478bd9Sstevel@tonic-gate extern int	nfs4_secinfo_path(mntinfo4_t *, cred_t *, int);
15517c478bd9Sstevel@tonic-gate extern int 	nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *);
15527c478bd9Sstevel@tonic-gate extern void	secinfo_free(sv_secinfo_t *);
15537c478bd9Sstevel@tonic-gate extern void	save_mnt_secinfo(servinfo4_t *);
15547c478bd9Sstevel@tonic-gate extern void	check_mnt_secinfo(servinfo4_t *, vnode_t *);
15557c478bd9Sstevel@tonic-gate extern int	vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int,
15567c478bd9Sstevel@tonic-gate 				enum nfs_opnum4, bitmap4 supp_mask);
15577c478bd9Sstevel@tonic-gate extern int	nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *,
15587c478bd9Sstevel@tonic-gate 			int, cred_t *);
15597c478bd9Sstevel@tonic-gate extern void	nfs4_write_error(vnode_t *, int, cred_t *);
15607c478bd9Sstevel@tonic-gate extern void	nfs4_lockcompletion(vnode_t *, int);
15617c478bd9Sstevel@tonic-gate extern bool_t	nfs4_map_lost_lock_conflict(vnode_t *);
15627c478bd9Sstevel@tonic-gate extern int	vtodv(vnode_t *, vnode_t **, cred_t *, bool_t);
15632f172c55SRobert Thurlow extern int	vtoname(vnode_t *, char *, ssize_t);
15647c478bd9Sstevel@tonic-gate extern void	nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *,
15657c478bd9Sstevel@tonic-gate 		    bool_t, bool_t *, nfs4_open_owner_t *, bool_t,
15667c478bd9Sstevel@tonic-gate 		    nfs4_error_t *, int *);
15677c478bd9Sstevel@tonic-gate extern void	nfs4_error_zinit(nfs4_error_t *);
15687c478bd9Sstevel@tonic-gate extern void	nfs4_error_init(nfs4_error_t *, int);
1569b9238976Sth extern void	nfs4_free_args(struct nfs_args *);
157050a83466Sjwahlig 
157150a83466Sjwahlig extern void 	mi_hold(mntinfo4_t *);
157250a83466Sjwahlig extern void	mi_rele(mntinfo4_t *);
157350a83466Sjwahlig 
15742f172c55SRobert Thurlow extern vnode_t	*find_referral_stubvp(vnode_t *, char *, cred_t *);
15752f172c55SRobert Thurlow extern int	 nfs4_setup_referral(vnode_t *, char *, vnode_t **, cred_t *);
15762f172c55SRobert Thurlow 
1577b9238976Sth extern sec_data_t	*copy_sec_data(sec_data_t *);
1578b9238976Sth extern gss_clntdata_t	*copy_sec_data_gss(gss_clntdata_t *);
1579b9238976Sth 
15807c478bd9Sstevel@tonic-gate #ifdef DEBUG
15817c478bd9Sstevel@tonic-gate extern int	nfs4_consistent_type(vnode_t *);
15827c478bd9Sstevel@tonic-gate #endif
15837c478bd9Sstevel@tonic-gate 
15847c478bd9Sstevel@tonic-gate extern void	nfs4_init_dot_entries(void);
15857c478bd9Sstevel@tonic-gate extern void	nfs4_destroy_dot_entries(void);
15867c478bd9Sstevel@tonic-gate extern struct nfs4_callback_globals	*nfs4_get_callback_globals(void);
15877c478bd9Sstevel@tonic-gate 
15887c478bd9Sstevel@tonic-gate extern struct nfs4_server nfs4_server_lst;
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate extern clock_t nfs_write_error_interval;
15917c478bd9Sstevel@tonic-gate 
15927c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate /*
15957c478bd9Sstevel@tonic-gate  * Flags for nfs4getfh_otw.
15967c478bd9Sstevel@tonic-gate  */
15977c478bd9Sstevel@tonic-gate 
15987c478bd9Sstevel@tonic-gate #define	NFS4_GETFH_PUBLIC	0x01
15997c478bd9Sstevel@tonic-gate #define	NFS4_GETFH_NEEDSOP	0x02
16007c478bd9Sstevel@tonic-gate 
16017c478bd9Sstevel@tonic-gate /*
16027c478bd9Sstevel@tonic-gate  * Found through rnodes.
16037c478bd9Sstevel@tonic-gate  *
16047c478bd9Sstevel@tonic-gate  * The os_open_ref_count keeps track the number of open file descriptor
1605957f6e72SMarcel Telka  * references on this data structure.  It will be bumped for any successful
16067c478bd9Sstevel@tonic-gate  * OTW OPEN call and any OPEN call that determines the OTW call is not
16077c478bd9Sstevel@tonic-gate  * necessary and the open stream hasn't just been created (see
16087c478bd9Sstevel@tonic-gate  * nfs4_is_otw_open_necessary).
16097c478bd9Sstevel@tonic-gate  *
16107c478bd9Sstevel@tonic-gate  * os_mapcnt is a count of the number of mmapped pages for a particular
16117c478bd9Sstevel@tonic-gate  * open stream; this in conjunction w/ os_open_ref_count is used to
16127c478bd9Sstevel@tonic-gate  * determine when to do a close to the server.  This is necessary because
16137c478bd9Sstevel@tonic-gate  * of the semantics of doing open, mmap, close; the OTW close must be wait
16147c478bd9Sstevel@tonic-gate  * until all open and mmap references have vanished.
16157c478bd9Sstevel@tonic-gate  *
16167c478bd9Sstevel@tonic-gate  * 'os_valid' tells us whether this structure is about to be freed or not,
16177c478bd9Sstevel@tonic-gate  * if it is then don't return it in find_open_stream().
16187c478bd9Sstevel@tonic-gate  *
16197c478bd9Sstevel@tonic-gate  * 'os_final_close' is set when a CLOSE OTW was attempted.  This is needed
16207c478bd9Sstevel@tonic-gate  * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE
16217c478bd9Sstevel@tonic-gate  * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE.  It
16227c478bd9Sstevel@tonic-gate  * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE
16237c478bd9Sstevel@tonic-gate  * that tried to close OTW but failed, and left the state cleanup to
16247c478bd9Sstevel@tonic-gate  * nfs4_inactive/CLOSE_FORCE.
16257c478bd9Sstevel@tonic-gate  *
16267c478bd9Sstevel@tonic-gate  * 'os_force_close' is used to let us know if an intervening thread came
16277c478bd9Sstevel@tonic-gate  * and reopened the open stream after we decided to issue a CLOSE_FORCE,
16287c478bd9Sstevel@tonic-gate  * but before we could actually process the CLOSE_FORCE.
16297c478bd9Sstevel@tonic-gate  *
16307c478bd9Sstevel@tonic-gate  * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the
16317c478bd9Sstevel@tonic-gate  * lost state queue.
16327c478bd9Sstevel@tonic-gate  *
1633957f6e72SMarcel Telka  * 'open_stateid' is set to the last open stateid returned by the server unless
16347c478bd9Sstevel@tonic-gate  * 'os_delegation' is 1, in which case 'open_stateid' refers to the
16357c478bd9Sstevel@tonic-gate  * delegation stateid returned by the server.  This is used in cases where the
16367c478bd9Sstevel@tonic-gate  * client tries to OPEN a file but already has a suitable delegation, so we
16377c478bd9Sstevel@tonic-gate  * just stick the delegation stateid in the open stream.
16387c478bd9Sstevel@tonic-gate  *
16397c478bd9Sstevel@tonic-gate  * os_dc_openacc are open access bits which have been granted to the
16407c478bd9Sstevel@tonic-gate  * open stream by virtue of a delegation, but which have not been seen
16417c478bd9Sstevel@tonic-gate  * by the server.  This applies even if the open stream does not have
16427c478bd9Sstevel@tonic-gate  * os_delegation set.  These bits are used when setting file locks to
16437c478bd9Sstevel@tonic-gate  * determine whether an open with CLAIM_DELEGATE_CUR needs to be done
16447c478bd9Sstevel@tonic-gate  * before the lock request can be sent to the server.  See
16457c478bd9Sstevel@tonic-gate  * nfs4frlock_check_deleg().
16467c478bd9Sstevel@tonic-gate  *
16477c478bd9Sstevel@tonic-gate  * 'os_mmap_read/write' keep track of the read and write access our memory
16487c478bd9Sstevel@tonic-gate  * maps require.  We need to keep track of this so we can provide the proper
16497c478bd9Sstevel@tonic-gate  * access bits in the open/mmap/close/reboot/reopen case.
16507c478bd9Sstevel@tonic-gate  *
16517c478bd9Sstevel@tonic-gate  * 'os_failed_reopen' tells us that we failed to successfully reopen this
16527c478bd9Sstevel@tonic-gate  * open stream; therefore, we should not use this open stateid as it is
16537c478bd9Sstevel@tonic-gate  * not valid anymore. This flag is also used to indicate an unsuccessful
16547c478bd9Sstevel@tonic-gate  * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR.
16557c478bd9Sstevel@tonic-gate  *
16567c478bd9Sstevel@tonic-gate  * If 'os_orig_oo_name' is different than os_open_owner's oo_name
16577c478bd9Sstevel@tonic-gate  * then this tells us that this open stream's open owner used a
16587c478bd9Sstevel@tonic-gate  * bad seqid (that is, got NFS4ERR_BAD_SEQID).  If different, this open
16597c478bd9Sstevel@tonic-gate  * stream will no longer be used for future OTW state releasing calls.
16607c478bd9Sstevel@tonic-gate  *
16617c478bd9Sstevel@tonic-gate  * Lock ordering:
16627c478bd9Sstevel@tonic-gate  * rnode4_t::r_os_lock > os_sync_lock
16637c478bd9Sstevel@tonic-gate  * os_sync_lock > rnode4_t::r_statelock
16647c478bd9Sstevel@tonic-gate  * os_sync_lock > rnode4_t::r_statev4_lock
16657c478bd9Sstevel@tonic-gate  * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call)
16667c478bd9Sstevel@tonic-gate  *
16677c478bd9Sstevel@tonic-gate  * The 'os_sync_lock' protects:
16687c478bd9Sstevel@tonic-gate  *	open_stateid
16697c478bd9Sstevel@tonic-gate  *	os_dc_openacc
16707c478bd9Sstevel@tonic-gate  *	os_delegation
16717c478bd9Sstevel@tonic-gate  *	os_failed_reopen
16727c478bd9Sstevel@tonic-gate  *	os_final_close
16737c478bd9Sstevel@tonic-gate  *	os_force_close
16747c478bd9Sstevel@tonic-gate  *	os_mapcnt
16757c478bd9Sstevel@tonic-gate  *	os_mmap_read
16767c478bd9Sstevel@tonic-gate  *	os_mmap_write
16777c478bd9Sstevel@tonic-gate  *	os_open_ref_count
16787c478bd9Sstevel@tonic-gate  *	os_pending_close
16797c478bd9Sstevel@tonic-gate  *	os_share_acc_read
16807c478bd9Sstevel@tonic-gate  *	os_share_acc_write
16817c478bd9Sstevel@tonic-gate  *	os_share_deny_none
16827c478bd9Sstevel@tonic-gate  *	os_share_deny_read
16837c478bd9Sstevel@tonic-gate  *	os_share_deny_write
16847c478bd9Sstevel@tonic-gate  *	os_ref_count
16857c478bd9Sstevel@tonic-gate  *	os_valid
16867c478bd9Sstevel@tonic-gate  *
16877c478bd9Sstevel@tonic-gate  * The rnode4_t::r_os_lock protects:
16887c478bd9Sstevel@tonic-gate  *	os_node
16897c478bd9Sstevel@tonic-gate  *
16907c478bd9Sstevel@tonic-gate  * These fields are set at creation time and
16917c478bd9Sstevel@tonic-gate  * read only after that:
16927c478bd9Sstevel@tonic-gate  *	os_open_owner
16937c478bd9Sstevel@tonic-gate  *	os_orig_oo_name
16947c478bd9Sstevel@tonic-gate  */
16957c478bd9Sstevel@tonic-gate typedef struct nfs4_open_stream {
16967c478bd9Sstevel@tonic-gate 	uint64_t		os_share_acc_read;
16977c478bd9Sstevel@tonic-gate 	uint64_t		os_share_acc_write;
16987c478bd9Sstevel@tonic-gate 	uint64_t		os_mmap_read;
16997c478bd9Sstevel@tonic-gate 	uint64_t		os_mmap_write;
17007c478bd9Sstevel@tonic-gate 	uint32_t		os_share_deny_none;
17017c478bd9Sstevel@tonic-gate 	uint32_t		os_share_deny_read;
17027c478bd9Sstevel@tonic-gate 	uint32_t		os_share_deny_write;
17037c478bd9Sstevel@tonic-gate 	stateid4		open_stateid;
17047c478bd9Sstevel@tonic-gate 	int			os_dc_openacc;
17057c478bd9Sstevel@tonic-gate 	int			os_ref_count;
17067c478bd9Sstevel@tonic-gate 	unsigned		os_valid:1;
17077c478bd9Sstevel@tonic-gate 	unsigned 		os_delegation:1;
17087c478bd9Sstevel@tonic-gate 	unsigned		os_final_close:1;
17097c478bd9Sstevel@tonic-gate 	unsigned 		os_pending_close:1;
17107c478bd9Sstevel@tonic-gate 	unsigned 		os_failed_reopen:1;
17117c478bd9Sstevel@tonic-gate 	unsigned		os_force_close:1;
17127c478bd9Sstevel@tonic-gate 	int			os_open_ref_count;
17137c478bd9Sstevel@tonic-gate 	long			os_mapcnt;
17147c478bd9Sstevel@tonic-gate 	list_node_t		os_node;
17157c478bd9Sstevel@tonic-gate 	struct nfs4_open_owner	*os_open_owner;
17167c478bd9Sstevel@tonic-gate 	uint64_t		os_orig_oo_name;
17177c478bd9Sstevel@tonic-gate 	kmutex_t		os_sync_lock;
17187c478bd9Sstevel@tonic-gate } nfs4_open_stream_t;
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate /*
17217c478bd9Sstevel@tonic-gate  * This structure describes the format of the lock_owner_name
17227c478bd9Sstevel@tonic-gate  * field of the lock owner.
17237c478bd9Sstevel@tonic-gate  */
17247c478bd9Sstevel@tonic-gate 
17257c478bd9Sstevel@tonic-gate typedef struct nfs4_lo_name {
17267c478bd9Sstevel@tonic-gate 	uint64_t	ln_seq_num;
17277c478bd9Sstevel@tonic-gate 	pid_t		ln_pid;
17287c478bd9Sstevel@tonic-gate } nfs4_lo_name_t;
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate /*
17317c478bd9Sstevel@tonic-gate  * Flags for lo_flags.
17327c478bd9Sstevel@tonic-gate  */
17337c478bd9Sstevel@tonic-gate #define	NFS4_LOCK_SEQID_INUSE	0x1
17347c478bd9Sstevel@tonic-gate #define	NFS4_BAD_SEQID_LOCK	0x2
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate /*
17377c478bd9Sstevel@tonic-gate  * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs
17387c478bd9Sstevel@tonic-gate  * off the rnode.  If the links are NULL it means this object is not on the
17397c478bd9Sstevel@tonic-gate  * list.
17407c478bd9Sstevel@tonic-gate  *
17417c478bd9Sstevel@tonic-gate  * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and
17427c478bd9Sstevel@tonic-gate  * didn't get a response back.  This is used to figure out if we have
17437c478bd9Sstevel@tonic-gate  * possible remote v4 locks, so that we can clean up at process exit.  In
17447c478bd9Sstevel@tonic-gate  * theory, the client should be able to figure out if the server received
17457c478bd9Sstevel@tonic-gate  * the request (based on what seqid works), so maybe we can get rid of this
17467c478bd9Sstevel@tonic-gate  * flag someday.
17477c478bd9Sstevel@tonic-gate  *
17487c478bd9Sstevel@tonic-gate  * 'lo_ref_count' tells us how many processes/threads are using this data
17497c478bd9Sstevel@tonic-gate  * structure.  The rnode's list accounts for one reference.
17507c478bd9Sstevel@tonic-gate  *
17517c478bd9Sstevel@tonic-gate  * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the
17527c478bd9Sstevel@tonic-gate  * data structure.  It is then set to NFS4_PERM_CREATED when a lock request
17537c478bd9Sstevel@tonic-gate  * is successful using this lock owner structure.  We need to keep 'temporary'
17547c478bd9Sstevel@tonic-gate  * lock owners around so we can properly keep the lock seqid synchronization
17557c478bd9Sstevel@tonic-gate  * when multiple processes/threads are trying to create the lock owner for the
17567c478bd9Sstevel@tonic-gate  * first time (especially with the DENIED error case).  Once
17577c478bd9Sstevel@tonic-gate  * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change.
17587c478bd9Sstevel@tonic-gate  *
17597c478bd9Sstevel@tonic-gate  * 'lo_valid' tells us whether this structure is about to be freed or not,
17607c478bd9Sstevel@tonic-gate  * if it is then don't return it from find_lock_owner().
17617c478bd9Sstevel@tonic-gate  *
17627c478bd9Sstevel@tonic-gate  * Retrieving and setting of 'lock_seqid' is protected by the
17637c478bd9Sstevel@tonic-gate  * NFS4_LOCK_SEQID_INUSE flag.  Waiters for NFS4_LOCK_SEQID_INUSE should
17647c478bd9Sstevel@tonic-gate  * use 'lo_cv_seqid_sync'.
17657c478bd9Sstevel@tonic-gate  *
17667c478bd9Sstevel@tonic-gate  * The setting of 'lock_stateid' is protected by the
17677c478bd9Sstevel@tonic-gate  * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'.  The retrieving of the
17687c478bd9Sstevel@tonic-gate  * 'lock_stateid' is protected by 'lo_lock', with the additional
17697c478bd9Sstevel@tonic-gate  * requirement that the calling function can handle NFS4ERR_OLD_STATEID and
17707c478bd9Sstevel@tonic-gate  * NFS4ERR_BAD_STATEID as appropiate.
17717c478bd9Sstevel@tonic-gate  *
17727c478bd9Sstevel@tonic-gate  * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock
17737c478bd9Sstevel@tonic-gate  * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID).  With this set,
17747c478bd9Sstevel@tonic-gate  * this lock owner will no longer be used for future OTW calls.  Once set,
17757c478bd9Sstevel@tonic-gate  * it is never unset.
17767c478bd9Sstevel@tonic-gate  *
17777c478bd9Sstevel@tonic-gate  * Lock ordering:
17787c478bd9Sstevel@tonic-gate  * rnode4_t::r_statev4_lock > lo_lock
17797c478bd9Sstevel@tonic-gate  */
17807c478bd9Sstevel@tonic-gate typedef struct nfs4_lock_owner {
17817c478bd9Sstevel@tonic-gate 	struct nfs4_lock_owner	*lo_next_rnode;
17827c478bd9Sstevel@tonic-gate 	struct nfs4_lock_owner	*lo_prev_rnode;
17837c478bd9Sstevel@tonic-gate 	int			lo_pid;
17847c478bd9Sstevel@tonic-gate 	stateid4		lock_stateid;
17857c478bd9Sstevel@tonic-gate 	seqid4			lock_seqid;
17867c478bd9Sstevel@tonic-gate 	/*
17877c478bd9Sstevel@tonic-gate 	 * Fix this to always be 12 bytes
17887c478bd9Sstevel@tonic-gate 	 */
17897c478bd9Sstevel@tonic-gate 	nfs4_lo_name_t		lock_owner_name;
17907c478bd9Sstevel@tonic-gate 	int			lo_ref_count;
17917c478bd9Sstevel@tonic-gate 	int			lo_valid;
17927c478bd9Sstevel@tonic-gate 	int			lo_pending_rqsts;
17937c478bd9Sstevel@tonic-gate 	int			lo_just_created;
17947c478bd9Sstevel@tonic-gate 	int			lo_flags;
17957c478bd9Sstevel@tonic-gate 	kcondvar_t		lo_cv_seqid_sync;
17967c478bd9Sstevel@tonic-gate 	kmutex_t		lo_lock;
17977c478bd9Sstevel@tonic-gate 	kthread_t		*lo_seqid_holder; /* debugging aid */
17987c478bd9Sstevel@tonic-gate } nfs4_lock_owner_t;
17997c478bd9Sstevel@tonic-gate 
18007c478bd9Sstevel@tonic-gate /* for nfs4_lock_owner_t lookups */
18017c478bd9Sstevel@tonic-gate typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t;
18027c478bd9Sstevel@tonic-gate 
18037c478bd9Sstevel@tonic-gate /* Number of times to retry a call that fails with state independent error */
18047c478bd9Sstevel@tonic-gate #define	NFS4_NUM_RECOV_RETRIES	3
18057c478bd9Sstevel@tonic-gate 
18067c478bd9Sstevel@tonic-gate typedef enum {
18077c478bd9Sstevel@tonic-gate 	NO_SID,
18087c478bd9Sstevel@tonic-gate 	DEL_SID,
18097c478bd9Sstevel@tonic-gate 	LOCK_SID,
18107c478bd9Sstevel@tonic-gate 	OPEN_SID,
18117c478bd9Sstevel@tonic-gate 	SPEC_SID
18127c478bd9Sstevel@tonic-gate } nfs4_stateid_type_t;
18137c478bd9Sstevel@tonic-gate 
18147c478bd9Sstevel@tonic-gate typedef struct nfs4_stateid_types {
18157c478bd9Sstevel@tonic-gate 	stateid4 d_sid;
18167c478bd9Sstevel@tonic-gate 	stateid4 l_sid;
18177c478bd9Sstevel@tonic-gate 	stateid4 o_sid;
18187c478bd9Sstevel@tonic-gate 	nfs4_stateid_type_t cur_sid_type;
18197c478bd9Sstevel@tonic-gate } nfs4_stateid_types_t;
18207c478bd9Sstevel@tonic-gate 
18217c478bd9Sstevel@tonic-gate /*
18227c478bd9Sstevel@tonic-gate  * Per-zone data for dealing with callbacks.  Included here solely for the
18237c478bd9Sstevel@tonic-gate  * benefit of MDB.
18247c478bd9Sstevel@tonic-gate  */
18257c478bd9Sstevel@tonic-gate struct nfs4_callback_stats {
18267c478bd9Sstevel@tonic-gate 	kstat_named_t	delegations;
18277c478bd9Sstevel@tonic-gate 	kstat_named_t	cb_getattr;
18287c478bd9Sstevel@tonic-gate 	kstat_named_t	cb_recall;
18297c478bd9Sstevel@tonic-gate 	kstat_named_t	cb_null;
18307c478bd9Sstevel@tonic-gate 	kstat_named_t	cb_dispatch;
18317c478bd9Sstevel@tonic-gate 	kstat_named_t	delegaccept_r;
18327c478bd9Sstevel@tonic-gate 	kstat_named_t	delegaccept_rw;
18337c478bd9Sstevel@tonic-gate 	kstat_named_t	delegreturn;
18347c478bd9Sstevel@tonic-gate 	kstat_named_t	callbacks;
18357c478bd9Sstevel@tonic-gate 	kstat_named_t	claim_cur;
18367c478bd9Sstevel@tonic-gate 	kstat_named_t	claim_cur_ok;
18377c478bd9Sstevel@tonic-gate 	kstat_named_t	recall_trunc;
18387c478bd9Sstevel@tonic-gate 	kstat_named_t	recall_failed;
18397c478bd9Sstevel@tonic-gate 	kstat_named_t	return_limit_write;
18407c478bd9Sstevel@tonic-gate 	kstat_named_t	return_limit_addmap;
18417c478bd9Sstevel@tonic-gate 	kstat_named_t	deleg_recover;
18427c478bd9Sstevel@tonic-gate 	kstat_named_t	cb_illegal;
18437c478bd9Sstevel@tonic-gate };
18447c478bd9Sstevel@tonic-gate 
18457c478bd9Sstevel@tonic-gate struct nfs4_callback_globals {
18467c478bd9Sstevel@tonic-gate 	kmutex_t nfs4_cb_lock;
18477c478bd9Sstevel@tonic-gate 	kmutex_t nfs4_dlist_lock;
18487c478bd9Sstevel@tonic-gate 	int nfs4_program_hint;
18497c478bd9Sstevel@tonic-gate 	/* this table maps the program number to the nfs4_server structure */
18507c478bd9Sstevel@tonic-gate 	struct nfs4_server **nfs4prog2server;
18517c478bd9Sstevel@tonic-gate 	list_t nfs4_dlist;
18527c478bd9Sstevel@tonic-gate 	list_t nfs4_cb_ports;
18537c478bd9Sstevel@tonic-gate 	struct nfs4_callback_stats nfs4_callback_stats;
18547c478bd9Sstevel@tonic-gate #ifdef DEBUG
18557c478bd9Sstevel@tonic-gate 	int nfs4_dlistadd_c;
18567c478bd9Sstevel@tonic-gate 	int nfs4_dlistclean_c;
18577c478bd9Sstevel@tonic-gate #endif
18587c478bd9Sstevel@tonic-gate };
18597c478bd9Sstevel@tonic-gate 
18607c478bd9Sstevel@tonic-gate typedef enum {
18617c478bd9Sstevel@tonic-gate 	CLOSE_NORM,
18627c478bd9Sstevel@tonic-gate 	CLOSE_DELMAP,
18637c478bd9Sstevel@tonic-gate 	CLOSE_FORCE,
18647c478bd9Sstevel@tonic-gate 	CLOSE_RESEND,
18657c478bd9Sstevel@tonic-gate 	CLOSE_AFTER_RESEND
18667c478bd9Sstevel@tonic-gate } nfs4_close_type_t;
18677c478bd9Sstevel@tonic-gate 
18687c478bd9Sstevel@tonic-gate /*
18697c478bd9Sstevel@tonic-gate  * Structure to hold the bad seqid information that is passed
18707c478bd9Sstevel@tonic-gate  * to the recovery framework.
18717c478bd9Sstevel@tonic-gate  */
18727c478bd9Sstevel@tonic-gate typedef struct nfs4_bseqid_entry {
18737c478bd9Sstevel@tonic-gate 	nfs4_open_owner_t	*bs_oop;
18747c478bd9Sstevel@tonic-gate 	nfs4_lock_owner_t	*bs_lop;
18757c478bd9Sstevel@tonic-gate 	vnode_t			*bs_vp;
18767c478bd9Sstevel@tonic-gate 	pid_t			bs_pid;
18777c478bd9Sstevel@tonic-gate 	nfs4_tag_type_t		bs_tag;
18787c478bd9Sstevel@tonic-gate 	seqid4			bs_seqid;
18797c478bd9Sstevel@tonic-gate 	list_node_t		bs_node;
18807c478bd9Sstevel@tonic-gate } nfs4_bseqid_entry_t;
18817c478bd9Sstevel@tonic-gate 
18827c478bd9Sstevel@tonic-gate #ifdef _KERNEL
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate extern void	nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int,
18857c478bd9Sstevel@tonic-gate 		    nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t,
18867c478bd9Sstevel@tonic-gate 		    size_t, uint_t, uint_t);
18877c478bd9Sstevel@tonic-gate extern void	nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *);
18887c478bd9Sstevel@tonic-gate extern void	nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4);
18897c478bd9Sstevel@tonic-gate extern void	open_owner_hold(nfs4_open_owner_t *);
18907c478bd9Sstevel@tonic-gate extern void	open_owner_rele(nfs4_open_owner_t *);
18917c478bd9Sstevel@tonic-gate extern nfs4_open_stream_t	*find_or_create_open_stream(nfs4_open_owner_t *,
18927c478bd9Sstevel@tonic-gate 					struct rnode4 *, int *);
18937c478bd9Sstevel@tonic-gate extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *,
18947c478bd9Sstevel@tonic-gate 				struct rnode4 *);
18957c478bd9Sstevel@tonic-gate extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop,
18967c478bd9Sstevel@tonic-gate 				struct rnode4 *rp);
18977c478bd9Sstevel@tonic-gate extern void	open_stream_hold(nfs4_open_stream_t *);
18987c478bd9Sstevel@tonic-gate extern void	open_stream_rele(nfs4_open_stream_t *, struct rnode4 *);
18997c478bd9Sstevel@tonic-gate extern int	nfs4close_all(vnode_t *, cred_t *);
19007c478bd9Sstevel@tonic-gate extern void	lock_owner_hold(nfs4_lock_owner_t *);
19017c478bd9Sstevel@tonic-gate extern void	lock_owner_rele(nfs4_lock_owner_t *);
19027c478bd9Sstevel@tonic-gate extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t);
19037c478bd9Sstevel@tonic-gate extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t);
19047c478bd9Sstevel@tonic-gate extern void	nfs4_rnode_remove_lock_owner(struct rnode4 *,
19057c478bd9Sstevel@tonic-gate 			nfs4_lock_owner_t *);
19067c478bd9Sstevel@tonic-gate extern void	nfs4_flush_lock_owners(struct rnode4 *);
19077c478bd9Sstevel@tonic-gate extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t);
19087c478bd9Sstevel@tonic-gate extern void	nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *,
19097c478bd9Sstevel@tonic-gate 		    nfs4_tag_type_t);
19107c478bd9Sstevel@tonic-gate extern void	nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *);
19117c478bd9Sstevel@tonic-gate extern void	nfs4_get_and_set_next_open_seqid(nfs4_open_owner_t *,
19127c478bd9Sstevel@tonic-gate 		    nfs4_tag_type_t);
19137c478bd9Sstevel@tonic-gate extern void	nfs4_end_open_seqid_sync(nfs4_open_owner_t *);
19147c478bd9Sstevel@tonic-gate extern int	nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *);
19157c478bd9Sstevel@tonic-gate extern void	nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *);
19167c478bd9Sstevel@tonic-gate extern int	nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *);
19177c478bd9Sstevel@tonic-gate extern void	nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *,
19187c478bd9Sstevel@tonic-gate 			nfs4_open_stream_t *, clientid4, locker4 *);
19197c478bd9Sstevel@tonic-gate extern void	nfs4_destroy_open_owner(nfs4_open_owner_t *);
19207c478bd9Sstevel@tonic-gate 
19217c478bd9Sstevel@tonic-gate extern void		nfs4_renew_lease_thread(nfs4_server_t *);
19227c478bd9Sstevel@tonic-gate extern nfs4_server_t	*find_nfs4_server(mntinfo4_t *);
19237c478bd9Sstevel@tonic-gate extern nfs4_server_t	*find_nfs4_server_all(mntinfo4_t *, int all);
19247c478bd9Sstevel@tonic-gate extern nfs4_server_t	*new_nfs4_server(servinfo4_t *,	cred_t *);
19257c478bd9Sstevel@tonic-gate extern void		nfs4_mark_srv_dead(nfs4_server_t *);
19267c478bd9Sstevel@tonic-gate extern nfs4_server_t	*servinfo4_to_nfs4_server(servinfo4_t *);
19277c478bd9Sstevel@tonic-gate extern void		nfs4_inc_state_ref_count(mntinfo4_t *);
19287c478bd9Sstevel@tonic-gate extern void		nfs4_inc_state_ref_count_nolock(nfs4_server_t *,
19297c478bd9Sstevel@tonic-gate 				mntinfo4_t *);
19307c478bd9Sstevel@tonic-gate extern void		nfs4_dec_state_ref_count(mntinfo4_t *);
19317c478bd9Sstevel@tonic-gate extern void		nfs4_dec_state_ref_count_nolock(nfs4_server_t *,
19327c478bd9Sstevel@tonic-gate 				mntinfo4_t *);
19337c478bd9Sstevel@tonic-gate extern clientid4	mi2clientid(mntinfo4_t *);
19347c478bd9Sstevel@tonic-gate extern int		nfs4_server_in_recovery(nfs4_server_t *);
19357c478bd9Sstevel@tonic-gate extern bool_t		nfs4_server_vlock(nfs4_server_t *, int);
19367c478bd9Sstevel@tonic-gate extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *);
19377c478bd9Sstevel@tonic-gate extern uint64_t		nfs4_get_new_oo_name(void);
19387c478bd9Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *);
19397c478bd9Sstevel@tonic-gate extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *);
19407c478bd9Sstevel@tonic-gate extern void	nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *,
19417c478bd9Sstevel@tonic-gate 			int, u_offset_t, cred_t *, nfs4_error_t *,
19427c478bd9Sstevel@tonic-gate 			nfs4_lost_rqst_t *, int *);
19437c478bd9Sstevel@tonic-gate extern void	nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *,
19447c478bd9Sstevel@tonic-gate 		    nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *,
19457c478bd9Sstevel@tonic-gate 		    vnode_t *, int, int);
19467c478bd9Sstevel@tonic-gate extern void	nfs4_open_downgrade(int, int, nfs4_open_owner_t *,
19477c478bd9Sstevel@tonic-gate 		    nfs4_open_stream_t *, vnode_t *, cred_t *,
19487c478bd9Sstevel@tonic-gate 		    nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *);
19497c478bd9Sstevel@tonic-gate extern seqid4	nfs4_get_open_seqid(nfs4_open_owner_t *);
19507c478bd9Sstevel@tonic-gate extern cred_t	*nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *);
19517c478bd9Sstevel@tonic-gate extern void	nfs4_init_stateid_types(nfs4_stateid_types_t *);
19527c478bd9Sstevel@tonic-gate extern void	nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *);
19537c478bd9Sstevel@tonic-gate 
19547c478bd9Sstevel@tonic-gate extern kmutex_t nfs4_server_lst_lock;
19557c478bd9Sstevel@tonic-gate 
19567c478bd9Sstevel@tonic-gate extern void	nfs4callback_destroy(nfs4_server_t *);
19577c478bd9Sstevel@tonic-gate extern void	nfs4_callback_init(void);
19587c478bd9Sstevel@tonic-gate extern void	nfs4_callback_fini(void);
19597c478bd9Sstevel@tonic-gate extern void	nfs4_cb_args(nfs4_server_t *, struct knetconfig *,
19607c478bd9Sstevel@tonic-gate 			SETCLIENTID4args *);
19617c478bd9Sstevel@tonic-gate extern void	nfs4delegreturn_async(struct rnode4 *, int, bool_t);
19627c478bd9Sstevel@tonic-gate 
19637c478bd9Sstevel@tonic-gate extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy;
19647c478bd9Sstevel@tonic-gate 
19657c478bd9Sstevel@tonic-gate extern void	nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *);
19667c478bd9Sstevel@tonic-gate extern void	nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *);
19677c478bd9Sstevel@tonic-gate extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *);
19687c478bd9Sstevel@tonic-gate extern bool_t	nfs4_fs_active(nfs4_server_t *);
19697c478bd9Sstevel@tonic-gate extern void	nfs4_server_rele(nfs4_server_t *);
19707c478bd9Sstevel@tonic-gate extern bool_t	inlease(nfs4_server_t *);
19717c478bd9Sstevel@tonic-gate extern bool_t	nfs4_has_pages(vnode_t *);
19727c478bd9Sstevel@tonic-gate extern void	nfs4_log_badowner(mntinfo4_t *, nfs_opnum4);
19737c478bd9Sstevel@tonic-gate 
19747c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate /*
19777c478bd9Sstevel@tonic-gate  * Client State Recovery
19787c478bd9Sstevel@tonic-gate  */
19797c478bd9Sstevel@tonic-gate 
19807c478bd9Sstevel@tonic-gate /*
19817c478bd9Sstevel@tonic-gate  * The following defines are used for rs_flags in
19827c478bd9Sstevel@tonic-gate  * a nfs4_recov_state_t structure.
19837c478bd9Sstevel@tonic-gate  *
19847c478bd9Sstevel@tonic-gate  * NFS4_RS_RENAME_HELD		Indicates that the mi_rename_lock was held.
19857c478bd9Sstevel@tonic-gate  * NFS4_RS_GRACE_MSG		Set once we have uprintf'ed a grace message.
19867c478bd9Sstevel@tonic-gate  * NFS4_RS_DELAY_MSG		Set once we have uprintf'ed a delay message.
19877c478bd9Sstevel@tonic-gate  * NFS4_RS_RECALL_HELD1		r_deleg_recall_lock for vp1 was held.
19887c478bd9Sstevel@tonic-gate  * NFS4_RS_RECALL_HELD2		r_deleg_recall_lock for vp2 was held.
19897c478bd9Sstevel@tonic-gate  */
19907c478bd9Sstevel@tonic-gate #define	NFS4_RS_RENAME_HELD	0x000000001
19917c478bd9Sstevel@tonic-gate #define	NFS4_RS_GRACE_MSG	0x000000002
19927c478bd9Sstevel@tonic-gate #define	NFS4_RS_DELAY_MSG	0x000000004
19937c478bd9Sstevel@tonic-gate #define	NFS4_RS_RECALL_HELD1	0x000000008
19947c478bd9Sstevel@tonic-gate #define	NFS4_RS_RECALL_HELD2	0x000000010
19957c478bd9Sstevel@tonic-gate 
19967c478bd9Sstevel@tonic-gate /*
19977c478bd9Sstevel@tonic-gate  * Information that is retrieved from nfs4_start_op() and that is
19987c478bd9Sstevel@tonic-gate  * passed into nfs4_end_op().
19997c478bd9Sstevel@tonic-gate  *
20007c478bd9Sstevel@tonic-gate  * rs_sp is a reference to the nfs4_server that was found, or NULL.
20017c478bd9Sstevel@tonic-gate  *
20027c478bd9Sstevel@tonic-gate  * rs_num_retry_despite_err is the number times client retried an
20037c478bd9Sstevel@tonic-gate  * OTW op despite a recovery error.  It is only incremented for hints
20047c478bd9Sstevel@tonic-gate  * exempt to normal R4RECOVERR processing
20057c478bd9Sstevel@tonic-gate  * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN).  (XXX this special-case code
20067c478bd9Sstevel@tonic-gate  * needs review for possible removal.)
20077c478bd9Sstevel@tonic-gate  * It is initialized wherever nfs4_recov_state_t is declared -- usually
20087c478bd9Sstevel@tonic-gate  * very near initialization of rs_flags.
20097c478bd9Sstevel@tonic-gate  */
20107c478bd9Sstevel@tonic-gate typedef struct {
20117c478bd9Sstevel@tonic-gate 	nfs4_server_t	*rs_sp;
20127c478bd9Sstevel@tonic-gate 	int		rs_flags;
20137c478bd9Sstevel@tonic-gate 	int		rs_num_retry_despite_err;
20147c478bd9Sstevel@tonic-gate } nfs4_recov_state_t;
20157c478bd9Sstevel@tonic-gate 
20167c478bd9Sstevel@tonic-gate /*
20177c478bd9Sstevel@tonic-gate  * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root.
20187c478bd9Sstevel@tonic-gate  */
20197c478bd9Sstevel@tonic-gate 
20207c478bd9Sstevel@tonic-gate #define	NFS4_REMAP_CKATTRS	1
20217c478bd9Sstevel@tonic-gate #define	NFS4_REMAP_NEEDSOP	2
20227c478bd9Sstevel@tonic-gate 
20237c478bd9Sstevel@tonic-gate #ifdef _KERNEL
20247c478bd9Sstevel@tonic-gate 
20257c478bd9Sstevel@tonic-gate extern int	nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int,
20267c478bd9Sstevel@tonic-gate 			vnode_t *, int, int *, int, nfs4_recov_state_t *);
20277c478bd9Sstevel@tonic-gate extern void	nfs4setclientid(struct mntinfo4 *, struct cred *, bool_t,
20287c478bd9Sstevel@tonic-gate 			nfs4_error_t *);
20297c478bd9Sstevel@tonic-gate extern void	nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *,
20307c478bd9Sstevel@tonic-gate 			open_claim_type4, bool_t, bool_t);
20317c478bd9Sstevel@tonic-gate extern void	nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int);
20327c478bd9Sstevel@tonic-gate extern void	nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int,
20337c478bd9Sstevel@tonic-gate 			nfs4_error_t *);
20347c478bd9Sstevel@tonic-gate extern void	nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int,
20357c478bd9Sstevel@tonic-gate 			nfs4_error_t *);
20367c478bd9Sstevel@tonic-gate extern int	nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t,
20377c478bd9Sstevel@tonic-gate 			vnode_t *, cred_t *, vnode_t **, int);
20387c478bd9Sstevel@tonic-gate extern void	nfs4_fail_recov(vnode_t *, char *, int, nfsstat4);
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate extern int	nfs4_needs_recovery(nfs4_error_t *, bool_t, vfs_t *);
20417c478bd9Sstevel@tonic-gate extern int	nfs4_recov_marks_dead(nfsstat4);
20427c478bd9Sstevel@tonic-gate extern bool_t	nfs4_start_recovery(nfs4_error_t *, struct mntinfo4 *,
20437c478bd9Sstevel@tonic-gate 			vnode_t *, vnode_t *, stateid4 *,
20442f172c55SRobert Thurlow 			nfs4_lost_rqst_t *, nfs_opnum4, nfs4_bseqid_entry_t *,
20452f172c55SRobert Thurlow 			vnode_t *, char *);
20467c478bd9Sstevel@tonic-gate extern int	nfs4_start_op(struct mntinfo4 *, vnode_t *, vnode_t *,
20477c478bd9Sstevel@tonic-gate 			nfs4_recov_state_t *);
20487c478bd9Sstevel@tonic-gate extern void	nfs4_end_op(struct mntinfo4 *, vnode_t *, vnode_t *,
20497c478bd9Sstevel@tonic-gate 			nfs4_recov_state_t *, bool_t);
20507c478bd9Sstevel@tonic-gate extern int	nfs4_start_fop(struct mntinfo4 *, vnode_t *, vnode_t *,
20517c478bd9Sstevel@tonic-gate 			nfs4_op_hint_t, nfs4_recov_state_t *, bool_t *);
20527c478bd9Sstevel@tonic-gate extern void	nfs4_end_fop(struct mntinfo4 *, vnode_t *, vnode_t *,
20537c478bd9Sstevel@tonic-gate 				nfs4_op_hint_t, nfs4_recov_state_t *, bool_t);
20547c478bd9Sstevel@tonic-gate extern char	*nfs4_recov_action_to_str(nfs4_recov_t);
20557c478bd9Sstevel@tonic-gate 
2056b9238976Sth /*
2057b9238976Sth  * In sequence, code desiring to unmount an ephemeral tree must
2058b9238976Sth  * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate,
2059b9238976Sth  * and nfs4_ephemeral_umount_unlock. The _unlock must also be
2060b9238976Sth  * called on all error paths that occur before it would naturally
2061b9238976Sth  * be invoked.
2062b9238976Sth  *
2063b9238976Sth  * The caller must also provde a pointer to a boolean to keep track
2064b9238976Sth  * of whether or not the code in _unlock is to be ran.
2065b9238976Sth  */
2066b9238976Sth extern void	nfs4_ephemeral_umount_activate(mntinfo4_t *,
20672f172c55SRobert Thurlow     bool_t *, nfs4_ephemeral_tree_t **);
2068b9238976Sth extern int	nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *,
20692f172c55SRobert Thurlow     bool_t *, nfs4_ephemeral_tree_t **);
20702f172c55SRobert Thurlow extern void	nfs4_ephemeral_umount_unlock(bool_t *,
2071b9238976Sth     nfs4_ephemeral_tree_t **);
2072b9238976Sth 
2073d3a14591SThomas Haynes extern int	nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp);
2074b9238976Sth 
20752f172c55SRobert Thurlow extern int	nfs4_callmapid(utf8string *, struct nfs_fsl_info *);
20762f172c55SRobert Thurlow extern int	nfs4_fetch_locations(mntinfo4_t *, struct nfs4_sharedfh *,
20772f172c55SRobert Thurlow     char *, cred_t *, nfs4_ga_res_t *, COMPOUND4res_clnt *, bool_t);
20782f172c55SRobert Thurlow 
20797c478bd9Sstevel@tonic-gate extern int	wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t,
20807c478bd9Sstevel@tonic-gate 			nfs4_recov_state_t *);
20817c478bd9Sstevel@tonic-gate extern void	nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *);
20827c478bd9Sstevel@tonic-gate extern void	nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t,
20837c478bd9Sstevel@tonic-gate 		    int, nfsstat4);
20847c478bd9Sstevel@tonic-gate extern time_t	nfs4err_delay_time;
20857c478bd9Sstevel@tonic-gate extern void	nfs4_set_grace_wait(mntinfo4_t *);
20867c478bd9Sstevel@tonic-gate extern void	nfs4_set_delay_wait(vnode_t *);
20877c478bd9Sstevel@tonic-gate extern int	nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *);
20887c478bd9Sstevel@tonic-gate extern int	nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *);
20897c478bd9Sstevel@tonic-gate extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *,
20907c478bd9Sstevel@tonic-gate 		    nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t,
20917c478bd9Sstevel@tonic-gate 		    seqid4);
20927c478bd9Sstevel@tonic-gate 
20937c478bd9Sstevel@tonic-gate extern void	nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *,
20947c478bd9Sstevel@tonic-gate 			nfs4_error_t *);
20957c478bd9Sstevel@tonic-gate extern void	nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *,
20967c478bd9Sstevel@tonic-gate 			nfs4_server_t *);
20977c478bd9Sstevel@tonic-gate extern int	nfs4_rpc_retry_error(int);
20987c478bd9Sstevel@tonic-gate extern int	nfs4_try_failover(nfs4_error_t *);
20997c478bd9Sstevel@tonic-gate extern void	nfs4_free_msg(nfs4_debug_msg_t *);
21007c478bd9Sstevel@tonic-gate extern void	nfs4_mnt_recov_kstat_init(vfs_t *);
21017c478bd9Sstevel@tonic-gate extern void	nfs4_mi_kstat_inc_delay(mntinfo4_t *);
21027c478bd9Sstevel@tonic-gate extern void	nfs4_mi_kstat_inc_no_grace(mntinfo4_t *);
21037c478bd9Sstevel@tonic-gate extern char	*nfs4_stat_to_str(nfsstat4);
21047c478bd9Sstevel@tonic-gate extern char	*nfs4_op_to_str(nfs_opnum4);
21057c478bd9Sstevel@tonic-gate 
21067c478bd9Sstevel@tonic-gate extern void	nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *,
21077c478bd9Sstevel@tonic-gate 		    uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t,
21087c478bd9Sstevel@tonic-gate 		    nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4);
21097c478bd9Sstevel@tonic-gate extern void	nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4,
21107c478bd9Sstevel@tonic-gate 		    nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *);
21117c478bd9Sstevel@tonic-gate #pragma	rarely_called(nfs4_queue_event)
21127c478bd9Sstevel@tonic-gate #pragma	rarely_called(nfs4_queue_fact)
21137c478bd9Sstevel@tonic-gate 
21147c478bd9Sstevel@tonic-gate /* Used for preformed "." and ".." dirents */
21157c478bd9Sstevel@tonic-gate extern char	*nfs4_dot_entries;
21167c478bd9Sstevel@tonic-gate extern char	*nfs4_dot_dot_entry;
21177c478bd9Sstevel@tonic-gate 
21187c478bd9Sstevel@tonic-gate #ifdef	DEBUG
21197c478bd9Sstevel@tonic-gate extern uint_t	nfs4_tsd_key;
21207c478bd9Sstevel@tonic-gate #endif
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
21237c478bd9Sstevel@tonic-gate 
21247c478bd9Sstevel@tonic-gate /*
21257c478bd9Sstevel@tonic-gate  * Filehandle management.
21267c478bd9Sstevel@tonic-gate  *
21277c478bd9Sstevel@tonic-gate  * Filehandles can change in v4, so rather than storing the filehandle
21287c478bd9Sstevel@tonic-gate  * directly in the rnode, etc., we manage the filehandle through one of
21297c478bd9Sstevel@tonic-gate  * these objects.
21307c478bd9Sstevel@tonic-gate  * Locking: sfh_fh and sfh_tree is protected by the filesystem's
21317c478bd9Sstevel@tonic-gate  * mi_fh_lock.  The reference count and flags are protected by sfh_lock.
21327c478bd9Sstevel@tonic-gate  * sfh_mi is read-only.
21337c478bd9Sstevel@tonic-gate  *
21347c478bd9Sstevel@tonic-gate  * mntinfo4_t::mi_fh_lock > sfh_lock.
21357c478bd9Sstevel@tonic-gate  */
21367c478bd9Sstevel@tonic-gate 
21377c478bd9Sstevel@tonic-gate typedef struct nfs4_sharedfh {
21387c478bd9Sstevel@tonic-gate 	nfs_fh4 sfh_fh;			/* key and current filehandle */
21397c478bd9Sstevel@tonic-gate 	kmutex_t sfh_lock;
21407c478bd9Sstevel@tonic-gate 	uint_t sfh_refcnt;		/* reference count */
21417c478bd9Sstevel@tonic-gate 	uint_t sfh_flags;
21427c478bd9Sstevel@tonic-gate 	mntinfo4_t *sfh_mi;		/* backptr to filesystem */
21437c478bd9Sstevel@tonic-gate 	avl_node_t sfh_tree;		/* used by avl package */
21447c478bd9Sstevel@tonic-gate } nfs4_sharedfh_t;
21457c478bd9Sstevel@tonic-gate 
21467c478bd9Sstevel@tonic-gate #define	SFH4_SAME(sfh1, sfh2)	((sfh1) == (sfh2))
21477c478bd9Sstevel@tonic-gate 
21487c478bd9Sstevel@tonic-gate /*
21497c478bd9Sstevel@tonic-gate  * Flags.
21507c478bd9Sstevel@tonic-gate  */
21517c478bd9Sstevel@tonic-gate #define	SFH4_IN_TREE	0x1		/* currently in an AVL tree */
21527c478bd9Sstevel@tonic-gate 
21537c478bd9Sstevel@tonic-gate #ifdef _KERNEL
21547c478bd9Sstevel@tonic-gate 
21557c478bd9Sstevel@tonic-gate extern void sfh4_createtab(avl_tree_t *);
21567c478bd9Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *);
21577c478bd9Sstevel@tonic-gate extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *,
21587c478bd9Sstevel@tonic-gate 				nfs4_sharedfh_t *);
21597c478bd9Sstevel@tonic-gate extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *);
21607c478bd9Sstevel@tonic-gate extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *);
21617c478bd9Sstevel@tonic-gate extern void sfh4_hold(nfs4_sharedfh_t *);
21627c478bd9Sstevel@tonic-gate extern void sfh4_rele(nfs4_sharedfh_t **);
21637c478bd9Sstevel@tonic-gate extern void sfh4_printfhandle(const nfs4_sharedfh_t *);
21647c478bd9Sstevel@tonic-gate 
21657c478bd9Sstevel@tonic-gate #endif
21667c478bd9Sstevel@tonic-gate 
21677c478bd9Sstevel@tonic-gate /*
21687c478bd9Sstevel@tonic-gate  * Path and file name management.
21697c478bd9Sstevel@tonic-gate  *
21707c478bd9Sstevel@tonic-gate  * This type stores the name of an entry in the filesystem and keeps enough
21717c478bd9Sstevel@tonic-gate  * information that it can provide a complete path.  All fields are
21727c478bd9Sstevel@tonic-gate  * protected by fn_lock, except for the reference count, which is managed
21737c478bd9Sstevel@tonic-gate  * using atomic add/subtract.
21747c478bd9Sstevel@tonic-gate  *
2175bbf2a467SNagakiran Rajashekar  * Additionally shared filehandle for this fname is stored.
2176bbf2a467SNagakiran Rajashekar  * Normally, fn_get() when it creates this fname stores the passed in
2177bbf2a467SNagakiran Rajashekar  * shared fh in fn_sfh by doing sfh_hold. Similarly the path which
2178bbf2a467SNagakiran Rajashekar  * destroys this fname releases the reference on this fh by doing sfh_rele.
2179bbf2a467SNagakiran Rajashekar  *
2180bbf2a467SNagakiran Rajashekar  * fn_get uses the fn_sfh to refine the comparision in cases
2181bbf2a467SNagakiran Rajashekar  * where we have matched the name but have differing file handles,
2182bbf2a467SNagakiran Rajashekar  * this normally happens due to
2183bbf2a467SNagakiran Rajashekar  *
2184bbf2a467SNagakiran Rajashekar  *	1. Server side rename of a file/directory.
2185bbf2a467SNagakiran Rajashekar  *	2. Another client renaming a file/directory on the server.
2186bbf2a467SNagakiran Rajashekar  *
2187bbf2a467SNagakiran Rajashekar  * Differing names but same filehandle is possible as in the case of hardlinks,
2188bbf2a467SNagakiran Rajashekar  * but differing filehandles with same name component will later confuse
2189bbf2a467SNagakiran Rajashekar  * the client and can cause various panics.
2190bbf2a467SNagakiran Rajashekar  *
21917c478bd9Sstevel@tonic-gate  * Lock order: child and then parent.
21927c478bd9Sstevel@tonic-gate  */
21937c478bd9Sstevel@tonic-gate 
21947c478bd9Sstevel@tonic-gate typedef struct nfs4_fname {
21957c478bd9Sstevel@tonic-gate 	struct nfs4_fname *fn_parent;	/* parent name; null if fs root */
21967c478bd9Sstevel@tonic-gate 	char *fn_name;			/* the actual name */
21977c478bd9Sstevel@tonic-gate 	ssize_t fn_len;			/* strlen(fn_name) */
21987c478bd9Sstevel@tonic-gate 	uint32_t fn_refcnt;		/* reference count */
21997c478bd9Sstevel@tonic-gate 	kmutex_t fn_lock;
22007c478bd9Sstevel@tonic-gate 	avl_node_t fn_tree;
22017c478bd9Sstevel@tonic-gate 	avl_tree_t fn_children;		/* children, if any */
2202be6d98b1SNagakiran Rajashekar 	nfs4_sharedfh_t *fn_sfh;	/* The fh for this fname */
22037c478bd9Sstevel@tonic-gate } nfs4_fname_t;
22047c478bd9Sstevel@tonic-gate 
22057c478bd9Sstevel@tonic-gate #ifdef _KERNEL
22067c478bd9Sstevel@tonic-gate 
22077c478bd9Sstevel@tonic-gate extern vnode_t	nfs4_xattr_notsupp_vnode;
22087c478bd9Sstevel@tonic-gate #define	NFS4_XATTR_DIR_NOTSUPP	&nfs4_xattr_notsupp_vnode
22097c478bd9Sstevel@tonic-gate 
2210bbf2a467SNagakiran Rajashekar extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *, nfs4_sharedfh_t *);
22117c478bd9Sstevel@tonic-gate extern void fn_hold(nfs4_fname_t *);
22127c478bd9Sstevel@tonic-gate extern void fn_rele(nfs4_fname_t **);
22137c478bd9Sstevel@tonic-gate extern char *fn_name(nfs4_fname_t *);
22147c478bd9Sstevel@tonic-gate extern char *fn_path(nfs4_fname_t *);
22157c478bd9Sstevel@tonic-gate extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *);
22167c478bd9Sstevel@tonic-gate extern nfs4_fname_t *fn_parent(nfs4_fname_t *);
22177c478bd9Sstevel@tonic-gate 
22182f172c55SRobert Thurlow /* Referral Support */
22192f172c55SRobert Thurlow extern int nfs4_process_referral(mntinfo4_t *, nfs4_sharedfh_t *, char *,
22202f172c55SRobert Thurlow     cred_t *, nfs4_ga_res_t *, COMPOUND4res_clnt *, struct nfs_fsl_info *);
22212f172c55SRobert Thurlow 
22227c478bd9Sstevel@tonic-gate #endif
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate /*
22257c478bd9Sstevel@tonic-gate  * Per-zone data for managing client handles, included in this file for the
22267c478bd9Sstevel@tonic-gate  * benefit of MDB.
22277c478bd9Sstevel@tonic-gate  */
22287c478bd9Sstevel@tonic-gate struct nfs4_clnt {
22297c478bd9Sstevel@tonic-gate 	struct chhead	*nfscl_chtable4;
22307c478bd9Sstevel@tonic-gate 	kmutex_t	nfscl_chtable4_lock;
22317c478bd9Sstevel@tonic-gate 	zoneid_t	nfscl_zoneid;
22327c478bd9Sstevel@tonic-gate 	list_node_t	nfscl_node;
22337c478bd9Sstevel@tonic-gate 	struct clstat4	nfscl_stat;
22347c478bd9Sstevel@tonic-gate };
22357c478bd9Sstevel@tonic-gate 
22367c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
22377c478bd9Sstevel@tonic-gate }
22387c478bd9Sstevel@tonic-gate #endif
22397c478bd9Sstevel@tonic-gate 
22407c478bd9Sstevel@tonic-gate #endif /* _NFS4_CLNT_H */
2241