Home | History | Annotate | Download | only in nfs
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
     27 /*	All Rights Reserved   */
     28 
     29 /*
     30  * Portions of this source code were derived from Berkeley 4.3 BSD
     31  * under license from the Regents of the University of California.
     32  */
     33 
     34 #ifndef _NFS4_CLNT_H
     35 #define	_NFS4_CLNT_H
     36 
     37 #include <sys/errno.h>
     38 #include <sys/types.h>
     39 #include <sys/kstat.h>
     40 #include <sys/time.h>
     41 #include <sys/flock.h>
     42 #include <vm/page.h>
     43 #include <nfs/nfs4_kprot.h>
     44 #include <nfs/nfs4.h>
     45 #include <nfs/rnode.h>
     46 #include <sys/avl.h>
     47 #include <sys/list.h>
     48 #include <rpc/auth.h>
     49 #include <sys/taskq.h>
     50 
     51 #ifdef	__cplusplus
     52 extern "C" {
     53 #endif
     54 
     55 #define	NFS4_SIZE_OK(size)	((size) <= MAXOFFSET_T)
     56 
     57 /* Client Sequence Heartbeat Flag bits */
     58 #define	NFS4_SEQHB_STARTED		1
     59 #define	NFS4_SEQHB_EXITING		2
     60 #define	NFS4_SEQHB_EXIT			4
     61 #define	NFS4_SEQHB_DESTROY_INZONE	8
     62 
     63 /* Four states of nfs4_server's lease_valid */
     64 #define	NFS4_LEASE_INVALID		0
     65 #define	NFS4_LEASE_VALID		1
     66 #define	NFS4_LEASE_UNINITIALIZED	2
     67 #define	NFS4_LEASE_NOT_STARTED		3
     68 
     69 /*
     70  * rfs4call() flags
     71  * NOTE: rfscall() can take RFSCALL_SOFT which is defined as 1 so start at 2
     72  */
     73 #define	RFS4CALL_SETCB	0x00000002
     74 #define	RFS4CALL_NOSEQ	0x00000004	/* Don't add sequence op (4.1+ only) */
     75 #define	RFS4CALL_FORCE	0x00000008	/* Force OTW, even if unmounted */
     76 #define	RFS4CALL_SHOLD	0x00000010	/* hold slot for caller  to release */
     77 
     78 #define	NFS4_TAG_SWAP		0x001
     79 #define	NFS4_TAG_DESTROY	0x002
     80 #define	NFS4_CBSERVER_CLEANUP	0x004
     81 
     82 /* flag to tell the renew thread it should exit */
     83 #define	NFS4_THREAD_EXIT	1
     84 
     85 /* Default number of seconds to wait on GRACE and DELAY errors */
     86 #define	NFS4ERR_DELAY_TIME	10
     87 
     88 /* Number of hash buckets for open owners for each nfs4_server */
     89 #define	NFS4_NUM_OO_BUCKETS	53
     90 
     91 /* Number of freed open owners (per mntinfo4_t) to keep around */
     92 #define	NFS4_NUM_FREED_OPEN_OWNERS	8
     93 
     94 /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */
     95 #define	NFS4_RETRY_SCLID_DELAY	10
     96 
     97 /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */
     98 #define	NFS4_NUM_SCLID_RETRIES	3
     99 
    100 /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */
    101 #define	NFS4_NUM_RETRY_BAD_SEQID	3
    102 
    103 /*
    104  * Is the attribute cache valid?  If client holds a delegation, then attrs
    105  * are by definition valid.  If not, then check to see if attrs have timed out.
    106  */
    107 #define	ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \
    108 	gethrtime() < VTOR4(vp)->r_time_attr_inval)
    109 
    110 /*
    111  * Flags to indicate whether to purge the DNLC for non-directory vnodes
    112  * in a call to nfs_purge_caches.
    113  */
    114 #define	NFS4_NOPURGE_DNLC	0
    115 #define	NFS4_PURGE_DNLC		1
    116 
    117 /*
    118  * Is cache valid?
    119  * Swap is always valid, if no attributes (attrtime == 0) or
    120  * if mtime matches cached mtime it is valid
    121  * NOTE: mtime is now a timestruc_t.
    122  * Caller should be holding the rnode r_statelock mutex.
    123  */
    124 #define	CACHE4_VALID(rp, mtime, fsize)				\
    125 	((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP ||		\
    126 	(((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec &&	\
    127 	(mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) &&	\
    128 	((fsize) == (rp)->r_attr.va_size)))
    129 
    130 /*
    131  * Macro to detect forced unmount or a zone shutdown.
    132  */
    133 #define	FS_OR_ZONE_GONE4(vfsp) \
    134 	(((vfsp)->vfs_flag & VFS_UNMOUNTED) || \
    135 	zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN)
    136 
    137 /*
    138  * Macro to help determine whether a request failed because the underlying
    139  * filesystem has been forcibly unmounted or because of zone shutdown.
    140  */
    141 #define	NFS4_FRC_UNMT_ERR(err, vfsp) \
    142 	((err) == EIO && FS_OR_ZONE_GONE4((vfsp)))
    143 
    144 
    145 /*
    146  * Returns TRUE if there are sessions related recoverable errors
    147  */
    148 #define	NFS4_NEED_SESS_RECOV(np) \
    149 	    (!(np->s_flags & N4S_SESSION_CREATED) || \
    150 	    (np->s_flags & N4S_NEED_BC2S))
    151 
    152 #define	NFS41_SERVER(np) (np->s_minorversion == 1)
    153 
    154 /*
    155  * Client zone key for global zone list of callback info.
    156  */
    157 zone_key_t nfs4clnt_zone_key;
    158 
    159 /*
    160  * Due to the way the address space callbacks are used to execute a delmap,
    161  * we must keep track of how many times the same thread has called
    162  * VOP_DELMAP()->nfs4_delmap().  This is done by having a list of
    163  * nfs4_delmapcall_t's associated with each rnode4_t.  This list is protected
    164  * by the rnode4_t's r_statelock.  The individual elements do not need to be
    165  * protected as they will only ever be created, modified and destroyed by
    166  * one thread (the call_id).
    167  * See nfs4_delmap() for further explanation.
    168  */
    169 typedef struct nfs4_delmapcall {
    170 	kthread_t	*call_id;
    171 	int		error;	/* error from delmap */
    172 	list_node_t	call_node;
    173 } nfs4_delmapcall_t;
    174 
    175 /*
    176  * delmap address space callback args
    177  */
    178 typedef struct nfs4_delmap_args {
    179 	vnode_t			*vp;
    180 	offset_t		off;
    181 	caddr_t			addr;
    182 	size_t			len;
    183 	uint_t			prot;
    184 	uint_t			maxprot;
    185 	uint_t			flags;
    186 	cred_t			*cr;
    187 	nfs4_delmapcall_t	*caller; /* to retrieve errors from the cb */
    188 } nfs4_delmap_args_t;
    189 
    190 /*
    191  * client side statistics
    192  */
    193 /*
    194  * Per-zone counters
    195  */
    196 struct clstat4 {
    197 	kstat_named_t	calls;			/* client requests */
    198 	kstat_named_t	badcalls;		/* rpc failures */
    199 	kstat_named_t	clgets;			/* client handle gets */
    200 	kstat_named_t	cltoomany;		/* client handle cache misses */
    201 };
    202 
    203 #ifdef DEBUG
    204 /*
    205  * The following are statistics that describe the behavior of the system as a
    206  * whole and don't correspond to any particular zone.
    207  */
    208 struct clstat4_debug {
    209 	kstat_named_t	clalloc;		/* number of client handles */
    210 	kstat_named_t	noresponse;		/* server not responding cnt */
    211 	kstat_named_t	failover;		/* server failover count */
    212 	kstat_named_t	remap;			/* server remap count */
    213 	kstat_named_t	nrnode;			/* number of allocated rnodes */
    214 	kstat_named_t	access;			/* size of access cache */
    215 	kstat_named_t	dirent;			/* size of readdir cache */
    216 	kstat_named_t	dirents;		/* size of readdir buf cache */
    217 	kstat_named_t	reclaim;		/* number of reclaims */
    218 	kstat_named_t	clreclaim;		/* number of cl reclaims */
    219 	kstat_named_t	f_reclaim;		/* number of free reclaims */
    220 	kstat_named_t	a_reclaim;		/* number of active reclaims */
    221 	kstat_named_t	r_reclaim;		/* number of rnode reclaims */
    222 	kstat_named_t	rpath;			/* bytes used to store rpaths */
    223 };
    224 extern struct clstat4_debug clstat4_debug;
    225 
    226 #endif
    227 
    228 /*
    229  * The NFS specific async_reqs structure.
    230  */
    231 
    232 enum iotype4 {
    233 	NFS4_READ_AHEAD,
    234 	NFS4_PUTAPAGE,
    235 	NFS4_PAGEIO,
    236 	NFS4_READDIR,
    237 	NFS4_INACTIVE,
    238 	NFS4_COMMIT
    239 };
    240 #define	NFS4_ASYNC_TYPES	(NFS4_COMMIT + 1)
    241 
    242 struct nfs4_async_read_req {
    243 	void (*readahead)();		/* pointer to readahead function */
    244 	u_offset_t blkoff;		/* offset in file */
    245 	struct seg *seg;		/* segment to do i/o to */
    246 	caddr_t addr;			/* address to do i/o to */
    247 };
    248 
    249 struct nfs4_pageio_req {
    250 	int (*pageio)();		/* pointer to pageio function */
    251 	page_t *pp;			/* page list */
    252 	u_offset_t io_off;		/* offset in file */
    253 	uint_t io_len;			/* size of request */
    254 	int flags;
    255 };
    256 
    257 struct nfs4_readdir_req {
    258 	int (*readdir)();		/* pointer to readdir function */
    259 	struct rddir4_cache *rdc;	/* pointer to cache entry to fill */
    260 };
    261 
    262 struct nfs4_commit_req {
    263 	void (*commit)();		/* pointer to commit function */
    264 	page_t *plist;			/* page list */
    265 	offset4 offset;			/* starting offset */
    266 	count4 count;			/* size of range to be commited */
    267 };
    268 
    269 struct nfs4_async_reqs {
    270 	struct nfs4_async_reqs *a_next;	/* pointer to next arg struct */
    271 #ifdef DEBUG
    272 	kthread_t *a_queuer;		/* thread id of queueing thread */
    273 #endif
    274 	struct vnode *a_vp;		/* vnode pointer */
    275 	struct cred *a_cred;		/* cred pointer */
    276 	enum iotype4 a_io;		/* i/o type */
    277 	union {
    278 		struct nfs4_async_read_req a_read_args;
    279 		struct nfs4_pageio_req a_pageio_args;
    280 		struct nfs4_readdir_req a_readdir_args;
    281 		struct nfs4_commit_req a_commit_args;
    282 	} a_args;
    283 };
    284 
    285 #define	a_nfs4_readahead a_args.a_read_args.readahead
    286 #define	a_nfs4_blkoff a_args.a_read_args.blkoff
    287 #define	a_nfs4_seg a_args.a_read_args.seg
    288 #define	a_nfs4_addr a_args.a_read_args.addr
    289 
    290 #define	a_nfs4_putapage a_args.a_pageio_args.pageio
    291 #define	a_nfs4_pageio a_args.a_pageio_args.pageio
    292 #define	a_nfs4_pp a_args.a_pageio_args.pp
    293 #define	a_nfs4_off a_args.a_pageio_args.io_off
    294 #define	a_nfs4_len a_args.a_pageio_args.io_len
    295 #define	a_nfs4_flags a_args.a_pageio_args.flags
    296 
    297 #define	a_nfs4_readdir a_args.a_readdir_args.readdir
    298 #define	a_nfs4_rdc a_args.a_readdir_args.rdc
    299 
    300 #define	a_nfs4_commit a_args.a_commit_args.commit
    301 #define	a_nfs4_plist a_args.a_commit_args.plist
    302 #define	a_nfs4_offset a_args.a_commit_args.offset
    303 #define	a_nfs4_count a_args.a_commit_args.count
    304 
    305 /*
    306  * Security information
    307  */
    308 typedef struct sv_secinfo {
    309 	uint_t		count;	/* how many sdata there are */
    310 	uint_t		index;	/* which sdata[index] */
    311 	struct sec_data	*sdata;
    312 } sv_secinfo_t;
    313 
    314 /*
    315  * Hash bucket for the mi's open owner list (mi_oo_list).
    316  */
    317 typedef struct nfs4_oo_hash_bucket {
    318 	list_t			b_oo_hash_list;
    319 	kmutex_t		b_lock;
    320 } nfs4_oo_hash_bucket_t;
    321 
    322 /*
    323  * Global array of ctags.
    324  */
    325 extern ctag_t nfs4_ctags[];
    326 
    327 typedef enum nfs4_tag_type {
    328 	TAG_NONE,
    329 	TAG_ACCESS,
    330 	TAG_CLOSE,
    331 	TAG_CLOSE_LOST,
    332 	TAG_CLOSE_UNDO,
    333 	TAG_COMMIT,
    334 	TAG_DELEGRETURN,
    335 	TAG_FSINFO,
    336 	TAG_GET_SYMLINK,
    337 	TAG_GETATTR,
    338 	TAG_INACTIVE,
    339 	TAG_LINK,
    340 	TAG_LOCK,
    341 	TAG_LOCK_RECLAIM,
    342 	TAG_LOCK_RESEND,
    343 	TAG_LOCK_REINSTATE,
    344 	TAG_LOCK_UNKNOWN,
    345 	TAG_LOCKT,
    346 	TAG_LOCKU,
    347 	TAG_LOCKU_RESEND,
    348 	TAG_LOCKU_REINSTATE,
    349 	TAG_LOOKUP,
    350 	TAG_LOOKUP_PARENT,
    351 	TAG_LOOKUP_VALID,
    352 	TAG_LOOKUP_VPARENT,
    353 	TAG_MKDIR,
    354 	TAG_MKNOD,
    355 	TAG_MOUNT,
    356 	TAG_OPEN,
    357 	TAG_OPEN_CONFIRM,
    358 	TAG_OPEN_CONFIRM_LOST,
    359 	TAG_OPEN_DG,
    360 	TAG_OPEN_DG_LOST,
    361 	TAG_OPEN_LOST,
    362 	TAG_OPENATTR,
    363 	TAG_PATHCONF,
    364 	TAG_PUTROOTFH,
    365 	TAG_READ,
    366 	TAG_READAHEAD,
    367 	TAG_READDIR,
    368 	TAG_READLINK,
    369 	TAG_RELOCK,
    370 	TAG_REMAP_LOOKUP,
    371 	TAG_REMAP_LOOKUP_AD,
    372 	TAG_REMAP_LOOKUP_NA,
    373 	TAG_REMAP_MOUNT,
    374 	TAG_RMDIR,
    375 	TAG_REMOVE,
    376 	TAG_RENAME,
    377 	TAG_RENAME_VFH,
    378 	TAG_RENEW,
    379 	TAG_REOPEN,
    380 	TAG_REOPEN_LOST,
    381 	TAG_SECINFO,
    382 	TAG_SETATTR,
    383 	TAG_SETCLIENTID,
    384 	TAG_SETCLIENTID_CF,
    385 	TAG_SYMLINK,
    386 	TAG_WRITE,
    387 	TAG_EXCHANGE_ID,			/* XXX - rick */
    388 	TAG_CREATE_SESSION,
    389 	TAG_BIND_CONN_TO_SESSION,
    390 	TAG_PNFS_READ,
    391 	TAG_PNFS_WRITE,
    392 	TAG_PNFS_COMMIT,
    393 	TAG_PNFS_LAYOUTGET,
    394 	TAG_PNFS_LAYOUTRETURN,
    395 	TAG_PNFS_GETDEVLIST,
    396 	TAG_SEQUENCE,
    397 	TAG_DESTROY_SESSION,
    398 	TAG_PNFS_GETDEVINFO,
    399 	TAG_RECLAIM_COMPLETE,
    400 	TAG_LAYOUTCOMMIT
    401 } nfs4_tag_type_t;
    402 
    403 #define	NFS4_TAG_INITIALIZER	{				\
    404 		{TAG_NONE,		"",			\
    405 			{0x20202020, 0x20202020, 0x20202020}},	\
    406 		{TAG_ACCESS,		"access",		\
    407 			{0x61636365, 0x73732020, 0x20202020}},	\
    408 		{TAG_CLOSE,		"close",		\
    409 			{0x636c6f73, 0x65202020, 0x20202020}},	\
    410 		{TAG_CLOSE_LOST,	"lost close",		\
    411 			{0x6c6f7374, 0x20636c6f, 0x73652020}},	\
    412 		{TAG_CLOSE_UNDO,	"undo close",		\
    413 			{0x756e646f, 0x20636c6f, 0x73652020}},	\
    414 		{TAG_COMMIT,		"commit",		\
    415 			{0x636f6d6d, 0x69742020, 0x20202020}},	\
    416 		{TAG_DELEGRETURN,	"delegreturn",		\
    417 			{0x64656c65, 0x67726574, 0x75726e20}},	\
    418 		{TAG_FSINFO,		"fsinfo",		\
    419 			{0x6673696e, 0x666f2020, 0x20202020}},	\
    420 		{TAG_GET_SYMLINK,	"get symlink text",	\
    421 			{0x67657420, 0x736c6e6b, 0x20747874}},	\
    422 		{TAG_GETATTR,		"getattr",		\
    423 			{0x67657461, 0x74747220, 0x20202020}},	\
    424 		{TAG_INACTIVE,		"inactive",		\
    425 			{0x696e6163, 0x74697665, 0x20202020}},	\
    426 		{TAG_LINK,		"link",			\
    427 			{0x6c696e6b, 0x20202020, 0x20202020}},	\
    428 		{TAG_LOCK,		"lock",			\
    429 			{0x6c6f636b, 0x20202020, 0x20202020}},	\
    430 		{TAG_LOCK_RECLAIM,	"reclaim lock",		\
    431 			{0x7265636c, 0x61696d20, 0x6c6f636b}},	\
    432 		{TAG_LOCK_RESEND,	"resend lock",		\
    433 			{0x72657365, 0x6e64206c, 0x6f636b20}},	\
    434 		{TAG_LOCK_REINSTATE,	"reinstate lock",	\
    435 			{0x7265696e, 0x7374206c, 0x6f636b20}},	\
    436 		{TAG_LOCK_UNKNOWN,	"unknown lock",		\
    437 			{0x756e6b6e, 0x6f776e20, 0x6c6f636b}},	\
    438 		{TAG_LOCKT,		"lock test",		\
    439 			{0x6c6f636b, 0x5f746573, 0x74202020}},	\
    440 		{TAG_LOCKU,		"unlock",		\
    441 			{0x756e6c6f, 0x636b2020, 0x20202020}},	\
    442 		{TAG_LOCKU_RESEND,	"resend locku",		\
    443 			{0x72657365, 0x6e64206c, 0x6f636b75}},	\
    444 		{TAG_LOCKU_REINSTATE,	"reinstate unlock",	\
    445 			{0x7265696e, 0x73742075, 0x6e6c636b}},	\
    446 		{TAG_LOOKUP,		"lookup",		\
    447 			{0x6c6f6f6b, 0x75702020, 0x20202020}},	\
    448 		{TAG_LOOKUP_PARENT,	"lookup parent",	\
    449 			{0x6c6f6f6b, 0x75702070, 0x6172656e}},	\
    450 		{TAG_LOOKUP_VALID,	"lookup valid",		\
    451 			{0x6c6f6f6b, 0x75702076, 0x616c6964}},	\
    452 		{TAG_LOOKUP_VPARENT,	"lookup valid parent",	\
    453 			{0x6c6f6f6b, 0x766c6420, 0x7061726e}},	\
    454 		{TAG_MKDIR,		"mkdir",		\
    455 			{0x6d6b6469, 0x72202020, 0x20202020}},	\
    456 		{TAG_MKNOD,		"mknod",		\
    457 			{0x6d6b6e6f, 0x64202020, 0x20202020}},	\
    458 		{TAG_MOUNT,		"mount",		\
    459 			{0x6d6f756e, 0x74202020, 0x20202020}},	\
    460 		{TAG_OPEN,		"open",			\
    461 			{0x6f70656e, 0x20202020, 0x20202020}},	\
    462 		{TAG_OPEN_CONFIRM,	"open confirm",		\
    463 			{0x6f70656e, 0x5f636f6e, 0x6669726d}},	\
    464 		{TAG_OPEN_CONFIRM_LOST,	"lost open confirm",	\
    465 			{0x6c6f7374, 0x206f7065, 0x6e5f636f}},	\
    466 		{TAG_OPEN_DG,		"open downgrade",	\
    467 			{0x6f70656e, 0x20646772, 0x61646520}},	\
    468 		{TAG_OPEN_DG_LOST,	"lost open downgrade",	\
    469 			{0x6c737420, 0x6f70656e, 0x20646772}},	\
    470 		{TAG_OPEN_LOST,		"lost open",		\
    471 			{0x6c6f7374, 0x206f7065, 0x6e202020}},	\
    472 		{TAG_OPENATTR,		"openattr",		\
    473 			{0x6f70656e, 0x61747472, 0x20202020}},	\
    474 		{TAG_PATHCONF,		"pathhconf",		\
    475 			{0x70617468, 0x636f6e66, 0x20202020}},	\
    476 		{TAG_PUTROOTFH,		"putrootfh",		\
    477 			{0x70757472, 0x6f6f7466, 0x68202020}},	\
    478 		{TAG_READ,		"read",			\
    479 			{0x72656164, 0x20202020, 0x20202020}},	\
    480 		{TAG_READAHEAD,		"readahead",		\
    481 			{0x72656164, 0x61686561, 0x64202020}},	\
    482 		{TAG_READDIR,		"readdir",		\
    483 			{0x72656164, 0x64697220, 0x20202020}},	\
    484 		{TAG_READLINK,		"readlink",		\
    485 			{0x72656164, 0x6c696e6b, 0x20202020}},	\
    486 		{TAG_RELOCK,		"relock",		\
    487 			{0x72656c6f, 0x636b2020, 0x20202020}},	\
    488 		{TAG_REMAP_LOOKUP,	"remap lookup",		\
    489 			{0x72656d61, 0x70206c6f, 0x6f6b7570}},	\
    490 		{TAG_REMAP_LOOKUP_AD,	"remap lookup attr dir",	\
    491 			{0x72656d70, 0x206c6b75, 0x70206164}},	\
    492 		{TAG_REMAP_LOOKUP_NA,	"remap lookup named attrs",	\
    493 			{0x72656d70, 0x206c6b75, 0x70206e61}},	\
    494 		{TAG_REMAP_MOUNT,	"remap mount",		\
    495 			{0x72656d61, 0x70206d6f, 0x756e7420}},	\
    496 		{TAG_RMDIR,		"rmdir",		\
    497 			{0x726d6469, 0x72202020, 0x20202020}},	\
    498 		{TAG_REMOVE,		"remove",		\
    499 			{0x72656d6f, 0x76652020, 0x20202020}},	\
    500 		{TAG_RENAME,		"rename",		\
    501 			{0x72656e61, 0x6d652020, 0x20202020}},	\
    502 		{TAG_RENAME_VFH,	"rename volatile fh",	\
    503 			{0x72656e61, 0x6d652028, 0x76666829}},	\
    504 		{TAG_RENEW,		"renew",		\
    505 			{0x72656e65, 0x77202020, 0x20202020}},	\
    506 		{TAG_REOPEN,		"reopen",		\
    507 			{0x72656f70, 0x656e2020, 0x20202020}},	\
    508 		{TAG_REOPEN_LOST,	"lost reopen",		\
    509 			{0x6c6f7374, 0x2072656f, 0x70656e20}},	\
    510 		{TAG_SECINFO,		"secinfo",		\
    511 			{0x73656369, 0x6e666f20, 0x20202020}},	\
    512 		{TAG_SETATTR,		"setattr",		\
    513 			{0x73657461, 0x74747220, 0x20202020}},	\
    514 		{TAG_SETCLIENTID,	"setclientid",		\
    515 			{0x73657463, 0x6c69656e, 0x74696420}},	\
    516 		{TAG_SETCLIENTID_CF,	"setclientid_confirm",	\
    517 			{0x73636c6e, 0x7469645f, 0x636f6e66}},	\
    518 		{TAG_SYMLINK,		"symlink",		\
    519 			{0x73796d6c, 0x696e6b20, 0x20202020}},	\
    520 		{TAG_WRITE,		"write",		\
    521 			{0x77726974, 0x65202020, 0x20202020}},	\
    522 		{TAG_EXCHANGE_ID,	"exchange_id",	\
    523 			{0x65786368, 0x616e6765, 0x5f696420}},	\
    524 		{TAG_CREATE_SESSION,	"create_session",	\
    525 			{0x63726561, 0x74655f73, 0x65737369}},	\
    526 		{TAG_BIND_CONN_TO_SESSION,	"bind_conn_to_session", \
    527 			{0x62696e64, 0x5f636f6e, 0x6e5f746f}},	\
    528 		{TAG_PNFS_READ,		"pnfs read",		\
    529 			{0x706e6673, 0x20726561, 0x64202020}},	\
    530 		{TAG_PNFS_WRITE,		"pnfs write",	\
    531 			{0x706e6673, 0x20777269, 0x74652020}},	\
    532 		{TAG_PNFS_COMMIT,		"pnfs commit",	\
    533 			{0x706e6673, 0x20636f6d, 0x6d697420}},	\
    534 		{TAG_PNFS_LAYOUTGET,		"layoutget",	\
    535 			{0x6c61796f, 0x75746765, 0x74202020}},	\
    536 		{TAG_PNFS_LAYOUTRETURN,		"layoutreturn",	\
    537 			{0x6c61796f, 0x75747265, 0x7475726e}},	\
    538 		{TAG_PNFS_GETDEVLIST,		"pnfs devlist",	\
    539 			{0x706e6673, 0x20646576, 0x6c697374}},	\
    540 		{TAG_SEQUENCE,			"sequence",	\
    541 			{0x73657175, 0x656e6365, 0x20202020}},	\
    542 		{TAG_DESTROY_SESSION,		"destroy session", \
    543 			{0x64657374, 0x726f7920, 0x73657373}},	\
    544 		{TAG_PNFS_GETDEVINFO,		"getdeviceinf", \
    545 			{0x67657464, 0x65766963, 0x65696e66}},	\
    546 		{TAG_RECLAIM_COMPLETE,		"reclaim complete", \
    547 			{0x7265636c, 0x61696d20, 0x636f6d70}},	\
    548 		{TAG_LAYOUTCOMMIT,		"layoutcommit", \
    549 			{0x6c61796f, 0x75742063, 0x6f6d6d69}} \
    550 	}
    551 
    552 /*
    553  * These flags are for differentiating the search criterian for
    554  * find_open_owner().  The comparison is done with the open_owners's
    555  * 'oo_just_created' flag.
    556  */
    557 #define	NFS4_PERM_CREATED	0x0
    558 #define	NFS4_JUST_CREATED	0x1
    559 
    560 /*
    561  * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw'
    562  * is stored upon a successful OPEN.  This is needed when the user's effective
    563  * and real uid's don't match.  The 'oo_cred_otw' overrides the credential
    564  * passed down by VFS for async read/write, commit, lock, and close operations.
    565  *
    566  * The oo_ref_count keeps track the number of active references on this
    567  * data structure + number of nfs4_open_streams point to this structure.
    568  *
    569  * 'oo_valid' tells whether this stuct is about to be freed or not.
    570  *
    571  * 'oo_just_created' tells us whether this struct has just been created but
    572  * not been fully finalized (that is created upon an OPEN request and
    573  * finalized upon the OPEN success).
    574  *
    575  * The 'oo_seqid_inuse' is for the open seqid synchronization.  If a thread
    576  * is currently using the open owner and it's open_seqid, then it sets the
    577  * oo_seqid_inuse to true if it currently is not set.  If it is set then it
    578  * does a cv_wait on the oo_cv_seqid_sync condition variable.  When the thread
    579  * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process
    580  * waiting on the condition variable.
    581  *
    582  * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW,
    583  * and 'oo_last_good_op' is the operation that issued the last valid seqid.
    584  *
    585  * Lock ordering:
    586  *	mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list)
    587  *
    588  *	oo_seqid_inuse > mntinfo4_t::mi_lock
    589  *	oo_seqid_inuse > rnode4_t::r_statelock
    590  *	oo_seqid_inuse > rnode4_t::r_statev4_lock
    591  *	oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock
    592  *
    593  * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects:
    594  *	oo_last_good_op
    595  *	oo_last_good_seqid
    596  *	oo_name
    597  *	oo_seqid
    598  *
    599  * The 'oo_lock' protects:
    600  *	oo_cred
    601  *	oo_cred_otw
    602  *	oo_foo_node
    603  *	oo_hash_node
    604  *	oo_just_created
    605  *	oo_ref_count
    606  *	oo_valid
    607  */
    608 
    609 typedef struct nfs4_open_owner {
    610 	cred_t			*oo_cred;
    611 	int			oo_ref_count;
    612 	int			oo_valid;
    613 	int			oo_just_created;
    614 	seqid4			oo_seqid;
    615 	seqid4			oo_last_good_seqid;
    616 	nfs4_tag_type_t		oo_last_good_op;
    617 	unsigned		oo_seqid_inuse:1;
    618 	cred_t			*oo_cred_otw;
    619 	kcondvar_t		oo_cv_seqid_sync;
    620 	/*
    621 	 * Fix this to always be 8 bytes
    622 	 */
    623 	uint64_t		oo_name;
    624 	list_node_t		oo_hash_node;
    625 	list_node_t		oo_foo_node;
    626 	kmutex_t		oo_lock;
    627 } nfs4_open_owner_t;
    628 
    629 /*
    630  * Static server information.
    631  * These fields are read-only once they are initialized:
    632  *	sv_addr
    633  *	sv_dhsec
    634  *	sv_hostname
    635  *	sv_hostnamelen
    636  *	sv_knconf
    637  *	sv_next
    638  *	sv_origknconf
    639  *
    640  * These fields are protected by sv_lock:
    641  *	sv_currsec
    642  *	sv_fhandle
    643  *	sv_flags
    644  *	sv_fsid
    645  *	sv_path
    646  *	sv_pathlen
    647  *	sv_pfhandle
    648  *	sv_save_secinfo
    649  *	sv_savesec
    650  *	sv_secdata
    651  *	sv_secinfo
    652  *	sv_supp_attrs
    653  *
    654  * Lock ordering:
    655  * nfs_rtable4_lock > sv_lock
    656  * rnode4_t::r_statelock > sv_lock
    657  */
    658 typedef struct servinfo4 {
    659 	struct knetconfig *sv_knconf;   /* bound TLI fd */
    660 	struct knetconfig *sv_origknconf;	/* For RDMA save orig knconf */
    661 	struct netbuf	   sv_addr;	/* server's address */
    662 	nfs4_fhandle_t	   sv_fhandle;	/* this server's filehandle */
    663 	nfs4_fhandle_t	   sv_pfhandle; /* parent dir filehandle */
    664 	int		   sv_pathlen;	/* Length of server path */
    665 	char		  *sv_path;	/* Path name on server */
    666 	uint32_t	   sv_flags;	/* flags for this server */
    667 	sec_data_t	  *sv_secdata;	/* client initiated security data */
    668 	sv_secinfo_t	  *sv_secinfo;	/* server security information */
    669 	sec_data_t	  *sv_currsec;	/* security data currently used; */
    670 					/* points to one of the sec_data */
    671 					/* entries in sv_secinfo */
    672 	sv_secinfo_t	  *sv_save_secinfo; /* saved secinfo */
    673 	sec_data_t	  *sv_savesec;	/* saved security data */
    674 	sec_data_t	  *sv_dhsec;    /* AUTH_DH data from the user land */
    675 	char		  *sv_hostname;	/* server's hostname */
    676 	int		   sv_hostnamelen;  /* server's hostname length */
    677 	fattr4_fsid		sv_fsid;    /* fsid of shared obj	*/
    678 	attrmap4	sv_supp_attrs;
    679 	struct servinfo4  *sv_next;	/* next in list */
    680 	nfs_rwlock_t	   sv_lock;
    681 	attrmap4	sv_supp_exclcreat;
    682 } servinfo4_t;
    683 
    684 /* sv_flags fields */
    685 #define	SV4_TRYSECINFO		0x001	/* try secinfo data from the server */
    686 #define	SV4_TRYSECDEFAULT	0x002	/* try a default flavor */
    687 #define	SV4_NOTINUSE		0x004	/* servinfo4_t had fatal errors */
    688 #define	SV4_ROOT_STALE		0x008	/* root vnode got ESTALE */
    689 #define	SV4_ISA_DS		0x010	/* this is a data server! */
    690 
    691 /*
    692  * Lock call types.  See nfs4frlock().
    693  */
    694 typedef enum nfs4_lock_call_type {
    695 	NFS4_LCK_CTYPE_NORM,
    696 	NFS4_LCK_CTYPE_RECLAIM,
    697 	NFS4_LCK_CTYPE_RESEND,
    698 	NFS4_LCK_CTYPE_REINSTATE
    699 } nfs4_lock_call_type_t;
    700 
    701 struct nfs4_server;
    702 
    703 /*
    704  * This structure holds the information for a lost open/close/open downgrade/
    705  * lock/locku request.  It is also used for requests that are queued up so
    706  * that the recovery thread can release server state after a forced
    707  * unmount.
    708  * "lr_op" is 0 if the struct is uninitialized.  Otherwise, it is set to
    709  * the proper OP_* nfs_opnum4 number.  The other fields contain information
    710  * to reconstruct the call.
    711  *
    712  * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the
    713  * parent directroy without relying on vtodv (since we may not have a vp
    714  * for the file we wish to create).
    715  *
    716  * lr_putfirst means that the request should go to the front of the resend
    717  * queue, rather than the end.
    718  */
    719 typedef struct nfs4_lost_rqst {
    720 	list_node_t			lr_node;
    721 	nfs_opnum4			lr_op;
    722 	vnode_t				*lr_vp;
    723 	vnode_t				*lr_dvp;
    724 	nfs4_open_owner_t		*lr_oop;
    725 	struct nfs4_open_stream		*lr_osp;
    726 	struct nfs4_lock_owner		*lr_lop;
    727 	cred_t				*lr_cr;
    728 	flock64_t			*lr_flk;
    729 	bool_t				lr_putfirst;
    730 	union {
    731 		struct {
    732 			nfs4_lock_call_type_t lru_ctype;
    733 			nfs_lock_type4	lru_locktype;
    734 		} lru_lockargs;		/* LOCK, LOCKU */
    735 		struct {
    736 			uint32_t		lru_oaccess;
    737 			uint32_t		lru_odeny;
    738 			enum open_claim_type4	lru_oclaim;
    739 			stateid4		lru_ostateid; /* reopen only */
    740 			component4		lru_ofile;
    741 			struct nfs4_server	*lru_slot_srv;
    742 			slot_ent_t		*lru_slot_ent;
    743 		} lru_open_args;
    744 		struct {
    745 			uint32_t	lru_dg_access;
    746 			uint32_t	lru_dg_deny;
    747 		} lru_open_dg_args;
    748 	} nfs4_lr_u;
    749 } nfs4_lost_rqst_t;
    750 
    751 #define	lr_oacc		nfs4_lr_u.lru_open_args.lru_oaccess
    752 #define	lr_odeny	nfs4_lr_u.lru_open_args.lru_odeny
    753 #define	lr_oclaim	nfs4_lr_u.lru_open_args.lru_oclaim
    754 #define	lr_ostateid	nfs4_lr_u.lru_open_args.lru_ostateid
    755 #define	lr_ofile	nfs4_lr_u.lru_open_args.lru_ofile
    756 #define	lr_slot_srv	nfs4_lr_u.lru_open_args.lru_slot_srv
    757 #define	lr_slot_ent	nfs4_lr_u.lru_open_args.lru_slot_ent
    758 #define	lr_dg_acc	nfs4_lr_u.lru_open_dg_args.lru_dg_access
    759 #define	lr_dg_deny	nfs4_lr_u.lru_open_dg_args.lru_dg_deny
    760 #define	lr_ctype	nfs4_lr_u.lru_lockargs.lru_ctype
    761 #define	lr_locktype	nfs4_lr_u.lru_lockargs.lru_locktype
    762 
    763 /*
    764  * Recovery actions.  Some actions can imply further recovery using a
    765  * different recovery action (e.g., recovering the clientid leads to
    766  * recovering open files and locks).
    767  */
    768 
    769 typedef enum {
    770 	NR_UNUSED,
    771 	NR_CLIENTID,
    772 	NR_OPENFILES,
    773 	NR_FHEXPIRED,
    774 	NR_FAILOVER,
    775 	NR_WRONGSEC,
    776 	NR_EXPIRED,
    777 	NR_BAD_STATEID,
    778 	NR_BADHANDLE,
    779 	NR_BAD_SEQID,
    780 	NR_OLDSTATEID,
    781 	NR_GRACE,
    782 	NR_DELAY,
    783 	NR_LOST_LOCK,
    784 	NR_LOST_STATE_RQST,
    785 	NR_STALE,
    786 	NR_BADSESSION,
    787 	NR_BC2S,
    788 	NR_SEQRETRY
    789 } nfs4_recov_t;
    790 
    791 /*
    792  * Administrative and debug message framework.
    793  */
    794 
    795 #define	NFS4_MSG_MAX	100
    796 extern int nfs4_msg_max;
    797 
    798 typedef enum {
    799 	RE_BAD_SEQID,
    800 	RE_BADHANDLE,
    801 	RE_CLIENTID,
    802 	RE_DEAD_FILE,
    803 	RE_END,
    804 	RE_FAIL_RELOCK,
    805 	RE_FAIL_REMAP_LEN,
    806 	RE_FAIL_REMAP_OP,
    807 	RE_FAILOVER,
    808 	RE_FILE_DIFF,
    809 	RE_LOST_STATE,
    810 	RE_OPENS_CHANGED,
    811 	RE_SIGLOST,
    812 	RE_SIGLOST_NO_DUMP,
    813 	RE_START,
    814 	RE_UNEXPECTED_ACTION,
    815 	RE_UNEXPECTED_ERRNO,
    816 	RE_UNEXPECTED_STATUS,
    817 	RE_WRONGSEC,
    818 	RE_LOST_STATE_BAD_OP
    819 } nfs4_event_type_t;
    820 
    821 typedef enum {
    822 	RFS_NO_INSPECT,
    823 	RFS_INSPECT
    824 } nfs4_fact_status_t;
    825 
    826 typedef enum {
    827 	RF_BADOWNER,
    828 	RF_ERR,
    829 	RF_RENEW_EXPIRED,
    830 	RF_SRV_NOT_RESPOND,
    831 	RF_SRV_OK,
    832 	RF_SRVS_NOT_RESPOND,
    833 	RF_SRVS_OK,
    834 	RF_DELMAP_CB_ERR,
    835 	RF_SENDQ_FULL
    836 } nfs4_fact_type_t;
    837 
    838 typedef enum {
    839 	NFS4_MS_DUMP,
    840 	NFS4_MS_NO_DUMP
    841 } nfs4_msg_status_t;
    842 
    843 typedef struct nfs4_rfact {
    844 	nfs4_fact_type_t	rf_type;
    845 	nfs4_fact_status_t	rf_status;
    846 	bool_t			rf_reboot;
    847 	nfs4_recov_t		rf_action;
    848 	nfs_opnum4		rf_op;
    849 	nfsstat4		rf_stat4;
    850 	timespec_t		rf_time;
    851 	int			rf_error;
    852 	struct rnode4		*rf_rp1;
    853 	char			*rf_char1;
    854 } nfs4_rfact_t;
    855 
    856 typedef struct nfs4_revent {
    857 	nfs4_event_type_t	re_type;
    858 	nfsstat4		re_stat4;
    859 	uint_t			re_uint;
    860 	pid_t			re_pid;
    861 	struct mntinfo4		*re_mi;
    862 	struct rnode4		*re_rp1;
    863 	struct rnode4		*re_rp2;
    864 	char			*re_char1;
    865 	char			*re_char2;
    866 	nfs4_tag_type_t		re_tag1;
    867 	nfs4_tag_type_t		re_tag2;
    868 	seqid4			re_seqid1;
    869 	seqid4			re_seqid2;
    870 } nfs4_revent_t;
    871 
    872 typedef enum {
    873 	RM_EVENT,
    874 	RM_FACT
    875 } nfs4_msg_type_t;
    876 
    877 typedef struct nfs4_debug_msg {
    878 	timespec_t		msg_time;
    879 	nfs4_msg_type_t		msg_type;
    880 	char			*msg_srv;
    881 	char			*msg_mntpt;
    882 	union {
    883 		nfs4_rfact_t	msg_fact;
    884 		nfs4_revent_t	msg_event;
    885 	} rmsg_u;
    886 	nfs4_msg_status_t	msg_status;
    887 	list_node_t		msg_node;
    888 } nfs4_debug_msg_t;
    889 
    890 /*
    891  * NFS private data per mounted file system
    892  *	The mi_lock mutex protects the following fields:
    893  *		mi_flags
    894  *		mi_in_recovery
    895  *		mi_recovflags
    896  *		mi_recovthread
    897  *		mi_error
    898  *		mi_printed
    899  *		mi_down
    900  *		mi_stsize
    901  *		mi_curread
    902  *		mi_curwrite
    903  *		mi_timers
    904  *		mi_curr_serv
    905  *		mi_klmconfig
    906  *		mi_oo_list
    907  *		mi_foo_list
    908  *		mi_foo_num
    909  *		mi_foo_max
    910  *		mi_lost_state
    911  *		mi_bseqid_list
    912  *		mi_ephemeral
    913  *		mi_ephemeral_tree
    914  *
    915  *	Normally the netconfig information for the mount comes from
    916  *	mi_curr_serv and mi_klmconfig is NULL.  If NLM calls need to use a
    917  *	different transport, mi_klmconfig contains the necessary netconfig
    918  *	information.
    919  *
    920  *	The mi_async_lock mutex protects the following fields:
    921  *		mi_async_reqs
    922  *		mi_async_req_count
    923  *		mi_async_tail
    924  *		mi_async_curr
    925  *		mi_async_clusters
    926  *		mi_async_init_clusters
    927  *		mi_threads
    928  *		mi_inactive_thread
    929  *		mi_manager_thread
    930  *
    931  *	The nfs4_server_t::s_lock protects the following fields:
    932  *		mi_clientid
    933  *		mi_clientid_next
    934  *		mi_clientid_prev
    935  *		mi_open_files
    936  *
    937  *	The mntinfo4_t::mi_recovlock protects the following fields:
    938  *		mi_srvsettime
    939  *		mi_srvset_cnt
    940  *		mi_srv
    941  *
    942  * Changing mi_srv from one nfs4_server_t to a different one requires
    943  * holding the mi_recovlock as RW_WRITER.
    944  * Exception: setting mi_srv the first time in mount/mountroot is done
    945  * holding the mi_recovlock as RW_READER.
    946  *
    947  *	Locking order:
    948  *	  mi4_globals::mig_lock > mi_async_lock
    949  *	  mi_async_lock > nfs4_server_t::s_lock > mi_lock
    950  *	  mi_recovlock > mi_rename_lock > nfs_rtable4_lock
    951  *	  nfs4_server_t::s_recovlock > mi_recovlock
    952  *	  rnode4_t::r_rwlock > mi_rename_lock
    953  *	  nfs_rtable4_lock > mi_lock
    954  *	  nfs4_server_t::s_lock > mi_msg_list_lock
    955  *	  mi_recovlock > nfs4_server_t::s_lock
    956  *	  mi_recovlock > nfs4_server_lst_lock
    957  *
    958  * The 'mi_oo_list' represents the hash buckets that contain the
    959  * nfs4_open_owenrs for this particular mntinfo4.
    960  *
    961  * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4.
    962  * 'mi_foo_num' is the current number of freed open owners on the list,
    963  * 'mi_foo_max' is the maximum number of freed open owners that are allowable
    964  * on the list.
    965  *
    966  * mi_rootfh and mi_srvparentfh are read-only once created, but that just
    967  * refers to the pointer.  The contents must be updated to keep in sync
    968  * with mi_curr_serv.
    969  *
    970  * The mi_msg_list_lock protects against adding/deleting entries to the
    971  * mi_msg_list, and also the updating/retrieving of mi_lease_period;
    972  *
    973  * 'mi_zone' is initialized at structure creation time, and never
    974  * changes; it may be read without a lock.
    975  *
    976  * mi_zone_node is linkage into the mi4_globals.mig_list, and is
    977  * protected by mi4_globals.mig_list_lock.
    978  *
    979  * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an
    980  * ephemeral structure for this ephemeral mount point. It can not be
    981  * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral
    982  * tree.
    983  *
    984  * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has
    985  * to be NULL. If mi_ephemeral_tree is non-NULL, then this node
    986  * is the enclosing mntinfo4 for the ephemeral tree.
    987  */
    988 struct zone;
    989 struct nfs4_ephemeral;
    990 struct nfs4_ephemeral_tree;
    991 struct nfs4_server;
    992 typedef struct mntinfo4 {
    993 	kmutex_t	mi_lock;	/* protects mntinfo4 fields */
    994 	struct servinfo4 *mi_servers;   /* server list */
    995 	struct servinfo4 *mi_curr_serv; /* current server */
    996 	struct nfs4_sharedfh *mi_rootfh; /* root filehandle */
    997 	struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */
    998 	uint32_t	mi_minorversion;
    999 	kcondvar_t	mi_failover_cv;	/* failover synchronization */
   1000 	struct vfs	*mi_vfsp;	/* back pointer to vfs */
   1001 	enum vtype	mi_type;	/* file type of the root vnode */
   1002 	uint_t		mi_flags;	/* see below */
   1003 	uint_t		mi_recovflags;	/* if recovery active; see below */
   1004 	kthread_t	*mi_recovthread; /* active recov thread or NULL */
   1005 	uint_t		mi_error;	/* only set/valid when MI4_RECOV_FAIL */
   1006 					/* is set in mi_flags */
   1007 	int		mi_tsize;	/* transfer size (bytes) */
   1008 					/* really read size */
   1009 	int		mi_stsize;	/* server's max transfer size (bytes) */
   1010 					/* really write size */
   1011 	int		mi_timeo;	/* inital timeout in 10th sec */
   1012 	int		mi_retrans;	/* times to retry request */
   1013 	hrtime_t	mi_acregmin;	/* min time to hold cached file attr */
   1014 	hrtime_t	mi_acregmax;	/* max time to hold cached file attr */
   1015 	hrtime_t	mi_acdirmin;	/* min time to hold cached dir attr */
   1016 	hrtime_t	mi_acdirmax;	/* max time to hold cached dir attr */
   1017 	len_t		mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */
   1018 	int		mi_curread;	/* current read size */
   1019 	int		mi_curwrite;	/* current write size */
   1020 	uint_t 		mi_count; 	/* ref count */
   1021 	/*
   1022 	 * async I/O management.  There may be a pool of threads to handle
   1023 	 * async I/O requests, etc., plus there is always one thread that
   1024 	 * handles over-the-wire requests for VOP_INACTIVE.  The async pool
   1025 	 * can also help out with VOP_INACTIVE.
   1026 	 */
   1027 	struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES];
   1028 	struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES];
   1029 	struct nfs4_async_reqs **mi_async_curr;	/* current async queue */
   1030 	uint_t		mi_async_clusters[NFS4_ASYNC_TYPES];
   1031 	uint_t		mi_async_init_clusters;
   1032 	uint_t		mi_async_req_count; /* # outstanding work requests */
   1033 	kcondvar_t	mi_async_reqs_cv; /* signaled when there's work */
   1034 	ushort_t	mi_threads;	/* number of active async threads */
   1035 	ushort_t	mi_max_threads;	/* max number of async threads */
   1036 	kthread_t	*mi_manager_thread; /* async manager thread id */
   1037 	kthread_t	*mi_inactive_thread; /* inactive thread id */
   1038 	kcondvar_t	mi_inact_req_cv; /* notify VOP_INACTIVE thread */
   1039 	kcondvar_t	mi_async_work_cv; /* tell workers to work */
   1040 	kcondvar_t	mi_async_cv;	/* all pool threads exited */
   1041 	kmutex_t	mi_async_lock;
   1042 	/*
   1043 	 * Other stuff
   1044 	 */
   1045 	struct pathcnf	*mi_pathconf;	/* static pathconf kludge */
   1046 	rpcprog_t	mi_prog;	/* RPC program number */
   1047 	rpcvers_t	mi_vers;	/* RPC program version number */
   1048 	char		**mi_rfsnames;	/* mapping to proc names */
   1049 	kstat_named_t	*mi_reqs;	/* count of requests */
   1050 	clock_t		mi_printftime;	/* last error printf time */
   1051 	nfs_rwlock_t	mi_recovlock;	/* separate ops from recovery (v4) */
   1052 	time_t		mi_grace_wait;	/* non-zero represents time to wait */
   1053 	/* when we switched nfs4_server_t - only for observability purposes */
   1054 	time_t		mi_srvsettime;
   1055 	nfs_rwlock_t	mi_rename_lock;	/* atomic volfh rename  */
   1056 	struct nfs4_fname *mi_fname;	/* root fname */
   1057 	list_t		mi_lost_state;	/* resend list */
   1058 	list_t		mi_bseqid_list; /* bad seqid list */
   1059 	/*
   1060 	 * Client Side Failover stats
   1061 	 */
   1062 	uint_t		mi_noresponse;	/* server not responding count */
   1063 	uint_t		mi_failover; 	/* failover to new server count */
   1064 	uint_t		mi_remap;	/* remap to new server count */
   1065 	/*
   1066 	 * Kstat statistics
   1067 	 */
   1068 	struct kstat	*mi_io_kstats;
   1069 	struct kstat	*mi_ro_kstats;
   1070 	kstat_t		*mi_recov_ksp;	/* ptr to the recovery kstat */
   1071 
   1072 	/*
   1073 	 * Volatile fh flags (nfsv4)
   1074 	 */
   1075 	uint32_t	mi_fh_expire_type;
   1076 	/*
   1077 	 * Lease Management
   1078 	 */
   1079 	struct mntinfo4	*mi_clientid_next;
   1080 	struct mntinfo4	*mi_clientid_prev;
   1081 	clientid4	mi_clientid; /* redundant info found in nfs4_server */
   1082 	int		mi_open_files;	/* count of open files */
   1083 	int		mi_in_recovery;	/* count of recovery instances */
   1084 	kcondvar_t	mi_cv_in_recov; /* cv for recovery threads */
   1085 	/*
   1086 	 * Open owner stuff.
   1087 	 */
   1088 	struct nfs4_oo_hash_bucket	mi_oo_list[NFS4_NUM_OO_BUCKETS];
   1089 	list_t				mi_foo_list;
   1090 	int				mi_foo_num;
   1091 	int				mi_foo_max;
   1092 	/*
   1093 	 * Shared filehandle pool.
   1094 	 */
   1095 	nfs_rwlock_t			mi_fh_lock;
   1096 	avl_tree_t			mi_filehandles;
   1097 
   1098 	/*
   1099 	 * pNFS support
   1100 	 */
   1101 	kmutex_t	mi_pnfs_lock;
   1102 	taskq_t		*mi_pnfs_io_taskq;
   1103 	taskq_t		*mi_pnfs_other_taskq;
   1104 	clock_t		mi_last_getdevicelist;
   1105 
   1106 	/*
   1107 	 * Debug message queue.
   1108 	 */
   1109 	list_t			mi_msg_list;
   1110 	int			mi_msg_count;
   1111 	time_t			mi_lease_period;
   1112 					/*
   1113 					 * not guaranteed to be accurate.
   1114 					 * only should be used by debug queue.
   1115 					 */
   1116 	kmutex_t		mi_msg_list_lock;
   1117 	/*
   1118 	 * Zones support.
   1119 	 */
   1120 	struct zone	*mi_zone; /* Zone mounted in */
   1121 	list_node_t	mi_zone_node;  /* linkage into per-zone mi list */
   1122 
   1123 	/*
   1124 	 * Links for unmounting ephemeral mounts.
   1125 	 */
   1126 	struct nfs4_ephemeral		*mi_ephemeral;
   1127 	struct nfs4_ephemeral_tree	*mi_ephemeral_tree;
   1128 
   1129 	uint_t mi_srvset_cnt; /* increment when changing the nfs4_server_t */
   1130 	struct nfs4_server *mi_srv; /* backpointer to nfs4_server_t */
   1131 	attrvers_t			mi_attrvers;
   1132 } mntinfo4_t;
   1133 
   1134 /*
   1135  * The values for mi_flags.
   1136  *
   1137  *	MI4_HARD		 hard or soft mount
   1138  *	MI4_PRINTED		 responding message printed
   1139  *	MI4_INT			 allow INTR on hard mount
   1140  * 	MI4_DOWN		 server is down
   1141  *	MI4_NOAC		 don't cache attributes
   1142  *	MI4_NOCTO		 no close-to-open consistency
   1143  *	MI4_LLOCK		 local locking only (no lockmgr)
   1144  *	MI4_GRPID		 System V group id inheritance
   1145  *	MI4_SHUTDOWN		 System is rebooting or shutting down
   1146  *	MI4_LINK		 server supports link
   1147  *	MI4_SYMLINK		 server supports symlink
   1148  *	MI4_EPHEMERAL_RECURSED	 an ephemeral mount being unmounted
   1149  *				 due to a recursive call - no need
   1150  *				 for additional recursion
   1151  *	MI4_PNFS		 server supports pNFS
   1152  *	MI4_ACL			 server supports NFSv4 ACLs
   1153  *	MI4_MIRRORMOUNT		 is a mirrormount
   1154  *	MI4_NOPRINT		 don't print messages
   1155  *	MI4_DIRECTIO		 do direct I/O
   1156  *	MI4_RECOV_ACTIV		 filesystem has recovery a thread
   1157  *	MI4_REMOVE_ON_LAST_CLOSE remove from server's list
   1158  *	MI4_RECOV_FAIL		 client recovery failed
   1159  *	MI4_PUBLIC		 public/url option used
   1160  *	MI4_MOUNTING		 mount in progress, don't failover
   1161  *	MI4_POSIX_LOCK		 if server is using POSIX locking
   1162  *	MI4_LOCK_DEBUG		 cmn_err'd posix lock err msg
   1163  *	MI4_DEAD		 zone has released it
   1164  *	MI4_INACTIVE_IDLE	 inactive thread idle
   1165  *	MI4_BADOWNER_DEBUG	 badowner error msg per mount
   1166  *	MI4_ASYNC_MGR_STOP	 tell async manager to die
   1167  *	MI4_TIMEDOUT		 saw a timeout during zone shutdown
   1168  *	MI4_EPHEMERAL		 is an ephemeral mount
   1169  */
   1170 #define	MI4_HARD		 0x1
   1171 #define	MI4_PRINTED		 0x2
   1172 #define	MI4_INT			 0x4
   1173 #define	MI4_DOWN		 0x8
   1174 #define	MI4_NOAC		 0x10
   1175 #define	MI4_NOCTO		 0x20
   1176 #define	MI4_LLOCK		 0x80
   1177 #define	MI4_GRPID		 0x100
   1178 #define	MI4_SHUTDOWN		 0x200
   1179 #define	MI4_LINK		 0x400
   1180 #define	MI4_SYMLINK		 0x800
   1181 #define	MI4_EPHEMERAL_RECURSED	 0x1000
   1182 #define	MI4_ACL			 0x2000
   1183 /* MI4_MIRRORMOUNT is also defined in nfsstat.c */
   1184 #define	MI4_MIRRORMOUNT		 0x4000
   1185 #define	MI4_PNFS		0x8000
   1186 /* 0x10000 is available */
   1187 #define	MI4_NOPRINT		 0x20000
   1188 #define	MI4_DIRECTIO		 0x40000
   1189 /* 0x80000 is available */
   1190 #define	MI4_RECOV_ACTIV		 0x100000
   1191 #define	MI4_REMOVE_ON_LAST_CLOSE 0x200000
   1192 #define	MI4_RECOV_FAIL		 0x400000
   1193 #define	MI4_PUBLIC		 0x800000
   1194 #define	MI4_MOUNTING		 0x1000000
   1195 #define	MI4_POSIX_LOCK		 0x2000000
   1196 #define	MI4_LOCK_DEBUG		 0x4000000
   1197 #define	MI4_DEAD		 0x8000000
   1198 #define	MI4_INACTIVE_IDLE	 0x10000000
   1199 #define	MI4_BADOWNER_DEBUG	 0x20000000
   1200 #define	MI4_ASYNC_MGR_STOP	 0x40000000
   1201 #define	MI4_TIMEDOUT		 0x80000000
   1202 
   1203 /*
   1204  * Note that when we add referrals, then MI4_EPHEMERAL
   1205  * will be MI4_MIRRORMOUNT | MI4_REFERRAL.
   1206  */
   1207 #define	MI4_EPHEMERAL		MI4_MIRRORMOUNT
   1208 
   1209 #define	INTR4(vp)	(VTOMI4(vp)->mi_flags & MI4_INT)
   1210 
   1211 #define	FAILOVER_MOUNT4(mi)	(mi->mi_servers->sv_next)
   1212 
   1213 /*
   1214  * Recovery flags.
   1215  *
   1216  * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag
   1217  * that's important), but some flag is needed to indicate that recovery is
   1218  * going on for the filesystem.
   1219  */
   1220 #define	MI4R_NEED_CLIENTID	0x1
   1221 #define	MI4R_REOPEN_FILES	0x2
   1222 #define	MI4R_NEED_SECINFO	0x4
   1223 #define	MI4R_NEED_NEW_SERVER	0x8
   1224 #define	MI4R_REMAP_FILES	0x10
   1225 #define	MI4R_SRV_REBOOT		0x20	/* server has rebooted */
   1226 #define	MI4R_LOST_STATE		0x40
   1227 #define	MI4R_BAD_SEQID		0x80
   1228 #define	MI4R_NEED_SESSION	0x100
   1229 #define	MI4R_NEED_BC2S		0x200
   1230 
   1231 #define	MI4_HOLD(mi) {		\
   1232 	mi_hold(mi);		\
   1233 }
   1234 
   1235 #define	MI4_RELE(mi) {		\
   1236 	mi_rele(mi);		\
   1237 }
   1238 
   1239 #define	NFS4_MINORVERSION(mi)	(mi->mi_minorversion)
   1240 
   1241 /*
   1242  * vfs pointer to mount info
   1243  */
   1244 #define	VFTOMI4(vfsp)	((mntinfo4_t *)((vfsp)->vfs_data))
   1245 
   1246 /*
   1247  * vnode pointer to mount info
   1248  */
   1249 #define	VTOMI4(vp)	((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data))
   1250 
   1251 /*
   1252  * Lease Management
   1253  *
   1254  * lease_valid is initially set to NFS4_LEASE_NOT_STARTED.  This is when the
   1255  * nfs4_server is first created.  lease_valid is then set to
   1256  * NFS4_LEASE_UNITIALIZED when the renew thread is started.  The extra state of
   1257  * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread
   1258  * already exists when we do SETCLIENTID).  lease_valid is then set to
   1259  * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating
   1260  * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as
   1261  * the lease is renewed.  It is set to NFS4_LEASE_INVALID when the lease
   1262  * expires.  Client recovery is needed to set the lease back to
   1263  * NFS4_LEASE_VALID from NFS4_LEASE_INVALID.
   1264  *
   1265  * The s_cred is the credential used to mount the first file system for this
   1266  * server.  It used as the credential for the renew thread's calls to the
   1267  * server.
   1268  *
   1269  * The renew thread waits on the condition variable cv_thread_exit.  If the cv
   1270  * is signalled, then the thread knows it must check s_thread_exit to see if
   1271  * it should exit.  The cv is signaled when the last file system is unmounted
   1272  * from a particular server.  s_thread_exit is set to 0 upon thread startup,
   1273  * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby
   1274  * telling the thread to exit.  s_thread_exit is needed to avoid spurious
   1275  * wakeups.
   1276  *
   1277  * state_ref_count is incremented every time a new file is opened and
   1278  * decremented every time a file is closed otw.  This keeps track of whether
   1279  * the nfs4_server has state associated with it or not.
   1280  *
   1281  * s_refcnt is the reference count for storage management of the struct
   1282  * itself.
   1283  *
   1284  * mntinfo4_list points to the doubly linked list of mntinfo4s that share
   1285  * this nfs4_server (ie: <clientid, saddr> pair) in the current zone.  This is
   1286  * needed for a nfs4_server to get a mntinfo4 for use in rfs4call.
   1287  *
   1288  * s_recovlock is used to synchronize recovery operations.  The thread
   1289  * that is recovering the client must acquire it as a writer.  If the
   1290  * thread is using the clientid (including recovery operations on other
   1291  * state), acquire it as a reader.
   1292  *
   1293  * The 's_otw_call_count' keeps track of the number of outstanding over the
   1294  * wire requests for this structure.  The struct will not go away as long
   1295  * as this is non-zero (or s_refcnt is non-zero).
   1296  *
   1297  * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count'
   1298  * variable to let the renew thread when an outstanding otw request has
   1299  * finished.
   1300  *
   1301  * 'zoneid' and 'zone_globals' are set at creation of this structure
   1302  * and are read-only after that; no lock is required to read them.
   1303  *
   1304  * s_lock protects: everything except cv_thread_exit and s_recovlock.
   1305  *
   1306  * s_program is used as the index into the nfs4_callback_globals's
   1307  * nfs4prog2server table.  When a callback request comes in, we can
   1308  * use that request's program number (minus NFS4_CALLBACK) as an index
   1309  * into the nfs4prog2server.  That entry will hold the nfs4_server_t ptr.
   1310  * We can then access that nfs4_server_t and its 's_deleg_list' (its list of
   1311  * delegated rnode4_ts).
   1312  *
   1313  * Lock order:
   1314  * nfs4_server::s_lock > mntinfo4::mi_lock
   1315  * nfs_rtable4_lock > s_lock
   1316  * nfs4_server_lst_lock > s_lock
   1317  * s_recovlock > s_lock
   1318  */
   1319 struct nfs4_callback_globals;
   1320 struct devnode;
   1321 
   1322 /*
   1323  * The nfs4_fsidlt_t will be the structure inserted as a node onto
   1324  * the nfs4_server_t's fsidlt (fsid layout tree).  There will be one
   1325  * per fsid that has done a layoutget.  Note that the fsid structures,
   1326  * once added to the fsidlt, will remain there until the nfs4_server_t
   1327  * is destroyed, even if all layouts have been returned for the fsid.
   1328  *
   1329  * The locking order is that, the s_lt_lock in the nfs4_server_t will
   1330  * lock the fsidlt tree.  Once the appropriate fsidlt node is found, it
   1331  * will be locked via its lt_rtl_lock, then the s_lt_lock can be dropped.
   1332  *
   1333  * Also note, that if the rnode4->r_statelock and the lt_rtl_lock are both
   1334  * required, the lt_rtl_lock must be taken out before the r_statelock
   1335  * and the lt_rtl_lock must be release after the r_statelock is released.
   1336  */
   1337 typedef struct nfs4_fsidlt
   1338 {
   1339 	fsid4		lt_fsid; /* fsid */
   1340 	avl_node_t	lt_node; /* link to nfs4_fsidlt tree */
   1341 	kmutex_t	lt_rlt_lock; /* rnode layout tree lock */
   1342 	avl_tree_t	lt_rlayout_tree; /* rnode layout tree by fh */
   1343 	uint_t		lt_lobulkblock;	/* operations blocking bulk lor */
   1344 	uint_t		lt_loinuse; /* layouts in use */
   1345 	uint_t		lt_locnt; /* valid layouts held for FSID */
   1346 	kcondvar_t	lt_lowait; /* condition variable */
   1347 	uint_t		lt_flags; /* layout flags */
   1348 } nfs4_fsidlt_t;
   1349 
   1350 /*
   1351  * s_loflags and lt_flags bit field values for nfs4_server and nfs4_fsidlt
   1352  */
   1353 #define	PNFS_CBLORECALL	0x01	/* Layout Recall Active Or Pending */
   1354 #define	PNFS_CBLOWAITER 0x02	/* Thread waiting for Bulk Lyaout Recall */
   1355 
   1356 /*
   1357  * Max slots and available slots can be accessed by stok_t->st_currw
   1358  * and stok_t->st_fslots.
   1359  */
   1360 typedef struct nfs4_session {
   1361 	sessionid4		sessionid;
   1362 	stok_t			*slot_table; /* Fore channel slot table. */
   1363 	stok_t			*cb_slot_table; /* Back Channel slot table */
   1364 	int			bi_rpc;
   1365 	channel_attrs4		fore_chan_attr;
   1366 	channel_attrs4		back_chan_attr;
   1367 	list_node_t		ssx_list;
   1368 	struct netbuf		saddr;
   1369 } nfs4_session_t;
   1370 
   1371 typedef struct nfs4_server {
   1372 	struct nfs4_server	*forw;
   1373 	struct nfs4_server	*back;
   1374 	struct netbuf		saddr;
   1375 	uint_t			s_flags; /* see below */
   1376 	uint_t			s_refcnt;
   1377 	clientid4		clientid;	/* what we get from server */
   1378 	nfs_client_id4		clidtosend;	/* what we send to server */
   1379 
   1380 	/* seqid for the next CREATE_SESSION */
   1381 	sequenceid4		csa_seqid;
   1382 
   1383 	nfs4_session_t		ssx;		/* sessions extension */
   1384 	int			seqhb_flags;
   1385 	mntinfo4_t		*mntinfo4_list;
   1386 	uint32_t		s_minorversion;	/* last tried minorversion */
   1387 	int			lease_valid;
   1388 	time_t			s_lease_time;
   1389 	time_t			last_renewal_time;
   1390 	timespec_t		propagation_delay;
   1391 	cred_t			*s_cred;
   1392 	kcondvar_t		cv_thread_exit;
   1393 	int			s_thread_exit;
   1394 	int			state_ref_count;
   1395 	int			s_otw_call_count;
   1396 	kcondvar_t		s_cv_otw_count;
   1397 	kcondvar_t		s_clientid_pend;
   1398 	kmutex_t		s_lock;
   1399 	list_t			s_deleg_list;
   1400 	rpcprog_t		s_program;
   1401 	nfs_rwlock_t		s_recovlock;
   1402 	kthread_t		*s_recovthread; /* active recov thrd or NULL */
   1403 	kcondvar_t		wait_cb_null; /* used to wait for CB_NULL */
   1404 	zoneid_t		zoneid;	/* zone using this nfs4_server_t */
   1405 	struct nfs4_callback_globals *zone_globals;	/* globals */
   1406 	kcondvar_t		ssx_wait;	/* wait for destroy session */
   1407 	servinfo4_t		*s_ds_svp; /* for dataservers, the servinfo4 */
   1408 	uint_t			s_lobulkblock; /* active ops block bulk lor */
   1409 	uint_t			s_loinuse; /* active ops using layouts */
   1410 	uint_t			s_loflags; /* layout flags */
   1411 	uint_t			s_locnt; /* Valid layouts held for clientid */
   1412 	kcondvar_t		s_lowait; /* bulk lor waiting here */
   1413 	kmutex_t		s_lt_lock; /* layout tree lock */
   1414 	avl_tree_t		s_fsidlt; /* fsid layout tree */
   1415 	avl_tree_t		s_devid_tree;	/* Device ID tree */
   1416 	mntinfo4_t		*s_hb_mi;	/* mi held by hb thread */
   1417 	servinfo4_t		*s_hb_svp;	/* servinfo4 for hb thread */
   1418 	struct devnode 		*s_devnode;
   1419 } nfs4_server_t;
   1420 
   1421 /* nfs4_server flags */
   1422 #define	N4S_CLIENTID_SET	1	/* server has our clientid */
   1423 #define	N4S_CLIENTID_PEND	0x2	/* server doesn't have clientid */
   1424 #define	N4S_CB_PINGED		0x4	/* server has sent us a CB_NULL */
   1425 #define	N4S_CB_WAITER		0x8	/* is/has wait{ing/ed} for cb_null */
   1426 #define	N4S_INSERTED		0x10	/* list has reference for server */
   1427 #define	N4S_BADOWNER_DEBUG	0x20	/* bad owner err msg per client */
   1428 #define	N4S_USE_PNFS_MDS	0x40	/* server is a pnfs MDS server */
   1429 #define	N4S_USE_PNFS_DS		0x80	/* server is a pnfs DS server */
   1430 #define	N4S_SESSION_CREATED	0x100	/* Session Created To Server */
   1431 #define	N4S_EXID_FAILED		0x200	/* Exchange ID failed */
   1432 #define	N4S_USE_NON_PNFS	0x400	/* server is a non pNFS 4.1 server */
   1433 #define	N4S_NEED_BC2S		0x800	/* need bind_conn_to_session */
   1434 #define	N4S_RECOV_ACTIV		0x1000	/* Recovery is active for this server */
   1435 #define	N4S_SRV_DEAD		0x2000	/* nfs4_mark_srv_dead() called */
   1436 
   1437 #define	N4S_CB_PAUSE_TIME	10000	/* Amount of time to pause (10ms) */
   1438 
   1439 struct lease_time_arg {
   1440 	time_t	lease_time;
   1441 };
   1442 
   1443 enum nfs4_delegreturn_policy {
   1444 	IMMEDIATE,
   1445 	FIRSTCLOSE,
   1446 	LASTCLOSE,
   1447 	INACTIVE
   1448 };
   1449 
   1450 /*
   1451  * Operation hints for the recovery framework (mostly).
   1452  *
   1453  * EXCEPTIONS:
   1454  * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR
   1455  *	These hints exist to allow user visit/readdir a R4SRVSTUB dir.
   1456  *	(dir represents the root of a server fs that has not yet been
   1457  *	mounted at client)
   1458  */
   1459 typedef enum {
   1460 	OH_OTHER,
   1461 	OH_READ,
   1462 	OH_WRITE,
   1463 	OH_COMMIT,
   1464 	OH_VFH_RENAME,
   1465 	OH_MOUNT,
   1466 	OH_CLOSE,
   1467 	OH_LOCKU,
   1468 	OH_DELEGRETURN,
   1469 	OH_ACCESS,
   1470 	OH_GETACL,
   1471 	OH_GETATTR,
   1472 	OH_LOOKUP,
   1473 	OH_READDIR,
   1474 	OH_SEQUENCE,
   1475 	OH_DESTROY_SESS
   1476 } nfs4_op_hint_t;
   1477 
   1478 /*
   1479  * This data structure is used to track ephemeral mounts for both
   1480  * mirror mounts and referrals.
   1481  *
   1482  * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral
   1483  * pointing at it. So we don't need two backpointers to walk
   1484  * back up the tree.
   1485  *
   1486  * An ephemeral tree is pointed to by an enclosing non-ephemeral
   1487  * mntinfo4. The root is also pointed to by its ephemeral
   1488  * mntinfo4. ne_child will get us back to it, while ne_prior
   1489  * will get us back to the non-ephemeral mntinfo4. This is an
   1490  * edge case we will need to be wary of when walking back up the
   1491  * tree.
   1492  *
   1493  * The way we handle this edge case is to have ne_prior be NULL
   1494  * for the root nfs4_ephemeral node.
   1495  */
   1496 typedef struct nfs4_ephemeral {
   1497 	mntinfo4_t		*ne_mount;	/* who encloses us */
   1498 	struct nfs4_ephemeral	*ne_child;	/* first child node */
   1499 	struct nfs4_ephemeral	*ne_peer;	/* next sibling */
   1500 	struct nfs4_ephemeral	*ne_prior;	/* who points at us */
   1501 	time_t			ne_ref_time;	/* time last referenced */
   1502 	uint_t			ne_mount_to;	/* timeout at */
   1503 	int			ne_state;	/* used to traverse */
   1504 } nfs4_ephemeral_t;
   1505 
   1506 /*
   1507  * State for the node (set in ne_state):
   1508  */
   1509 #define	NFS4_EPHEMERAL_OK		0x0
   1510 #define	NFS4_EPHEMERAL_VISIT_CHILD	0x1
   1511 #define	NFS4_EPHEMERAL_VISIT_SIBLING	0x2
   1512 #define	NFS4_EPHEMERAL_PROCESS_ME	0x4
   1513 #define	NFS4_EPHEMERAL_CHILD_ERROR	0x8
   1514 #define	NFS4_EPHEMERAL_PEER_ERROR	0x10
   1515 
   1516 /*
   1517  * These are the locks used in processing ephemeral data:
   1518  *
   1519  * mi->mi_lock
   1520  *
   1521  * net->net_tree_lock
   1522  *     This lock is used to gate all tree operations.
   1523  *     If it is held, then no other process may
   1524  *     traverse the tree. This allows us to not
   1525  *     throw a hold on each vfs_t in the tree.
   1526  *     Can be held for a "long" time.
   1527  *
   1528  * net->net_cnt_lock
   1529  *     Used to protect refcnt and status.
   1530  *     Must be held for a really short time.
   1531  *
   1532  * nfs4_ephemeral_thread_lock
   1533  *     Is only held to create the harvester for the zone.
   1534  *     There is no ordering imposed on it.
   1535  *     Held for a really short time.
   1536  *
   1537  * Some further detail on the interactions:
   1538  *
   1539  * net_tree_lock controls access to net_root. Access needs to first be
   1540  * attempted in a non-blocking check.
   1541  *
   1542  * net_cnt_lock controls access to net_refcnt and net_status. It must only be
   1543  * held for very short periods of time, unless the refcnt is 0 and the status
   1544  * is INVALID.
   1545  *
   1546  * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock
   1547  * to bump the net_refcnt. It then releases it and does the action specific
   1548  * algorithm to get the net_tree_lock. Once it has that, then it is okay to
   1549  * grab the net_cnt_lock and change the status. The status can only be
   1550  * changed if the caller has the net_tree_lock held as well.
   1551  *
   1552  * Note that the initial grab of net_cnt_lock must occur whilst
   1553  * mi_lock is being held. This prevents stale data in that if the
   1554  * ephemeral tree is non-NULL, then the harvester can not remove
   1555  * the tree from the mntinfo node until it grabs that lock. I.e.,
   1556  * we get the pointer to the tree and hold the lock atomically
   1557  * with respect to being in mi_lock.
   1558  *
   1559  * When a caller is done with net_tree_lock, it can decrement the net_refcnt
   1560  * either before it releases net_tree_lock or after.
   1561  *
   1562  * In either event, to decrement net_refcnt, it must hold net_cnt_lock.
   1563  *
   1564  * Note that the overall locking scheme for the nodes is to control access
   1565  * via the tree. The current scheme could easily be extended such that
   1566  * the enclosing root referenced a "forest" of trees. The underlying trees
   1567  * would be autonomous with respect to locks.
   1568  *
   1569  * Note that net_next is controlled by external locks
   1570  * particular to the data structure that the tree is being added to.
   1571  */
   1572 typedef struct nfs4_ephemeral_tree {
   1573 	mntinfo4_t			*net_mount;
   1574 	nfs4_ephemeral_t		*net_root;
   1575 	struct nfs4_ephemeral_tree	*net_next;
   1576 	kmutex_t			net_tree_lock;
   1577 	kmutex_t			net_cnt_lock;
   1578 	uint_t				net_status;
   1579 	uint_t				net_refcnt;
   1580 } nfs4_ephemeral_tree_t;
   1581 
   1582 /*
   1583  * State for the tree (set in net_status):
   1584  */
   1585 #define	NFS4_EPHEMERAL_TREE_OK		0x0
   1586 #define	NFS4_EPHEMERAL_TREE_BUILDING	0x1
   1587 #define	NFS4_EPHEMERAL_TREE_DEROOTING	0x2
   1588 #define	NFS4_EPHEMERAL_TREE_INVALID	0x4
   1589 #define	NFS4_EPHEMERAL_TREE_MOUNTING	0x8
   1590 #define	NFS4_EPHEMERAL_TREE_UMOUNTING	0x10
   1591 #define	NFS4_EPHEMERAL_TREE_LOCKED	0x20
   1592 
   1593 #define	NFS4_EPHEMERAL_TREE_PROCESSING	(NFS4_EPHEMERAL_TREE_DEROOTING | \
   1594 	NFS4_EPHEMERAL_TREE_INVALID | NFS4_EPHEMERAL_TREE_UMOUNTING | \
   1595 	NFS4_EPHEMERAL_TREE_LOCKED)
   1596 
   1597 /*
   1598  * This macro evaluates to non-zero if the given op releases state at the
   1599  * server.  For 4.1 sequence and destroy session, they are allowed after
   1600  * an unmount.
   1601  */
   1602 #define	OH_IS_STATE_RELE(op)	((op) == OH_CLOSE || (op) == OH_LOCKU || \
   1603 				(op) == OH_DELEGRETURN || \
   1604 				(op) == OH_SEQUENCE || (op) == OH_DESTROY_SESS)
   1605 
   1606 #ifdef _KERNEL
   1607 
   1608 extern int	layoutcmp(const void *, const void *);
   1609 extern void	nfs4_set_mod(vnode_t *);
   1610 extern void	nfs4_set_pageerror(page_t *);
   1611 extern void	nfs4_async_manager(struct vfs *);
   1612 extern void	nfs4_async_manager_stop(struct vfs *);
   1613 extern void	nfs4_async_stop(struct vfs *);
   1614 extern int	nfs4_async_stop_sig(struct vfs *);
   1615 extern int	nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t,
   1616 				struct seg *, cred_t *,
   1617 				void (*)(vnode_t *, u_offset_t,
   1618 				caddr_t, struct seg *, cred_t *));
   1619 extern int	nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t,
   1620 				int, cred_t *, int (*)(vnode_t *, page_t *,
   1621 				u_offset_t, size_t, int, cred_t *));
   1622 extern int	nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t,
   1623 				int, cred_t *, int (*)(vnode_t *, page_t *,
   1624 				u_offset_t, size_t, int, cred_t *));
   1625 extern void	nfs4_async_commit(vnode_t *, page_t *, offset3, count3,
   1626 				cred_t *, void (*)(vnode_t *, page_t *,
   1627 				offset3, count3, cred_t *));
   1628 extern void	nfs4_async_inactive(vnode_t *, cred_t *);
   1629 extern void	nfs4_inactive_thread(mntinfo4_t *mi);
   1630 extern void	nfs4_inactive_otw(vnode_t *, cred_t *);
   1631 extern int	nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *);
   1632 
   1633 extern int	nfs4_setopts(vnode_t *, model_t, struct nfs_args *);
   1634 extern void	nfs4_mnt_kstat_init(struct vfs *);
   1635 
   1636 extern void	nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *);
   1637 extern int	nfs4_attr_otw(vnode_t *, nfs4_tag_type_t,
   1638 				nfs4_ga_res_t *, attrmap4 *, cred_t *);
   1639 
   1640 extern void	nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t);
   1641 extern void	nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *,
   1642 				hrtime_t, cred_t *, int,
   1643 				change_info4 *);
   1644 extern void	nfs4_purge_rddir_cache(vnode_t *);
   1645 extern void	nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *);
   1646 extern void	nfs4_purge_caches(vnode_t *, int, cred_t *, int);
   1647 extern void	nfs4_purge_stale_fh(int, vnode_t *, cred_t *);
   1648 
   1649 extern void	nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *);
   1650 extern void	nfs4_update_paths(vnode_t *, char *, vnode_t *, char *,
   1651 			vnode_t *);
   1652 
   1653 extern void	nfs4args_copen_free(OPEN4cargs *);
   1654 
   1655 extern void	nfs4_printfhandle(nfs4_fhandle_t *);
   1656 
   1657 extern void	nfs_free_mi4(mntinfo4_t *);
   1658 extern servinfo4_t *new_servinfo4(mntinfo4_t *, char *, struct knetconfig *,
   1659 			struct netbuf *, int);
   1660 extern void	sv4_free(servinfo4_t *);
   1661 
   1662 extern void	nfs4_mi_zonelist_add(mntinfo4_t *);
   1663 extern int	nfs4_mi_zonelist_remove(mntinfo4_t *);
   1664 extern int 	nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *);
   1665 extern void	nfs4_secinfo_init(void);
   1666 extern void	nfs4_secinfo_fini(void);
   1667 extern int	nfs4_secinfo_path(mntinfo4_t *, cred_t *, int);
   1668 extern int 	nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *);
   1669 extern void	secinfo_free(sv_secinfo_t *);
   1670 extern void	save_mnt_secinfo(servinfo4_t *);
   1671 extern void	check_mnt_secinfo(servinfo4_t *, vnode_t *);
   1672 extern int	vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int,
   1673     enum nfs_opnum4, attrmap4 *, int, file_layouthint4 *);
   1674 extern int	nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *,
   1675 			int, cred_t *);
   1676 extern void	nfs4_write_error(vnode_t *, int, cred_t *);
   1677 extern void	nfs4_lockcompletion(vnode_t *, int);
   1678 extern bool_t	nfs4_map_lost_lock_conflict(vnode_t *);
   1679 extern int	vtodv(vnode_t *, vnode_t **, cred_t *, bool_t);
   1680 extern void	nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *,
   1681 		    bool_t, bool_t *, nfs4_open_owner_t *, bool_t,
   1682 		    nfs4_error_t *, int *);
   1683 extern void	nfs4_error_zinit(nfs4_error_t *);
   1684 extern void	nfs4_error_init(nfs4_error_t *, int);
   1685 extern void	nfs4_free_args(struct nfs_args *);
   1686 extern void	nfs4_error_set(nfs4_error_t *, enum clnt_stat, enum nfsstat4);
   1687 
   1688 extern void 	mi_hold(mntinfo4_t *);
   1689 extern void	mi_rele(mntinfo4_t *);
   1690 
   1691 extern sec_data_t	*copy_sec_data(sec_data_t *);
   1692 extern gss_clntdata_t	*copy_sec_data_gss(gss_clntdata_t *);
   1693 
   1694 #ifdef DEBUG
   1695 extern int	nfs4_consistent_type(vnode_t *);
   1696 #endif
   1697 
   1698 extern void	nfs4_init_dot_entries(void);
   1699 extern void	nfs4_destroy_dot_entries(void);
   1700 extern struct nfs4_callback_globals	*nfs4_get_callback_globals(void);
   1701 extern int	nfs4_commit(vnode_t *, page_t *, offset4, count4, cred_t *);
   1702 extern int	nfs4_commit_normal(vnode_t *, page_t *, offset4, count4,
   1703     cred_t *);
   1704 
   1705 extern struct nfs4_server nfs4_server_lst;
   1706 
   1707 extern clock_t nfs_write_error_interval;
   1708 
   1709 #endif /* _KERNEL */
   1710 
   1711 /*
   1712  * Flags for nfs4getfh_otw.
   1713  */
   1714 
   1715 #define	NFS4_GETFH_PUBLIC	0x01
   1716 #define	NFS4_GETFH_NEEDSOP	0x02
   1717 
   1718 /*
   1719  * Found through rnodes.
   1720  *
   1721  * The os_open_ref_count keeps track the number of open file descriptor
   1722  * refernces on this data structure.  It will be bumped for any successful
   1723  * OTW OPEN call and any OPEN call that determines the OTW call is not
   1724  * necessary and the open stream hasn't just been created (see
   1725  * nfs4_is_otw_open_necessary).
   1726  *
   1727  * os_mapcnt is a count of the number of mmapped pages for a particular
   1728  * open stream; this in conjunction w/ os_open_ref_count is used to
   1729  * determine when to do a close to the server.  This is necessary because
   1730  * of the semantics of doing open, mmap, close; the OTW close must be wait
   1731  * until all open and mmap references have vanished.
   1732  *
   1733  * 'os_valid' tells us whether this structure is about to be freed or not,
   1734  * if it is then don't return it in find_open_stream().
   1735  *
   1736  * 'os_final_close' is set when a CLOSE OTW was attempted.  This is needed
   1737  * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE
   1738  * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE.  It
   1739  * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE
   1740  * that tried to close OTW but failed, and left the state cleanup to
   1741  * nfs4_inactive/CLOSE_FORCE.
   1742  *
   1743  * 'os_force_close' is used to let us know if an intervening thread came
   1744  * and reopened the open stream after we decided to issue a CLOSE_FORCE,
   1745  * but before we could actually process the CLOSE_FORCE.
   1746  *
   1747  * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the
   1748  * lost state queue.
   1749  *
   1750  * 'open_stateid' is set the last open stateid returned by the server unless
   1751  * 'os_delegation' is 1, in which case 'open_stateid' refers to the
   1752  * delegation stateid returned by the server.  This is used in cases where the
   1753  * client tries to OPEN a file but already has a suitable delegation, so we
   1754  * just stick the delegation stateid in the open stream.
   1755  *
   1756  * os_dc_openacc are open access bits which have been granted to the
   1757  * open stream by virtue of a delegation, but which have not been seen
   1758  * by the server.  This applies even if the open stream does not have
   1759  * os_delegation set.  These bits are used when setting file locks to
   1760  * determine whether an open with CLAIM_DELEGATE_CUR needs to be done
   1761  * before the lock request can be sent to the server.  See
   1762  * nfs4frlock_check_deleg().
   1763  *
   1764  * 'os_mmap_read/write' keep track of the read and write access our memory
   1765  * maps require.  We need to keep track of this so we can provide the proper
   1766  * access bits in the open/mmap/close/reboot/reopen case.
   1767  *
   1768  * 'os_failed_reopen' tells us that we failed to successfully reopen this
   1769  * open stream; therefore, we should not use this open stateid as it is
   1770  * not valid anymore. This flag is also used to indicate an unsuccessful
   1771  * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR.
   1772  *
   1773  * If 'os_orig_oo_name' is different than os_open_owner's oo_name
   1774  * then this tells us that this open stream's open owner used a
   1775  * bad seqid (that is, got NFS4ERR_BAD_SEQID).  If different, this open
   1776  * stream will no longer be used for future OTW state releasing calls.
   1777  *
   1778  * Lock ordering:
   1779  * rnode4_t::r_os_lock > os_sync_lock
   1780  * os_sync_lock > rnode4_t::r_statelock
   1781  * os_sync_lock > rnode4_t::r_statev4_lock
   1782  * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call)
   1783  *
   1784  * The 'os_sync_lock' protects:
   1785  *	open_stateid
   1786  *	os_dc_openacc
   1787  *	os_delegation
   1788  *	os_failed_reopen
   1789  *	os_final_close
   1790  *	os_force_close
   1791  *	os_mapcnt
   1792  *	os_mmap_read
   1793  *	os_mmap_write
   1794  *	os_open_ref_count
   1795  *	os_pending_close
   1796  *	os_share_acc_read
   1797  *	os_share_acc_write
   1798  *	os_share_deny_none
   1799  *	os_share_deny_read
   1800  *	os_share_deny_write
   1801  *	os_ref_count
   1802  *	os_valid
   1803  *
   1804  * The rnode4_t::r_os_lock protects:
   1805  *	os_node
   1806  *
   1807  * These fields are set at creation time and
   1808  * read only after that:
   1809  *	os_open_owner
   1810  *	os_orig_oo_name
   1811  */
   1812 typedef struct nfs4_open_stream {
   1813 	uint64_t		os_share_acc_read;
   1814 	uint64_t		os_share_acc_write;
   1815 	uint64_t		os_mmap_read;
   1816 	uint64_t		os_mmap_write;
   1817 	uint32_t		os_share_deny_none;
   1818 	uint32_t		os_share_deny_read;
   1819 	uint32_t		os_share_deny_write;
   1820 	stateid4		open_stateid;
   1821 	int			os_dc_openacc;
   1822 	int			os_ref_count;
   1823 	unsigned		os_valid:1;
   1824 	unsigned 		os_delegation:1;
   1825 	unsigned		os_final_close:1;
   1826 	unsigned 		os_pending_close:1;
   1827 	unsigned 		os_failed_reopen:1;
   1828 	unsigned		os_force_close:1;
   1829 	int			os_open_ref_count;
   1830 	long			os_mapcnt;
   1831 	list_node_t		os_node;
   1832 	struct nfs4_open_owner	*os_open_owner;
   1833 	uint64_t		os_orig_oo_name;
   1834 	kmutex_t		os_sync_lock;
   1835 } nfs4_open_stream_t;
   1836 
   1837 /*
   1838  * This structure describes the format of the lock_owner_name
   1839  * field of the lock owner.
   1840  */
   1841 
   1842 typedef struct nfs4_lo_name {
   1843 	uint64_t	ln_seq_num;
   1844 	pid_t		ln_pid;
   1845 } nfs4_lo_name_t;
   1846 
   1847 /*
   1848  * Flags for lo_flags.
   1849  */
   1850 #define	NFS4_LOCK_SEQID_INUSE	0x1
   1851 #define	NFS4_BAD_SEQID_LOCK	0x2
   1852 
   1853 /*
   1854  * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs
   1855  * off the rnode.  If the links are NULL it means this object is not on the
   1856  * list.
   1857  *
   1858  * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and
   1859  * didn't get a response back.  This is used to figure out if we have
   1860  * possible remote v4 locks, so that we can clean up at process exit.  In
   1861  * theory, the client should be able to figure out if the server received
   1862  * the request (based on what seqid works), so maybe we can get rid of this
   1863  * flag someday.
   1864  *
   1865  * 'lo_ref_count' tells us how many processes/threads are using this data
   1866  * structure.  The rnode's list accounts for one reference.
   1867  *
   1868  * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the
   1869  * data structure.  It is then set to NFS4_PERM_CREATED when a lock request
   1870  * is successful using this lock owner structure.  We need to keep 'temporary'
   1871  * lock owners around so we can properly keep the lock seqid synchronization
   1872  * when multiple processes/threads are trying to create the lock owner for the
   1873  * first time (especially with the DENIED error case).  Once
   1874  * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change.
   1875  *
   1876  * 'lo_valid' tells us whether this structure is about to be freed or not,
   1877  * if it is then don't return it from find_lock_owner().
   1878  *
   1879  * Retrieving and setting of 'lock_seqid' is protected by the
   1880  * NFS4_LOCK_SEQID_INUSE flag.  Waiters for NFS4_LOCK_SEQID_INUSE should
   1881  * use 'lo_cv_seqid_sync'.
   1882  *
   1883  * The setting of 'lock_stateid' is protected by the
   1884  * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'.  The retrieving of the
   1885  * 'lock_stateid' is protected by 'lo_lock', with the additional
   1886  * requirement that the calling function can handle NFS4ERR_OLD_STATEID and
   1887  * NFS4ERR_BAD_STATEID as appropiate.
   1888  *
   1889  * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock
   1890  * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID).  With this set,
   1891  * this lock owner will no longer be used for future OTW calls.  Once set,
   1892  * it is never unset.
   1893  *
   1894  * Lock ordering:
   1895  * rnode4_t::r_statev4_lock > lo_lock
   1896  */
   1897 typedef struct nfs4_lock_owner {
   1898 	struct nfs4_lock_owner	*lo_next_rnode;
   1899 	struct nfs4_lock_owner	*lo_prev_rnode;
   1900 	int			lo_pid;
   1901 	stateid4		lock_stateid;
   1902 	seqid4			lock_seqid;
   1903 	/*
   1904 	 * Fix this to always be 12 bytes
   1905 	 */
   1906 	nfs4_lo_name_t		lock_owner_name;
   1907 	int			lo_ref_count;
   1908 	int			lo_valid;
   1909 	int			lo_pending_rqsts;
   1910 	int			lo_just_created;
   1911 	int			lo_flags;
   1912 	kcondvar_t		lo_cv_seqid_sync;
   1913 	kmutex_t		lo_lock;
   1914 	kthread_t		*lo_seqid_holder; /* debugging aid */
   1915 } nfs4_lock_owner_t;
   1916 
   1917 /* for nfs4_lock_owner_t lookups */
   1918 typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t;
   1919 
   1920 /* Number of times to retry a call that fails with state independent error */
   1921 #define	NFS4_NUM_RECOV_RETRIES	3
   1922 
   1923 typedef enum {
   1924 	NO_SID,
   1925 	DEL_SID,
   1926 	LOCK_SID,
   1927 	OPEN_SID,
   1928 	SPEC_SID
   1929 } nfs4_stateid_type_t;
   1930 
   1931 typedef struct nfs4_stateid_types {
   1932 	stateid4 d_sid;
   1933 	stateid4 l_sid;
   1934 	stateid4 o_sid;
   1935 	nfs4_stateid_type_t cur_sid_type;
   1936 } nfs4_stateid_types_t;
   1937 
   1938 /*
   1939  * Flags used to determine stateid we want.
   1940  */
   1941 
   1942 #define	GETSID_TRYNEXT	0x00000001	/* Try next stateid */
   1943 #define	GETSID_LAYOUT	0x00000002	/* Need Stateid For Layoutget */
   1944 
   1945 
   1946 /*
   1947  * Per-zone data for dealing with callbacks.  Included here solely for the
   1948  * benefit of MDB.
   1949  */
   1950 struct nfs4_callback_stats {
   1951 	kstat_named_t	delegations;
   1952 	kstat_named_t	cb_getattr;
   1953 	kstat_named_t	cb_recall;
   1954 	kstat_named_t	cb_null;
   1955 	kstat_named_t	cb_dispatch;
   1956 	kstat_named_t	delegaccept_r;
   1957 	kstat_named_t	delegaccept_rw;
   1958 	kstat_named_t	delegreturn;
   1959 	kstat_named_t	callbacks;
   1960 	kstat_named_t	claim_cur;
   1961 	kstat_named_t	claim_cur_ok;
   1962 	kstat_named_t	recall_trunc;
   1963 	kstat_named_t	recall_failed;
   1964 	kstat_named_t	return_limit_write;
   1965 	kstat_named_t	return_limit_addmap;
   1966 	kstat_named_t	deleg_recover;
   1967 	kstat_named_t	cb_illegal;
   1968 	kstat_named_t	cb_sequence;
   1969 };
   1970 
   1971 struct nfs41_cb_info {
   1972 	rpcprog_t		cb_prog;
   1973 	SVC_DISPATCH		*cb_dispatch;
   1974 	CLIENT			*cb_client;
   1975 	struct nfs4_clnt	*cb_nfscl;
   1976 	int			cb_state;
   1977 	kmutex_t		cb_cbconn_lock;
   1978 	kcondvar_t		cb_cbconn_wait;	/* cbconn heartbeat */
   1979 	int			cb_cbconn_exit;
   1980 	int			cb_refcnt;
   1981 	kmutex_t		cb_reflock;
   1982 	kcondvar_t		cb_destroy_wait;
   1983 } nfs41_cb_info_t;
   1984 
   1985 struct nfs4_callback_globals {
   1986 	kmutex_t nfs4_cb_lock;
   1987 	kmutex_t nfs4_dlist_lock;
   1988 	int nfs4_program_hint;
   1989 	/* this table maps the program number to the nfs4_server structure */
   1990 	struct nfs4_server **nfs4prog2server;
   1991 	struct nfs41_cb_info **nfs4prog2cbinfo;
   1992 	list_t nfs4_dlist;
   1993 	list_t nfs4_cb_ports;
   1994 	struct nfs4_callback_stats nfs4_callback_stats;
   1995 #ifdef DEBUG
   1996 	int nfs4_dlistadd_c;
   1997 	int nfs4_dlistclean_c;
   1998 #endif
   1999 };
   2000 
   2001 typedef enum {
   2002 	CLOSE_NORM,
   2003 	CLOSE_DELMAP,
   2004 	CLOSE_FORCE,
   2005 	CLOSE_RESEND,
   2006 	CLOSE_AFTER_RESEND
   2007 } nfs4_close_type_t;
   2008 
   2009 /*
   2010  * Structure to hold the bad seqid information that is passed
   2011  * to the recovery framework.
   2012  */
   2013 typedef struct nfs4_bseqid_entry {
   2014 	nfs4_open_owner_t	*bs_oop;
   2015 	nfs4_lock_owner_t	*bs_lop;
   2016 	vnode_t			*bs_vp;
   2017 	pid_t			bs_pid;
   2018 	nfs4_tag_type_t		bs_tag;
   2019 	seqid4			bs_seqid;
   2020 	list_node_t		bs_node;
   2021 } nfs4_bseqid_entry_t;
   2022 
   2023 typedef struct nfs4_tagswap {
   2024 	sessionid4 ts_oldtag;
   2025 	sessionid4 *ts_newtag;
   2026 } nfs4_tagswap_t;
   2027 
   2028 #ifdef _KERNEL
   2029 
   2030 extern void	nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int,
   2031 		    nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t,
   2032 		    size_t, uint_t, uint_t);
   2033 extern void	nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *);
   2034 extern void	nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4);
   2035 extern void	open_owner_hold(nfs4_open_owner_t *);
   2036 extern void	open_owner_rele(nfs4_open_owner_t *);
   2037 extern nfs4_open_stream_t	*find_or_create_open_stream(nfs4_open_owner_t *,
   2038 					struct rnode4 *, int *);
   2039 extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *,
   2040 				struct rnode4 *);
   2041 extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop,
   2042 				struct rnode4 *rp);
   2043 extern void	open_stream_hold(nfs4_open_stream_t *);
   2044 extern void	open_stream_rele(nfs4_open_stream_t *, struct rnode4 *);
   2045 extern int	nfs4close_all(vnode_t *, cred_t *);
   2046 extern void	lock_owner_hold(nfs4_lock_owner_t *);
   2047 extern void	lock_owner_rele(nfs4_lock_owner_t *);
   2048 extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t);
   2049 extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t);
   2050 extern void	nfs4_rnode_remove_lock_owner(struct rnode4 *,
   2051 			nfs4_lock_owner_t *);
   2052 extern void	nfs4_flush_lock_owners(struct rnode4 *);
   2053 extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t);
   2054 extern void	nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *,
   2055 		    nfs4_tag_type_t);
   2056 extern void	nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *);
   2057 extern void	nfs4_end_open_seqid_sync(nfs4_open_owner_t *);
   2058 extern int	nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *);
   2059 extern void	nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *);
   2060 extern int	nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *);
   2061 extern void	nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *,
   2062 			nfs4_open_stream_t *, mntinfo4_t *, locker4 *);
   2063 extern void	nfs4_destroy_open_owner(nfs4_open_owner_t *);
   2064 
   2065 extern void		nfs4_renew_lease_thread(nfs4_server_t *);
   2066 extern void		nfs4_sequence_heartbeat_thread(nfs4_server_t *);
   2067 extern void		nfs4_cbconn_thread(nfs4_server_t *);
   2068 extern nfs4_server_t	*find_nfs4_server(mntinfo4_t *);
   2069 extern nfs4_server_t	*find_nfs4_server_nolock(mntinfo4_t *);
   2070 extern nfs4_server_t	*find_nfs4_server_all(mntinfo4_t *, int all);
   2071 extern nfs4_server_t	*find_nfs4_server_by_servinfo4(servinfo4_t *);
   2072 extern nfs4_server_t	*new_nfs4_server(servinfo4_t *,	cred_t *);
   2073 extern nfs4_server_t	*add_new_nfs4_server(servinfo4_t *, cred_t *);
   2074 extern void		nfs4_mark_srv_dead(nfs4_server_t *, uint_t);
   2075 extern nfs4_server_t	*servinfo4_to_nfs4_server(servinfo4_t *);
   2076 extern void		nfs4_inc_state_ref_count(mntinfo4_t *);
   2077 extern void		nfs4_inc_state_ref_count_nolock(nfs4_server_t *,
   2078 				mntinfo4_t *);
   2079 extern void		nfs4_dec_state_ref_count(mntinfo4_t *);
   2080 extern void		nfs4_dec_state_ref_count_nolock(nfs4_server_t *,
   2081 				mntinfo4_t *);
   2082 extern clientid4	mi2clientid(mntinfo4_t *);
   2083 extern int		nfs4_server_in_recovery(nfs4_server_t *);
   2084 extern bool_t		nfs4_server_vlock(nfs4_server_t *, int);
   2085 extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *);
   2086 extern uint64_t		nfs4_get_new_oo_name(void);
   2087 extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *);
   2088 extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *);
   2089 extern void	nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *,
   2090 			int, u_offset_t, cred_t *, nfs4_error_t *,
   2091 			nfs4_lost_rqst_t *, int *);
   2092 extern void	nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *,
   2093 		    nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *,
   2094 		    vnode_t *, int, int);
   2095 extern void	nfs4_open_downgrade(int, int, nfs4_open_owner_t *,
   2096 		    nfs4_open_stream_t *, vnode_t *, cred_t *,
   2097 		    nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *);
   2098 extern seqid4	nfs4_get_open_seqid(nfs4_open_owner_t *);
   2099 extern cred_t	*nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *);
   2100 extern void	nfs4_init_stateid_types(nfs4_stateid_types_t *);
   2101 extern void	nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *);
   2102 
   2103 extern kmutex_t nfs4_server_lst_lock;
   2104 
   2105 extern void 	nfs4_cleanup_oldsession(mntinfo4_t *, servinfo4_t *,
   2106 		    nfs4_server_t *);
   2107 
   2108 /* flags for nfs4destroy_session */
   2109 #define	N4DS_TERMINATE_HB_THREAD	1
   2110 #define	N4DS_DESTROY_OTW		2
   2111 #define	N4DS_DESTROY_INZONE		4
   2112 
   2113 extern void	nfs4destroy_session(nfs4_server_t *, mntinfo4_t *,
   2114 		    servinfo4_t *, nfs4_error_t *, int);
   2115 extern void	nfs41_cbinfo_rele(struct nfs41_cb_info *);
   2116 extern void	nfs4callback_destroy(nfs4_server_t *);
   2117 extern void	nfs4_callback_init(void);
   2118 extern void	nfs4_callback_fini(void);
   2119 
   2120 extern void	nfs41_cb_args(nfs4_server_t *, struct knetconfig *,
   2121 			CREATE_SESSION4args *);
   2122 extern void 	nfs4_cb_args(nfs4_server_t *, struct knetconfig *,
   2123 			SETCLIENTID4args *);
   2124 extern void	nfs41set_callback(nfs4_server_t *, servinfo4_t *,
   2125 			mntinfo4_t *, cred_t *);
   2126 extern void	nfs4delegreturn_async(struct rnode4 *, int, bool_t);
   2127 
   2128 extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy;
   2129 
   2130 extern void	nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *);
   2131 extern void	nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *);
   2132 extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *);
   2133 extern bool_t	nfs4_fs_active(nfs4_server_t *);
   2134 extern void	nfs4_server_hold(nfs4_server_t *);
   2135 extern void	nfs4_server_rele(nfs4_server_t *);
   2136 extern void	nfs4_server_rele_lockt(nfs4_server_t *);
   2137 extern bool_t	inlease(nfs4_server_t *);
   2138 extern bool_t	nfs4_has_pages(vnode_t *);
   2139 extern void	nfs4_log_badowner(mntinfo4_t *, nfs_opnum4);
   2140 
   2141 #endif /* _KERNEL */
   2142 
   2143 /*
   2144  * Client State Recovery
   2145  */
   2146 
   2147 /*
   2148  * The following defines are used for rs_flags in
   2149  * a nfs4_recov_state_t structure.
   2150  *
   2151  * NFS4_RS_RENAME_HELD		Indicates that the mi_rename_lock was held.
   2152  * NFS4_RS_GRACE_MSG		Set once we have uprintf'ed a grace message.
   2153  * NFS4_RS_DELAY_MSG		Set once we have uprintf'ed a delay message.
   2154  * NFS4_RS_RECALL_HELD1		r_deleg_recall_lock for vp1 was held.
   2155  * NFS4_RS_RECALL_HELD2		r_deleg_recall_lock for vp2 was held.
   2156  * NFS4_RS_NEEDS_RECOVERY	Indicates recovery needed (for debug).
   2157  */
   2158 #define	NFS4_RS_RENAME_HELD	0x000000001
   2159 #define	NFS4_RS_GRACE_MSG	0x000000002
   2160 #define	NFS4_RS_DELAY_MSG	0x000000004
   2161 #define	NFS4_RS_RECALL_HELD1	0x000000008
   2162 #define	NFS4_RS_RECALL_HELD2	0x000000010
   2163 #define	NFS4_RS_NEEDS_RECOVERY	0x000000020
   2164 
   2165 #define	NFS4_RS_RECOVSTR(rs)	\
   2166 	(((rs)->rs_flags & NFS4_RS_NEEDS_RECOVERY) ? "recov" : "first")
   2167 
   2168 /*
   2169  * Information that is retrieved from nfs4_start_op() and that is
   2170  * passed into nfs4_end_op().
   2171  *
   2172  * rs_sp is a reference to the nfs4_server that was found, or NULL.
   2173  *
   2174  * rs_num_retry_despite_err is the number times client retried an
   2175  * OTW op despite a recovery error.  It is only incremented for hints
   2176  * exempt to normal R4RECOVERR processing
   2177  * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN).  (XXX this special-case code
   2178  * needs review for possible removal.)
   2179  * It is initialized wherever nfs4_recov_state_t is declared -- usually
   2180  * very near initialization of rs_flags.
   2181  */
   2182 typedef struct {
   2183 	nfs4_server_t	*rs_sp;
   2184 	int		rs_flags;
   2185 	int		rs_num_retry_despite_err;
   2186 } nfs4_recov_state_t;
   2187 
   2188 /*
   2189  * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root.
   2190  */
   2191 
   2192 #define	NFS4_REMAP_CKATTRS	1
   2193 #define	NFS4_REMAP_NEEDSOP	2
   2194 
   2195 #ifdef _KERNEL
   2196 
   2197 extern int	nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int,
   2198 			vnode_t *, int, int *, int, nfs4_recov_state_t *);
   2199 extern void	nfs4exchange_id(struct mntinfo4 *, struct cred *, bool_t,
   2200 			nfs4_error_t *);
   2201 extern void 	nfs4create_session(mntinfo4_t *, servinfo4_t *, cred_t *,
   2202 			nfs4_server_t *, nfs4_error_t *);
   2203 extern int	nfs4bind_conn_to_session(nfs4_server_t *, servinfo4_t *,
   2204 			struct mntinfo4 *, cred_t *, channel_dir_from_client4);
   2205 extern int	nfs4_tag_ctl(nfs4_server_t *, mntinfo4_t *, servinfo4_t *,
   2206 			sessionid4, int, cred_t *);
   2207 extern void	nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *,
   2208 			open_claim_type4, bool_t, bool_t);
   2209 extern void	nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int);
   2210 extern void	nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int,
   2211 			nfs4_error_t *);
   2212 extern void	nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int,
   2213 			nfs4_error_t *);
   2214 extern int	nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t,
   2215 			vnode_t *, cred_t *, vnode_t **, int);
   2216 extern void	nfs4_fail_recov(vnode_t *, char *, int, nfsstat4);
   2217 
   2218 extern int	nfs4_recov_marks_dead(nfsstat4);
   2219 extern char	*nfs4_recov_action_to_str(nfs4_recov_t);
   2220 
   2221 /*
   2222  * In sequence, code desiring to unmount an ephemeral tree must
   2223  * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate,
   2224  * and nfs4_ephemeral_umount_unlock. The _unlock must also be
   2225  * called on all error paths that occur before it would naturally
   2226  * be invoked.
   2227  *
   2228  * The caller must also provde a pointer to a boolean to keep track
   2229  * of whether or not the code in _unlock is to be ran.
   2230  */
   2231 extern void	nfs4_ephemeral_umount_activate(mntinfo4_t *,
   2232     bool_t *, bool_t *, nfs4_ephemeral_tree_t **);
   2233 extern int	nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *,
   2234     bool_t *, bool_t *, nfs4_ephemeral_tree_t **);
   2235 extern void	nfs4_ephemeral_umount_unlock(bool_t *, bool_t *,
   2236     nfs4_ephemeral_tree_t **);
   2237 
   2238 extern int	nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp);
   2239 
   2240 extern int	wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t,
   2241 			nfs4_recov_state_t *);
   2242 extern void	nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *);
   2243 extern void	nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t,
   2244 		    int, nfsstat4);
   2245 extern time_t	nfs4err_delay_time;
   2246 extern void	nfs4_set_grace_wait(mntinfo4_t *);
   2247 extern void	nfs4_set_delay_wait(vnode_t *);
   2248 extern int	nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *, int);
   2249 extern int	nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *, int);
   2250 extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *,
   2251 		    nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t,
   2252 		    seqid4);
   2253 
   2254 extern void	nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *,
   2255 			nfs4_error_t *);
   2256 extern void	nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *,
   2257 			nfs4_server_t *);
   2258 extern int	nfs4_rpc_retry_error(int);
   2259 extern int	nfs4_try_failover(nfs4_error_t *);
   2260 extern void	nfs4_free_msg(nfs4_debug_msg_t *);
   2261 extern void	nfs4_mnt_recov_kstat_init(vfs_t *);
   2262 extern void	nfs4_mi_kstat_inc_delay(mntinfo4_t *);
   2263 extern void	nfs4_mi_kstat_inc_no_grace(mntinfo4_t *);
   2264 extern char	*nfs4_stat_to_str(nfsstat4);
   2265 extern void	nfs4exchange_id_otw(mntinfo4_t *, servinfo4_t *, cred_t *,
   2266 			nfs4_server_t *, nfs4_error_t *, int *);
   2267 extern void	nfs4session_init(void);
   2268 extern void	nfs4_pnfs_init_n4s(struct nfs4_server *);
   2269 extern void	pnfs_rele_device(struct nfs4_server *, struct devnode *);
   2270 
   2271 extern void	nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *,
   2272 		    uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t,
   2273 		    nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4);
   2274 extern void	nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4,
   2275 		    nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *);
   2276 #pragma	rarely_called(nfs4_queue_event)
   2277 #pragma	rarely_called(nfs4_queue_fact)
   2278 
   2279 /* Used for preformed "." and ".." dirents */
   2280 extern char	*nfs4_dot_entries;
   2281 extern char	*nfs4_dot_dot_entry;
   2282 
   2283 #ifdef	DEBUG
   2284 extern uint_t	nfs4_tsd_key;
   2285 #endif
   2286 
   2287 #endif /* _KERNEL */
   2288 
   2289 /*
   2290  * Filehandle management.
   2291  *
   2292  * Filehandles can change in v4, so rather than storing the filehandle
   2293  * directly in the rnode, etc., we manage the filehandle through one of
   2294  * these objects.
   2295  * Locking: sfh_fh and sfh_tree is protected by the filesystem's
   2296  * mi_fh_lock.  The reference count and flags are protected by sfh_lock.
   2297  * sfh_mi is read-only.
   2298  *
   2299  * mntinfo4_t::mi_fh_lock > sfh_lock.
   2300  */
   2301 
   2302 typedef struct nfs4_sharedfh {
   2303 	nfs_fh4 sfh_fh;			/* key and current filehandle */
   2304 	kmutex_t sfh_lock;
   2305 	uint_t sfh_refcnt;		/* reference count */
   2306 	uint_t sfh_flags;
   2307 	mntinfo4_t *sfh_mi;		/* backptr to filesystem */
   2308 	avl_node_t sfh_tree;		/* used by avl package */
   2309 } nfs4_sharedfh_t;
   2310 
   2311 #define	SFH4_SAME(sfh1, sfh2)	((sfh1) == (sfh2))
   2312 
   2313 /*
   2314  * Flags.
   2315  */
   2316 #define	SFH4_IN_TREE	0x1		/* currently in an AVL tree */
   2317 
   2318 #ifdef _KERNEL
   2319 
   2320 extern void sfh4_createtab(avl_tree_t *);
   2321 extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *);
   2322 extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *,
   2323 				nfs4_sharedfh_t *);
   2324 extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *);
   2325 extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *);
   2326 extern void sfh4_hold(nfs4_sharedfh_t *);
   2327 extern void sfh4_rele(nfs4_sharedfh_t **);
   2328 extern void sfh4_printfhandle(const nfs4_sharedfh_t *);
   2329 
   2330 #endif
   2331 
   2332 /*
   2333  * Path and file name management.
   2334  *
   2335  * This type stores the name of an entry in the filesystem and keeps enough
   2336  * information that it can provide a complete path.  All fields are
   2337  * protected by fn_lock, except for the reference count, which is managed
   2338  * using atomic add/subtract.
   2339  *
   2340  * Additionally shared filehandle for this fname is stored.
   2341  * Normally, fn_get() when it creates this fname stores the passed in
   2342  * shared fh in fn_sfh by doing sfh_hold. Similarly the path which
   2343  * destroys this fname releases the reference on this fh by doing sfh_rele.
   2344  *
   2345  * fn_get uses the fn_sfh to refine the comparision in cases
   2346  * where we have matched the name but have differing file handles,
   2347  * this normally happens due to
   2348  *
   2349  *	1. Server side rename of a file/directory.
   2350  *	2. Another client renaming a file/directory on the server.
   2351  *
   2352  * Differing names but same filehandle is possible as in the case of hardlinks,
   2353  * but differing filehandles with same name component will later confuse
   2354  * the client and can cause various panics.
   2355  *
   2356  * Lock order: child and then parent.
   2357  */
   2358 
   2359 typedef struct nfs4_fname {
   2360 	struct nfs4_fname *fn_parent;	/* parent name; null if fs root */
   2361 	char *fn_name;			/* the actual name */
   2362 	ssize_t fn_len;			/* strlen(fn_name) */
   2363 	uint32_t fn_refcnt;		/* reference count */
   2364 	kmutex_t fn_lock;
   2365 	avl_node_t fn_tree;
   2366 	avl_tree_t fn_children;		/* children, if any */
   2367 	nfs4_sharedfh_t *fn_sfh;	/* The fh for this fname */
   2368 } nfs4_fname_t;
   2369 
   2370 #ifdef _KERNEL
   2371 
   2372 extern vnode_t	nfs4_xattr_notsupp_vnode;
   2373 #define	NFS4_XATTR_DIR_NOTSUPP	&nfs4_xattr_notsupp_vnode
   2374 
   2375 extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *, nfs4_sharedfh_t *);
   2376 extern void fn_hold(nfs4_fname_t *);
   2377 extern void fn_rele(nfs4_fname_t **);
   2378 extern char *fn_name(nfs4_fname_t *);
   2379 extern char *fn_path(nfs4_fname_t *);
   2380 extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *);
   2381 extern nfs4_fname_t *fn_parent(nfs4_fname_t *);
   2382 #endif
   2383 
   2384 /*
   2385  * Per-zone data for managing client handles, included in this file for the
   2386  * benefit of MDB.
   2387  */
   2388 struct nfs4_clnt {
   2389 	struct chhead	*nfscl_chtable4;
   2390 	kmutex_t	nfscl_chtable4_lock;
   2391 	zoneid_t	nfscl_zoneid;
   2392 	list_node_t	nfscl_node;
   2393 	/*
   2394 	 * nfscl_stat[0] for minor version 0
   2395 	 * nfscl_stat[1] for minor version 1
   2396 	 */
   2397 	struct clstat4 nfscl_stat[NFS4_MINORVERSMAX + 1];
   2398 };
   2399 
   2400 /*
   2401  * New recovery interfaces & structures
   2402  */
   2403 typedef struct nfs4_call {
   2404 	mntinfo4_t	*nc_mi;
   2405 	vnode_t		*nc_vp1;
   2406 	vnode_t		*nc_vp2;
   2407 
   2408 	/* needed by nfs4_start_fop */
   2409 	nfs4_op_hint_t	nc_ophint;
   2410 	int		nc_start_recov;
   2411 
   2412 	/* needed by nfs4_needs_recovery */
   2413 	int		nc_stateful;
   2414 	nfs4_error_t	nc_e;
   2415 
   2416 	/* needed by start_recovery */
   2417 	nfs_opnum4	nc_opnum;
   2418 	nfs4_lost_rqst_t *nc_lost_rqst;
   2419 	nfs4_bseqid_entry_t *nc_bseqid_rqst;
   2420 
   2421 	/* needed by rfs4call */
   2422 	int		nc_doqueue[1];
   2423 	int		nc_rfs4call_flags;
   2424 	cred_t		*nc_cr;
   2425 	servinfo4_t	*nc_svp;
   2426 	nfs4_server_t	*nc_slot_srv;
   2427 	slot_ent_t	*nc_slot_ent;
   2428 
   2429 	/* new pnfs stuffs */
   2430 	servinfo4_t	*nc_ds_servinfo;	/* NULL if call targets MDS */
   2431 	nfs4_server_t	*nc_ds_nfs4_srv;	/* NULL if call targets MDS */
   2432 	kmutex_t	nc_lock[1];
   2433 	uint_t		nc_count;
   2434 	int		nc_needs_recovery;
   2435 	int		nc_wait_for_recovery;
   2436 
   2437 	COMPOUND4args_clnt	nc_args;
   2438 	COMPOUND4res_clnt	nc_res;
   2439 	int			nc_flags;
   2440 } nfs4_call_t;
   2441 
   2442 #define	NFS4_CALL_FLAG_RESFREE		0x01	/* need to free nc_res */
   2443 #define	NFS4_CALL_FLAG_SEQADDED		0x02	/* sequence op added */
   2444 #define	NFS4_CALL_FLAG_RCV_DONTBLOCK	0x04	/* Don't block, return EAGAIN */
   2445 #define	NFS4_CALL_FLAG_SLOT_HELD	0x08	/* slot is held */
   2446 #define	NFS4_CALL_FLAG_SLOT_RECALLED	0x10	/* slot was recalled */
   2447 #define	NFS4_CALL_FLAG_SLOT_INCR	0x20	/* increment slot seq */
   2448 
   2449 #ifdef _KERNEL
   2450 extern nfs4_call_t *nfs4_call_init(int, nfs_opnum4, nfs4_op_hint_t, int,
   2451     mntinfo4_t *, vnode_t *, vnode_t *, cred_t *);
   2452 extern void nfs4_call_hold(nfs4_call_t *);
   2453 extern void nfs4_call_rele(nfs4_call_t *);
   2454 extern void nfs4_call_slot_release(nfs4_call_t *);
   2455 extern void nfs4_call_slot_clear(nfs4_call_t *);
   2456 extern void nfs4_call_opresfree(nfs4_call_t *);
   2457 extern COMPOUND4node_clnt *nfs4_op_generic(nfs4_call_t *, nfs_opnum4);
   2458 extern SEQUENCE4res *nfs4_op_sequence(nfs4_call_t *);
   2459 extern PUTFH4res *nfs4_op_cputfh(nfs4_call_t *, nfs4_sharedfh_t *);
   2460 extern GETFH4res *nfs4_op_getfh(nfs4_call_t *);
   2461 extern SAVEFH4res *nfs4_op_savefh(nfs4_call_t *);
   2462 extern RESTOREFH4res *nfs4_op_restorefh(nfs4_call_t *);
   2463 extern ACCESS4res *nfs4_op_access(nfs4_call_t *, uint32_t);
   2464 extern GETATTR4res *nfs4_op_getattr(nfs4_call_t *, attrmap4);
   2465 extern OPEN4res *nfs4_op_copen(nfs4_call_t *, OPEN4cargs **);
   2466 extern OPEN_DOWNGRADE4res *nfs4_op_open_downgrade(nfs4_call_t *, stateid4 *,
   2467     seqid4, uint32_t, uint32_t);
   2468 extern CLOSE4res *nfs4_op_close(nfs4_call_t *, seqid4, stateid4);
   2469 extern LAYOUTCOMMIT4res *nfs4_op_layoutcommit(nfs4_call_t *,
   2470     LAYOUTCOMMIT4args **);
   2471 extern WRITE4res *nfs4_op_write(nfs4_call_t *, stable_how4, WRITE4args **);
   2472 extern READ4res *nfs4_op_read(nfs4_call_t *, READ4args **);
   2473 extern SETATTR4res *nfs4_op_setattr(nfs4_call_t *, SETATTR4args **);
   2474 extern VERIFY4res *nfs4_op_verify(nfs4_call_t *, VERIFY4args **);
   2475 extern NVERIFY4res *nfs4_op_nverify(nfs4_call_t *, NVERIFY4args **);
   2476 extern READLINK4res *nfs4_op_readlink(nfs4_call_t *);
   2477 extern REMOVE4res *nfs4_op_cremove(nfs4_call_t *, char *);
   2478 extern LOOKUP4res *nfs4_op_lookup(nfs4_call_t *, utf8string *);
   2479 extern LOOKUP4res *nfs4_op_clookup(nfs4_call_t *, char *);
   2480 extern LOOKUPP4res *nfs4_op_lookupp(nfs4_call_t *);
   2481 extern OPENATTR4res *nfs4_op_openattr(nfs4_call_t *, bool_t);
   2482 extern CREATE4res *nfs4_op_ccreate(nfs4_call_t *, char *, nfs_ftype4, void *,
   2483     CREATE4cargs **);
   2484 extern LINK4res *nfs4_op_clink(nfs4_call_t *, char *);
   2485 extern RENAME4res *nfs4_op_crename(nfs4_call_t *, char *, char *);
   2486 extern READDIR4res_clnt *nfs4_op_readdir(nfs4_call_t *, READDIR4args **);
   2487 extern COMMIT4res *nfs4_op_commit(nfs4_call_t *, offset4, count4);
   2488 extern OPEN_CONFIRM4res *nfs4_op_open_confirm(nfs4_call_t *, seqid4,
   2489     stateid4 *);
   2490 extern LOCK4res *nfs4_op_lock(nfs4_call_t *, LOCK4args **);
   2491 extern LOCKU4res *nfs4_op_locku(nfs4_call_t *, LOCKU4args **);
   2492 extern LOCKT4res *nfs4_op_lockt(nfs4_call_t *, LOCKT4args **);
   2493 extern PUTPUBFH4res *nfs4_op_putpubfh(nfs4_call_t *);
   2494 extern PUTROOTFH4res *nfs4_op_putrootfh(nfs4_call_t *);
   2495 extern SECINFO4res *nfs4_op_secinfo(nfs4_call_t *, component4 *);
   2496 extern SECINFO4res *nfs4_op_csecinfo(nfs4_call_t *, char *);
   2497 extern BIND_CONN_TO_SESSION4res *nfs4_op_bind_conn_to_session(nfs4_call_t *cp,
   2498     sessionid4 *, channel_dir_from_client4, bool_t);
   2499 extern DELEGRETURN4res *nfs4_op_delegreturn(nfs4_call_t *, stateid4 *);
   2500 extern RENEW4res *nfs4_op_renew(nfs4_call_t *, clientid4);
   2501 extern EXCHANGE_ID4res *nfs4_op_exchange_id(nfs4_call_t *, EXCHANGE_ID4args **);
   2502 extern CREATE_SESSION4res *nfs4_op_create_session(nfs4_call_t *,
   2503     CREATE_SESSION4args **);
   2504 extern SETCLIENTID4res *nfs4_op_setclientid(nfs4_call_t *, SETCLIENTID4args **);
   2505 extern SETCLIENTID_CONFIRM4res *nfs4_op_setclientid_confirm(nfs4_call_t *,
   2506     clientid4, verifier4);
   2507 extern RECLAIM_COMPLETE4res *nfs4_op_reclaim_complete(nfs4_call_t *, bool_t);
   2508 extern GETDEVICEINFO4res *nfs4_op_getdeviceinfo(nfs4_call_t *, deviceid4,
   2509     layouttype4, count4, bitmap4);
   2510 extern LAYOUTRETURN4res *nfs4_op_layoutreturn(nfs4_call_t *,
   2511     LAYOUTRETURN4args **);
   2512 extern LAYOUTGET4res *nfs4_op_layoutget(nfs4_call_t *, LAYOUTGET4args **);
   2513 extern GETDEVICELIST4res *nfs4_op_getdevicelist(nfs4_call_t *,
   2514     GETDEVICELIST4args **);
   2515 extern DESTROY_SESSION4res *nfs4_op_destroy_session(nfs4_call_t *, sessionid4);
   2516 
   2517 extern void nfs4lookup_setup(nfs4_call_t *, char *, lkp4_attr_setup_t,
   2518     attrmap4, int);
   2519 extern void nfs4args_lookup_free(nfs4_call_t *);
   2520 extern void rfs4call(nfs4_call_t *, nfs4_error_t *);
   2521 extern int nfs4_start_op(nfs4_call_t *, nfs4_recov_state_t *);
   2522 extern void nfs4_end_op(nfs4_call_t *, nfs4_recov_state_t *);
   2523 extern void nfs4_needs_recovery(nfs4_call_t *);
   2524 extern bool_t nfs4_start_recovery(nfs4_call_t *);
   2525 
   2526 /* interim */
   2527 extern int nfs4_needs_recovery_old(nfs4_error_t *, bool_t, vfs_t *);
   2528 extern bool_t nfs4_start_recovery_old(nfs4_error_t *, struct mntinfo4 *,
   2529     vnode_t *, vnode_t *, nfs4_lost_rqst_t *, nfs_opnum4,
   2530     nfs4_bseqid_entry_t *);
   2531 #endif /* _KERNEL */
   2532 
   2533 #ifdef	__cplusplus
   2534 }
   2535 #endif
   2536 
   2537 #endif /* _NFS4_CLNT_H */
   2538