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