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 2007 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_H
     30 #define	_NFS_NFS_H
     31 
     32 #pragma ident	"@(#)nfs.h	1.152	07/10/25 SMI"
     33 /*	nfs.h 2.38 88/08/19 SMI 	*/
     34 
     35 #include <sys/isa_defs.h>
     36 #include <sys/vfs.h>
     37 #include <sys/stream.h>
     38 #include <rpc/types.h>
     39 #include <sys/types32.h>
     40 #ifdef _KERNEL
     41 #include <rpc/rpc.h>
     42 #include <sys/fcntl.h>
     43 #include <sys/kstat.h>
     44 #include <sys/dirent.h>
     45 #include <sys/zone.h>
     46 #include <sys/tsol/label.h>
     47 #include <sys/nvpair.h>
     48 #include <nfs/mount.h>
     49 #endif
     50 #include <vm/page.h>
     51 #include <rpc/rpc_sztypes.h>
     52 #include <sys/sysmacros.h>
     53 
     54 #ifdef	__cplusplus
     55 extern "C" {
     56 #endif
     57 
     58 /*
     59  * Solaris NFS daemons configuration file location
     60  */
     61 #define	NFSADMIN	"/etc/default/nfs"
     62 
     63 /*
     64  * remote file service numbers
     65  */
     66 #define	NFS_PROGRAM	((rpcprog_t)100003)
     67 #define	NFS_VERSMIN	((rpcvers_t)2)
     68 #define	NFS_VERSMAX	((rpcvers_t)4)
     69 #define	NFS_VERSION	((rpcvers_t)2)
     70 #define	NFS_PORT	2049
     71 
     72 /*
     73  * Used to determine registration and service handling of versions
     74  */
     75 #define	NFS_VERSMIN_DEFAULT	((rpcvers_t)2)
     76 #define	NFS_VERSMAX_DEFAULT	((rpcvers_t)4)
     77 
     78 extern rpcvers_t nfs_versmin;
     79 extern rpcvers_t nfs_versmax;
     80 
     81 /*
     82  * Default delegation setting for the server ==> "on"
     83  */
     84 #define	NFS_SERVER_DELEGATION_DEFAULT	(TRUE)
     85 
     86 /* Maximum size of data portion of a remote request */
     87 #define	NFS_MAXDATA	8192
     88 #define	NFS_MAXNAMLEN	255
     89 #define	NFS_MAXPATHLEN	1024
     90 
     91 /*
     92  * Rpc retransmission parameters
     93  */
     94 #define	NFS_TIMEO	11	/* initial timeout for clts in 10th of a sec */
     95 #define	NFS_RETRIES	5	/* times to retry request */
     96 #define	NFS_COTS_TIMEO	600	/* initial timeout for cots in 10th of a sec */
     97 
     98 /*
     99  * The value of UID_NOBODY/GID_NOBODY presented to the world via NFS.
    100  * UID_NOBODY/GID_NOBODY is translated to NFS_UID_NOBODY/NFS_GID_NOBODY
    101  * when being sent out over the network and NFS_UID_NOBODY/NFS_GID_NOBODY
    102  * is translated to UID_NOBODY/GID_NOBODY when received.
    103  */
    104 #define	NFS_UID_NOBODY	-2
    105 #define	NFS_GID_NOBODY	-2
    106 
    107 /*
    108  * maximum transfer size for different interfaces
    109  */
    110 #define	ECTSIZE	2048
    111 #define	IETSIZE	8192
    112 
    113 /*
    114  * WebNFS error status
    115  */
    116 enum wnfsstat {
    117 	WNFSERR_CLNT_FLAVOR = 20001	/* invalid client sec flavor */
    118 };
    119 
    120 /*
    121  * Error status
    122  * Should include all possible net errors.
    123  * For now we just cast errno into an enum nfsstat.
    124  */
    125 enum nfsstat {
    126 	NFS_OK = 0,			/* no error */
    127 	NFSERR_PERM = 1,		/* Not owner */
    128 	NFSERR_NOENT = 2,		/* No such file or directory */
    129 	NFSERR_IO = 5,			/* I/O error */
    130 	NFSERR_NXIO = 6,		/* No such device or address */
    131 	NFSERR_ACCES = 13,		/* Permission denied */
    132 	NFSERR_EXIST = 17,		/* File exists */
    133 	NFSERR_XDEV = 18,		/* Cross-device link */
    134 	NFSERR_NODEV = 19,		/* No such device */
    135 	NFSERR_NOTDIR = 20,		/* Not a directory */
    136 	NFSERR_ISDIR = 21,		/* Is a directory */
    137 	NFSERR_INVAL = 22,		/* Invalid argument */
    138 	NFSERR_FBIG = 27,		/* File too large */
    139 	NFSERR_NOSPC = 28,		/* No space left on device */
    140 	NFSERR_ROFS = 30,		/* Read-only file system */
    141 	NFSERR_OPNOTSUPP = 45,		/* Operation not supported */
    142 	NFSERR_NAMETOOLONG = 63,	/* File name too long */
    143 	NFSERR_NOTEMPTY = 66,		/* Directory not empty */
    144 	NFSERR_DQUOT = 69,		/* Disc quota exceeded */
    145 	NFSERR_STALE = 70,		/* Stale NFS file handle */
    146 	NFSERR_REMOTE = 71,		/* Object is remote */
    147 	NFSERR_WFLUSH = 99		/* write cache flushed */
    148 };
    149 
    150 typedef enum nfsstat nfsstat;
    151 
    152 /*
    153  * File types
    154  */
    155 enum nfsftype {
    156 	NFNON,
    157 	NFREG,		/* regular file */
    158 	NFDIR,		/* directory */
    159 	NFBLK,		/* block special */
    160 	NFCHR,		/* character special */
    161 	NFLNK,		/* symbolic link */
    162 	NFSOC		/* socket */
    163 };
    164 
    165 /*
    166  * Macros for converting device numbers to and from the format
    167  * SunOS 4.x used. SVR4 uses 14 bit majors and 18 bits minors,
    168  * SunOS 4.x used 8 bit majors and 8 bit minors. It isn't sufficient
    169  * to use the cmpdev() and expdev() macros because they only compress
    170  * 7 bit (and smaller) majors. We must compress 8 bit majors too.
    171  * If the major or minor exceeds 8 bits, then we send it out in
    172  * full 32 bit format and hope that the peer can deal with it.
    173  */
    174 
    175 #define	SO4_BITSMAJOR	8	/* # of SunOS 4.x major device bits */
    176 #define	SO4_BITSMINOR	8	/* # of SunOS 4.x minor device bits */
    177 #define	SO4_MAXMAJ	0xff	/* SunOS 4.x max major value */
    178 #define	SO4_MAXMIN	0xff	/* SunOS 4.x max minor value */
    179 
    180 /*
    181  * Convert to over-the-wire device number format
    182  */
    183 #define	nfsv2_cmpdev(x) \
    184 	((uint32_t) \
    185 	((getmajor(x) > SO4_MAXMAJ || getminor(x) > SO4_MAXMIN) ? NODEV : \
    186 	((getmajor(x) << SO4_BITSMINOR) | (getminor(x) & SO4_MAXMIN))))
    187 
    188 /*
    189  * Convert from over-the-wire format to SVR4 device number format
    190  */
    191 #define	nfsv2_expdev(x) \
    192 	makedevice((((x) >> SO4_BITSMINOR) & SO4_MAXMAJ), (x) & SO4_MAXMIN)
    193 
    194 /*
    195  * Special kludge for fifos (named pipes)  [to adhere to NFS Protocol Spec]
    196  *
    197  * VFIFO is not in the protocol spec (VNON will be replaced by VFIFO)
    198  * so the over-the-wire representation is VCHR with a '-1' device number.
    199  *
    200  * NOTE: This kludge becomes unnecessary with the Protocol Revision,
    201  *	 but it may be necessary to support it (backwards compatibility).
    202  */
    203 #define	NFS_FIFO_TYPE	NFCHR
    204 #define	NFS_FIFO_MODE	S_IFCHR
    205 #define	NFS_FIFO_DEV	((uint32_t)-1)
    206 
    207 /* identify fifo in nfs attributes */
    208 #define	NA_ISFIFO(NA)	(((NA)->na_type == NFS_FIFO_TYPE) && \
    209 			    ((NA)->na_rdev == NFS_FIFO_DEV))
    210 
    211 /* set fifo in nfs attributes */
    212 #define	NA_SETFIFO(NA)	{ \
    213 		(NA)->na_type = NFS_FIFO_TYPE; \
    214 		(NA)->na_rdev = NFS_FIFO_DEV; \
    215 		(NA)->na_mode = ((NA)->na_mode & ~S_IFMT) | NFS_FIFO_MODE; \
    216 		}
    217 
    218 /*
    219  * Check for time overflow using a kernel tunable to determine whether
    220  * we should accept or reject an unsigned 32-bit time value. Time value in NFS
    221  * v2/3 protocol is unsigned 32 bit, but ILP32 kernel only allows 31 bits.
    222  * In nfsv4, time value is a signed 64 bit, so needs to be checked for
    223  * overflow as well (e.g. for setattr). So define the tunable as follows:
    224  * nfs_allow_preepoch_time is TRUE if pre-epoch (negative) times are allowed
    225  * and is FALSE (the default) otherwise. For nfsv2/3 this means that
    226  * if negative times are allowed, the uint32_t time value is interpreted
    227  * as a signed int, otherwise as a large positive number. For nfsv4,
    228  * we use the value as is - except that if negative times are not allowed,
    229  * we will not accept a negative value otw.
    230  *
    231  * So for nfsv2/3 (uint32_t):
    232  *
    233  * If nfs_allow_preepoch_time is
    234  * FALSE, the maximum time value is INT32_MAX for 32-bit kernels and
    235  * UINT32_MAX for 64-bit kernels (to allow times larger than 2038)
    236  * and the minimum is zero. Note that in that case, a 32-bit application
    237  * running on a 64-bit kernel will not be able to access files with
    238  * the larger time values.
    239  * If nfs_allow_preepoch_time is TRUE, the maximum time value is INT32_MAX
    240  * for both kernel configurations and the minimum is INT32_MIN.
    241  *
    242  * And for nfsv4 (int64_t):
    243  *
    244  * nfsv4 allows for negative values in the protocol, and has a 64-bit
    245  * time field, so nfs_allow_preepoch_time can be ignored.
    246  */
    247 #ifdef _KERNEL
    248 
    249 extern bool_t		nfs_allow_preepoch_time;
    250 
    251 #ifdef _LP64
    252 
    253 /*
    254  * If no negative otw values are allowed, may use the full 32-bits of the
    255  * time to represent time later than 2038, by presenting the value as an
    256  * unsigned (but this can only be used by 64-bit apps due to cstat32
    257  * restrictions). If negative values are allowed, cannot represent times
    258  * after 2038. Either way, all 32 bits have a valid representation.
    259  */
    260 
    261 /* Check if nfstime4 seconds (int64_t) can be stored in the system time */
    262 #define	NFS4_TIME_OK(tt)	TRUE
    263 
    264 
    265 #define	NFS3_TIME_OVERFLOW(tt)	(FALSE)
    266 #define	NFS2_TIME_OVERFLOW(tt)	(FALSE)
    267 
    268 /*
    269  * check if a time_t (int64_t) is ok when preepoch times are allowed -
    270  * nfsv2/3: every 32-bit value is accepted, but can't overflow 64->32.
    271  * nfsv4: every value is valid.
    272  */
    273 #define	NFS_PREEPOCH_TIME_T_OK(tt)					\
    274 	(((tt) >= (time_t)INT32_MIN) && ((tt) <= (time_t)INT32_MAX))
    275 
    276 /*
    277  * check if a time_t (int64_t) is ok when preepoch times are not allowed -
    278  * nfsv2/3: every positive 32-bit value is accepted, but can't overflow 64->32.
    279  * nfsv4: every value is valid.
    280  */
    281 #define	NFS_NO_PREEPOCH_TIME_T_OK(tt)					\
    282 	(((tt) >= 0) && ((tt) <= (time_t)(ulong_t)UINT32_MAX))
    283 
    284 #else /* not _LP64 */
    285 
    286 /*
    287  * Cannot represent times after 2038 in a 32-bit kernel, but we may wish to
    288  * restrict the use of negative values (which violate the protocol).
    289  * So if negative times allowed, all uint32 time values are valid. Otherwise
    290  * only those which are less than INT32_MAX (msb=0).
    291  *
    292  * NFSv4 uses int64_t for the time, so in a 32-bit kernel the nfsv4 value
    293  * must fit in an int32_t.
    294  */
    295 
    296 /* Only allow signed 32-bit time values */
    297 
    298 /* Check if an nfstime4 (int64_t) can be stored in the system time */
    299 #define	NFS4_TIME_OK(tt)						\
    300 	(((tt) <= INT32_MAX) &&	((tt) >= INT32_MIN))
    301 
    302 #define	NFS3_TIME_OVERFLOW(tt)	((tt) > INT32_MAX)
    303 #define	NFS2_TIME_OVERFLOW(tt)	((tt) > INT32_MAX)
    304 
    305 /*
    306  * check if a time_t (int32_t) is ok when preepoch times are allowed -
    307  * every 32-bit value is accepted
    308  */
    309 #define	NFS_PREEPOCH_TIME_T_OK(tt)	TRUE
    310 
    311 /*
    312  * check if a time_t (int32_t) is ok when preepoch times are not allowed -
    313  * only positive values are accepted.
    314  */
    315 #define	NFS_NO_PREEPOCH_TIME_T_OK(tt)	((tt) >= 0)
    316 
    317 #endif /* _LP64 */
    318 
    319 /* Check if an nfstime3 (uint32_t) can be stored in the system time */
    320 #define	NFS3_TIME_OK(tt)						\
    321 	(nfs_allow_preepoch_time || (!NFS3_TIME_OVERFLOW(tt)))
    322 
    323 /* Check if an nfs2_timeval (uint32_t) can be stored in the system time. */
    324 #define	NFS2_TIME_OK(tt)						\
    325 	(nfs_allow_preepoch_time || (!NFS2_TIME_OVERFLOW(tt)))
    326 
    327 /*
    328  * Test if time_t (signed long) can be sent over the wire - for v2/3 only if:
    329  * 1. The time value can fit in a uint32_t; and
    330  * 2. Either the time value is positive or allow preepoch times.
    331  * No restrictions for nfsv4.
    332  */
    333 #define	NFS_TIME_T_OK(tt)						\
    334 	(nfs_allow_preepoch_time ?					\
    335 		NFS_PREEPOCH_TIME_T_OK(tt) : NFS_NO_PREEPOCH_TIME_T_OK(tt))
    336 
    337 #define	NFS4_TIME_T_OK(tt)		TRUE
    338 
    339 /* Test if all attr times are valid */
    340 #define	NFS_VAP_TIME_OK(vap)						\
    341 	(nfs_allow_preepoch_time ?					\
    342 		(NFS_PREEPOCH_TIME_T_OK((vap)->va_atime.tv_sec) &&	\
    343 		NFS_PREEPOCH_TIME_T_OK((vap)->va_mtime.tv_sec) &&	\
    344 		NFS_PREEPOCH_TIME_T_OK((vap)->va_ctime.tv_sec)) :	\
    345 		(NFS_NO_PREEPOCH_TIME_T_OK((vap)->va_atime.tv_sec) &&	\
    346 		NFS_NO_PREEPOCH_TIME_T_OK((vap)->va_mtime.tv_sec) &&	\
    347 		NFS_NO_PREEPOCH_TIME_T_OK((vap)->va_ctime.tv_sec)))
    348 
    349 #define	NFS4_VAP_TIME_OK(vap)			TRUE
    350 
    351 /*
    352  * To extend the sign or not extend the sign, that is the question.
    353  * Note: The correct way is to code a macro:
    354  * #define	NFS_TIME_T_CONVERT(tt)					\
    355  *	(nfs_allow_preepoch_time ? (int32_t)(tt) : (uint32_t)(tt))
    356  * But the 64-bit compiler does not extend the sign in that case (why?)
    357  * so we'll do it the ugly way...
    358  */
    359 #define	NFS_TIME_T_CONVERT(systt, tt)		\
    360 	if (nfs_allow_preepoch_time) {		\
    361 		systt = (int32_t)(tt);		\
    362 	} else {				\
    363 		systt = (uint32_t)(tt);		\
    364 	}
    365 
    366 /* macro to check for overflowed time attribute fields - version 3 */
    367 #define	NFS3_FATTR_TIME_OK(attrs)			\
    368 	(NFS3_TIME_OK((attrs)->atime.seconds) &&	\
    369 	NFS3_TIME_OK((attrs)->mtime.seconds) &&		\
    370 	NFS3_TIME_OK((attrs)->ctime.seconds))
    371 
    372 /* macro to check for overflowed time attribute fields - version 2 */
    373 #define	NFS2_FATTR_TIME_OK(attrs)			\
    374 	(NFS2_TIME_OK((attrs)->na_atime.tv_sec) &&	\
    375 	NFS2_TIME_OK((attrs)->na_mtime.tv_sec) &&	\
    376 	NFS2_TIME_OK((attrs)->na_ctime.tv_sec))
    377 
    378 /* Check that a size3 value is not overflowed */
    379 #define	NFS3_SIZE_OK(size)	((size) <= MAXOFFSET_T)
    380 
    381 #endif /* _KERNEL */
    382 
    383 /*
    384  * Size of an fhandle in bytes
    385  */
    386 #define	NFS_FHSIZE	32
    387 
    388 struct nfs_fid {
    389 	ushort_t nf_len;
    390 	ushort_t nf_pad;
    391 	char	nf_data[NFS_FHSIZE];
    392 };
    393 
    394 /*
    395  * "Legacy" filehandles use NFS_FHMAXDATA (10) byte fids. Filesystems that
    396  * return a larger fid than NFS_FHMAXDATA, such as ZFS's .zfs snapshot
    397  * directory, can use up to (((64 - 8) / 2) - 2) bytes for their fid.
    398  * This currently holds for both NFSv3 and NFSv4.
    399  */
    400 #define	NFS_FHMAXDATA		10
    401 #define	NFS_FH3MAXDATA		26
    402 #define	NFS_FH4MAXDATA		26
    403 
    404 /*
    405  * The original nfs file handle size for version 3 was 32 which was
    406  * the same in version 2; now we're making it bigger to to deal with
    407  * ZFS snapshot FIDs.
    408  *
    409  * If the size of fhandle3_t changes or if Version 3 uses some other
    410  * filehandle format, this constant may need to change.
    411  */
    412 
    413 #define	NFS3_OLDFHSIZE	32
    414 #define	NFS3_MAXFHSIZE	64
    415 
    416 /*
    417  * This is the actual definition of a legacy filehandle.  There is some
    418  * dependence on this layout in NFS-related code, particularly in the
    419  * user-level lock manager, so be careful about changing it.
    420  *
    421  * Currently only NFSv2 uses this structure.
    422  */
    423 
    424 typedef struct svcfh {
    425 	fsid_t	fh_fsid;			/* filesystem id */
    426 	ushort_t fh_len;			/* file number length */
    427 	char	fh_data[NFS_FHMAXDATA];		/* and data */
    428 	ushort_t fh_xlen;			/* export file number length */
    429 	char	fh_xdata[NFS_FHMAXDATA];	/* and data */
    430 } fhandle_t;
    431 
    432 /*
    433  * This is the in-memory structure for an NFSv3 extended filehandle.
    434  */
    435 typedef struct {
    436 	fsid_t	_fh3_fsid;			/* filesystem id */
    437 	ushort_t _fh3_len;			/* file number length */
    438 	char	_fh3_data[NFS_FH3MAXDATA];		/* and data */
    439 	ushort_t _fh3_xlen;			/* export file number length */
    440 	char	_fh3_xdata[NFS_FH3MAXDATA];	/* and data */
    441 } fhandle3_t;
    442 
    443 /*
    444  * This is the in-memory structure for an NFSv4 extended filehandle.
    445  */
    446 typedef struct {
    447 	fsid_t	fhx_fsid;			/* filesystem id */
    448 	ushort_t fhx_len;			/* file number length */
    449 	char	fhx_data[NFS_FH4MAXDATA];	/* and data */
    450 	ushort_t fhx_xlen;			/* export file number length */
    451 	char	fhx_xdata[NFS_FH4MAXDATA];	/* and data */
    452 } fhandle4_t;
    453 
    454 /*
    455  * Arguments to remote write and writecache
    456  */
    457 /*
    458  * The `over the wire' representation of the first four arguments.
    459  */
    460 struct otw_nfswriteargs {
    461 	fhandle_t	otw_wa_fhandle;
    462 	uint32_t	otw_wa_begoff;
    463 	uint32_t	otw_wa_offset;
    464 	uint32_t	otw_wa_totcount;
    465 };
    466 
    467 struct nfswriteargs {
    468 	struct otw_nfswriteargs *wa_args;	/* ptr to the otw arguments */
    469 	struct otw_nfswriteargs wa_args_buf;	/* space for otw arguments */
    470 	uint32_t	wa_count;
    471 	char		*wa_data;	/* data to write (up to NFS_MAXDATA) */
    472 	mblk_t		*wa_mblk;	/* pointer to mblks containing data */
    473 };
    474 #define	wa_fhandle	wa_args->otw_wa_fhandle
    475 #define	wa_begoff	wa_args->otw_wa_begoff
    476 #define	wa_offset	wa_args->otw_wa_offset
    477 #define	wa_totcount	wa_args->otw_wa_totcount
    478 
    479 /*
    480  * NFS timeval struct using unsigned int as specified in V2 protocol.
    481  * tv_sec and tv_usec used to match existing code.
    482  */
    483 struct nfs2_timeval {
    484 	uint32_t tv_sec;
    485 	uint32_t tv_usec;
    486 };
    487 typedef struct nfs2_timeval nfs2_timeval;
    488 
    489 /*
    490  * File attributes
    491  */
    492 struct nfsfattr {
    493 	enum nfsftype	na_type;	/* file type */
    494 	uint32_t	na_mode;	/* protection mode bits */
    495 	uint32_t	na_nlink;	/* # hard links */
    496 	uint32_t	na_uid;		/* owner user id */
    497 	uint32_t	na_gid;		/* owner group id */
    498 	uint32_t	na_size;	/* file size in bytes */
    499 	uint32_t	na_blocksize;	/* preferred block size */
    500 	uint32_t	na_rdev;	/* special device # */
    501 	uint32_t	na_blocks;	/* Kb of disk used by file */
    502 	uint32_t	na_fsid;	/* device # */
    503 	uint32_t	na_nodeid;	/* inode # */
    504 	struct nfs2_timeval na_atime;	/* time of last access */
    505 	struct nfs2_timeval na_mtime;	/* time of last modification */
    506 	struct nfs2_timeval na_ctime;	/* time of last change */
    507 };
    508 
    509 #define	n2v_type(x)	(NA_ISFIFO(x) ? VFIFO : nf_to_vt[(x)->na_type])
    510 #define	n2v_rdev(x)	(NA_ISFIFO(x) ? 0 : (x)->na_rdev)
    511 
    512 /*
    513  * Arguments to remote read
    514  */
    515 struct nfsreadargs {
    516 	fhandle_t	ra_fhandle;	/* handle for file */
    517 	uint32_t	ra_offset;	/* byte offset in file */
    518 	uint32_t	ra_count;	/* immediate read count */
    519 	uint32_t	ra_totcount;	/* total read cnt (from this offset) */
    520 };
    521 
    522 /*
    523  * Status OK portion of remote read reply
    524  */
    525 struct nfsrrok {
    526 	struct nfsfattr	rrok_attr;	/* attributes, need for pagin */
    527 	uint32_t	rrok_count;	/* bytes of data */
    528 	char		*rrok_data;	/* data (up to NFS_MAXDATA bytes) */
    529 	uint_t		rrok_bufsize;	/* size of kmem_alloc'd buffer */
    530 	mblk_t		*rrok_mp;	/* mblk_t contains data for reply */
    531 };
    532 
    533 /*
    534  * Reply from remote read
    535  */
    536 struct nfsrdresult {
    537 	nfsstat	rr_status;			/* status of read */
    538 	union {
    539 		struct nfsrrok	rr_ok_u;	/* attributes, need for pagin */
    540 	} rr_u;
    541 };
    542 #define	rr_ok		rr_u.rr_ok_u
    543 #define	rr_attr		rr_u.rr_ok_u.rrok_attr
    544 #define	rr_count	rr_u.rr_ok_u.rrok_count
    545 #define	rr_bufsize	rr_u.rr_ok_u.rrok_bufsize
    546 #define	rr_data		rr_u.rr_ok_u.rrok_data
    547 #define	rr_mp		rr_u.rr_ok_u.rrok_mp
    548 
    549 /*
    550  * File attributes which can be set
    551  */
    552 struct nfssattr {
    553 	uint32_t	sa_mode;	/* protection mode bits */
    554 	uint32_t	sa_uid;		/* owner user id */
    555 	uint32_t	sa_gid;		/* owner group id */
    556 	uint32_t	sa_size;	/* file size in bytes */
    557 	struct nfs2_timeval sa_atime;	/* time of last access */
    558 	struct nfs2_timeval sa_mtime;	/* time of last modification */
    559 };
    560 
    561 
    562 /*
    563  * Reply status with file attributes
    564  */
    565 struct nfsattrstat {
    566 	nfsstat	ns_status;			/* reply status */
    567 	union {
    568 		struct nfsfattr ns_attr_u;	/* NFS_OK: file attributes */
    569 	} ns_u;
    570 };
    571 #define	ns_attr	ns_u.ns_attr_u
    572 
    573 
    574 /*
    575  * NFS_OK part of read sym link reply union
    576  */
    577 struct nfssrok {
    578 	uint32_t srok_count;	/* size of string */
    579 	char	*srok_data;	/* string (up to NFS_MAXPATHLEN bytes) */
    580 };
    581 
    582 /*
    583  * Result of reading symbolic link
    584  */
    585 struct nfsrdlnres {
    586 	nfsstat	rl_status;			/* status of symlink read */
    587 	union {
    588 		struct nfssrok	rl_srok_u;	/* name of linked to */
    589 	} rl_u;
    590 };
    591 #define	rl_srok		rl_u.rl_srok_u
    592 #define	rl_count	rl_u.rl_srok_u.srok_count
    593 #define	rl_data		rl_u.rl_srok_u.srok_data
    594 
    595 
    596 /*
    597  * Arguments to readdir
    598  */
    599 struct nfsrddirargs {
    600 	fhandle_t rda_fh;	/* directory handle */
    601 	uint32_t rda_offset;	/* offset in directory (opaque) */
    602 	uint32_t rda_count;	/* number of directory bytes to read */
    603 };
    604 
    605 /*
    606  * NFS_OK part of readdir result
    607  */
    608 struct nfsrdok {
    609 	uint32_t rdok_offset;		/* next offset (opaque) */
    610 	uint32_t rdok_size;		/* size in bytes of entries */
    611 	bool_t	rdok_eof;		/* true if last entry is in result */
    612 	struct dirent64 *rdok_entries;	/* variable number of entries */
    613 };
    614 
    615 /*
    616  * Readdir result
    617  */
    618 struct nfsrddirres {
    619 	nfsstat	rd_status;
    620 	uint_t		rd_bufsize;	/* client request size (not xdr'ed) */
    621 	union {
    622 		struct nfsrdok rd_rdok_u;
    623 	} rd_u;
    624 };
    625 #define	rd_rdok		rd_u.rd_rdok_u
    626 #define	rd_offset	rd_u.rd_rdok_u.rdok_offset
    627 #define	rd_size		rd_u.rd_rdok_u.rdok_size
    628 #define	rd_eof		rd_u.rd_rdok_u.rdok_eof
    629 #define	rd_entries	rd_u.rd_rdok_u.rdok_entries
    630 
    631 
    632 /*
    633  * Arguments for directory operations
    634  */
    635 struct nfsdiropargs {
    636 	fhandle_t	*da_fhandle;	/* pointer to directory file handle */
    637 	char		*da_name;	/* name (up to NFS_MAXNAMLEN bytes) */
    638 	fhandle_t	da_fhandle_buf;	/* directory file handle */
    639 	int		da_flags;	/* flags, see below */
    640 };
    641 #define	DA_FREENAME	1
    642 
    643 /*
    644  * NFS_OK part of directory operation result
    645  */
    646 struct  nfsdrok {
    647 	fhandle_t	drok_fhandle;	/* result file handle */
    648 	struct nfsfattr	drok_attr;	/* result file attributes */
    649 };
    650 
    651 /*
    652  * Results from directory operation
    653  */
    654 struct  nfsdiropres {
    655 	nfsstat	dr_status;			/* result status */
    656 	union {
    657 		struct  nfsdrok	dr_drok_u;	/* NFS_OK result */
    658 	} dr_u;
    659 };
    660 #define	dr_drok		dr_u.dr_drok_u
    661 #define	dr_fhandle	dr_u.dr_drok_u.drok_fhandle
    662 #define	dr_attr		dr_u.dr_drok_u.drok_attr
    663 
    664 /*
    665  * arguments to setattr
    666  */
    667 struct nfssaargs {
    668 	fhandle_t	saa_fh;		/* fhandle of file to be set */
    669 	struct nfssattr	saa_sa;		/* new attributes */
    670 };
    671 
    672 /*
    673  * arguments to create and mkdir
    674  */
    675 struct nfscreatargs {
    676 	struct nfsdiropargs	ca_da;	/* file name to create and parent dir */
    677 	struct nfssattr		*ca_sa;	/* initial attributes */
    678 	struct nfssattr		ca_sa_buf;	/* space to store attributes */
    679 };
    680 
    681 /*
    682  * arguments to link
    683  */
    684 struct nfslinkargs {
    685 	fhandle_t		*la_from;	/* old file */
    686 	fhandle_t		la_from_buf;	/* old file */
    687 	struct nfsdiropargs	la_to;		/* new file and parent dir */
    688 };
    689 
    690 /*
    691  * arguments to rename
    692  */
    693 struct nfsrnmargs {
    694 	struct nfsdiropargs rna_from;	/* old file and parent dir */
    695 	struct nfsdiropargs rna_to;	/* new file and parent dir */
    696 };
    697 
    698 /*
    699  * arguments to symlink
    700  */
    701 struct nfsslargs {
    702 	struct nfsdiropargs	sla_from;	/* old file and parent dir */
    703 	char			*sla_tnm;	/* new name */
    704 	int			sla_tnm_flags;	/* flags for name */
    705 	struct nfssattr		*sla_sa;	/* attributes */
    706 	struct nfssattr		sla_sa_buf;	/* attributes buffer */
    707 };
    708 #define	SLA_FREETNM	1
    709 
    710 /*
    711  * NFS_OK part of statfs operation
    712  */
    713 struct nfsstatfsok {
    714 	uint32_t fsok_tsize;	/* preferred transfer size in bytes */
    715 	uint32_t fsok_bsize;	/* fundamental file system block size */
    716 	uint32_t fsok_blocks;	/* total blocks in file system */
    717 	uint32_t fsok_bfree;	/* free blocks in fs */
    718 	uint32_t fsok_bavail;	/* free blocks avail to non-superuser */
    719 };
    720 
    721 /*
    722  * Results of statfs operation
    723  */
    724 struct nfsstatfs {
    725 	nfsstat	fs_status;			/* result status */
    726 	union {
    727 		struct	nfsstatfsok fs_fsok_u;	/* NFS_OK result */
    728 	} fs_u;
    729 };
    730 #define	fs_fsok		fs_u.fs_fsok_u
    731 #define	fs_tsize	fs_u.fs_fsok_u.fsok_tsize
    732 #define	fs_bsize	fs_u.fs_fsok_u.fsok_bsize
    733 #define	fs_blocks	fs_u.fs_fsok_u.fsok_blocks
    734 #define	fs_bfree	fs_u.fs_fsok_u.fsok_bfree
    735 #define	fs_bavail	fs_u.fs_fsok_u.fsok_bavail
    736 
    737 #ifdef _KERNEL
    738 /*
    739  * XDR routines for handling structures defined above
    740  */
    741 extern bool_t	xdr_attrstat(XDR *, struct nfsattrstat *);
    742 extern bool_t	xdr_fastattrstat(XDR *, struct nfsattrstat *);
    743 extern bool_t	xdr_creatargs(XDR *, struct nfscreatargs *);
    744 extern bool_t	xdr_diropargs(XDR *, struct nfsdiropargs *);
    745 extern bool_t	xdr_diropres(XDR *, struct nfsdiropres *);
    746 extern bool_t	xdr_fastdiropres(XDR *, struct nfsdiropres *);
    747 extern bool_t	xdr_drok(XDR *, struct nfsdrok *);
    748 #ifdef _LITTLE_ENDIAN
    749 extern bool_t	xdr_fastdrok(XDR *, struct nfsdrok *);
    750 extern bool_t	xdr_fastfattr(XDR *, struct nfsfattr *);
    751 #endif
    752 extern bool_t	xdr_fattr(XDR *, struct nfsfattr *);
    753 extern bool_t	xdr_fhandle(XDR *, fhandle_t *);
    754 extern bool_t	xdr_fastfhandle(XDR *, fhandle_t **);
    755 extern bool_t	xdr_linkargs(XDR *, struct nfslinkargs *);
    756 extern bool_t	xdr_rddirargs(XDR *, struct nfsrddirargs *);
    757 extern bool_t	xdr_putrddirres(XDR *, struct nfsrddirres *);
    758 extern bool_t	xdr_getrddirres(XDR *, struct nfsrddirres *);
    759 extern bool_t	xdr_rdlnres(XDR *, struct nfsrdlnres *);
    760 extern bool_t	xdr_rdresult(XDR *, struct nfsrdresult *);
    761 extern bool_t	xdr_readargs(XDR *, struct nfsreadargs *);
    762 extern bool_t	xdr_rnmargs(XDR *, struct nfsrnmargs *);
    763 extern bool_t	xdr_rrok(XDR *, struct nfsrrok *);
    764 extern bool_t	xdr_saargs(XDR *, struct nfssaargs *);
    765 extern bool_t	xdr_sattr(XDR *, struct nfssattr *);
    766 extern bool_t	xdr_slargs(XDR *, struct nfsslargs *);
    767 extern bool_t	xdr_srok(XDR *, struct nfssrok *);
    768 extern bool_t	xdr_nfs2_timeval(XDR *, struct nfs2_timeval *);
    769 extern bool_t	xdr_writeargs(XDR *, struct nfswriteargs *);
    770 extern bool_t	xdr_fsok(XDR *, struct nfsstatfsok *);
    771 #ifdef _LITTLE_ENDIAN
    772 extern bool_t	xdr_fastfsok(XDR *, struct nfsstatfsok *);
    773 extern bool_t	xdr_fastenum(XDR *, enum_t *);
    774 #endif
    775 extern bool_t	xdr_statfs(XDR *, struct nfsstatfs *);
    776 extern bool_t	xdr_faststatfs(XDR *, struct nfsstatfs *);
    777 #endif
    778 
    779 /*
    780  * Remote file service routines
    781  */
    782 #define	RFS_NULL	0
    783 #define	RFS_GETATTR	1
    784 #define	RFS_SETATTR	2
    785 #define	RFS_ROOT	3
    786 #define	RFS_LOOKUP	4
    787 #define	RFS_READLINK	5
    788 #define	RFS_READ	6
    789 #define	RFS_WRITECACHE	7
    790 #define	RFS_WRITE	8
    791 #define	RFS_CREATE	9
    792 #define	RFS_REMOVE	10
    793 #define	RFS_RENAME	11
    794 #define	RFS_LINK	12
    795 #define	RFS_SYMLINK	13
    796 #define	RFS_MKDIR	14
    797 #define	RFS_RMDIR	15
    798 #define	RFS_READDIR	16
    799 #define	RFS_STATFS	17
    800 #define	RFS_NPROC	18
    801 
    802 #ifdef _KERNEL
    803 /*
    804  * The NFS Version 2 service procedures
    805  */
    806 struct exportinfo;	/* defined in nfs/export.h */
    807 struct servinfo;	/* defined in nfs/nfs_clnt.h */
    808 struct mntinfo;		/* defined in nfs/nfs_clnt.h */
    809 
    810 extern void rfs_getattr(fhandle_t *, struct nfsattrstat *,
    811 			struct exportinfo *, struct svc_req *, cred_t *);
    812 extern void *rfs_getattr_getfh(fhandle_t *);
    813 extern void rfs_setattr(struct nfssaargs *, struct nfsattrstat *,
    814 			struct exportinfo *, struct svc_req *, cred_t *);
    815 extern void *rfs_setattr_getfh(struct nfssaargs *);
    816 extern void rfs_lookup(struct nfsdiropargs *, struct nfsdiropres *,
    817 			struct exportinfo *, struct svc_req *, cred_t *);
    818 extern void *rfs_lookup_getfh(struct nfsdiropargs *);
    819 extern void rfs_readlink(fhandle_t *, struct nfsrdlnres *,
    820 			struct exportinfo *, struct svc_req *, cred_t *);
    821 extern void *rfs_readlink_getfh(fhandle_t *);
    822 extern void rfs_rlfree(struct nfsrdlnres *);
    823 extern void rfs_read(struct nfsreadargs *, struct nfsrdresult *,
    824 			struct exportinfo *, struct svc_req *, cred_t *);
    825 extern void *rfs_read_getfh(struct nfsreadargs *);
    826 extern void rfs_rdfree(struct nfsrdresult *);
    827 extern void rfs_write_sync(struct nfswriteargs *, struct nfsattrstat *,
    828 			struct exportinfo *, struct svc_req *, cred_t *);
    829 extern void rfs_write(struct nfswriteargs *, struct nfsattrstat *,
    830 			struct exportinfo *, struct svc_req *, cred_t *);
    831 extern void *rfs_write_getfh(struct nfswriteargs *);
    832 extern void rfs_create(struct nfscreatargs *, struct nfsdiropres *,
    833 			struct exportinfo *, struct svc_req *, cred_t *);
    834 extern void *rfs_create_getfh(struct nfscreatargs *);
    835 extern void rfs_remove(struct nfsdiropargs *, enum nfsstat *,
    836 			struct exportinfo *, struct svc_req *, cred_t *);
    837 extern void *rfs_remove_getfh(struct nfsdiropargs *);
    838 extern void rfs_rename(struct nfsrnmargs *, enum nfsstat *,
    839 			struct exportinfo *, struct svc_req *, cred_t *);
    840 extern void *rfs_rename_getfh(struct nfsrnmargs *);
    841 extern void rfs_link(struct nfslinkargs *, enum nfsstat *,
    842 			struct exportinfo *, struct svc_req *, cred_t *);
    843 extern void *rfs_link_getfh(struct nfslinkargs *);
    844 extern void rfs_symlink(struct nfsslargs *, enum nfsstat *,
    845 			struct exportinfo *, struct svc_req *, cred_t *);
    846 extern void *rfs_symlink_getfh(struct nfsslargs *);
    847 extern void rfs_mkdir(struct nfscreatargs *, struct nfsdiropres *,
    848 			struct exportinfo *, struct svc_req *, cred_t *);
    849 extern void *rfs_mkdir_getfh(struct nfscreatargs *);
    850 extern void rfs_rmdir(struct nfsdiropargs *, enum nfsstat *,
    851 			struct exportinfo *, struct svc_req *, cred_t *);
    852 extern void *rfs_rmdir_getfh(struct nfsdiropargs *);
    853 extern void rfs_readdir(struct nfsrddirargs *, struct nfsrddirres *,
    854 			struct exportinfo *, struct svc_req *, cred_t *);
    855 extern void *rfs_readdir_getfh(struct nfsrddirargs *);
    856 extern void rfs_rddirfree(struct nfsrddirres *);
    857 extern void rfs_statfs(fhandle_t *, struct nfsstatfs *,
    858 			struct exportinfo *, struct svc_req *, cred_t *);
    859 extern void *rfs_statfs_getfh(fhandle_t *);
    860 extern void rfs_srvrinit(void);
    861 extern void rfs_srvrfini(void);
    862 
    863 /*
    864  * flags to define path types during Multi Component Lookups
    865  * using the public filehandle
    866  */
    867 #define	URLPATH		0x01	/* Universal Resource Locator path */
    868 #define	NATIVEPATH	0x02	/* Native path, i.e., via mount protocol */
    869 #define	SECURITY_QUERY	0x04	/* Security query */
    870 
    871 enum nfs_svccounts {NFS_CALLS, NFS_BADCALLS}; /* index for svstat_ptr */
    872 
    873 /*	function defs for NFS kernel */
    874 extern int	nfs_waitfor_purge_complete(vnode_t *);
    875 extern int	nfs_validate_caches(vnode_t *, cred_t *);
    876 extern void	nfs_purge_caches(vnode_t *, int, cred_t *);
    877 extern void	nfs_purge_rddir_cache(vnode_t *);
    878 extern void	nfs_attrcache(vnode_t *, struct nfsfattr *, hrtime_t);
    879 extern int	nfs_cache_fattr(vnode_t *, struct nfsfattr *, vattr_t *,
    880 				hrtime_t, cred_t *);
    881 extern void	nfs_attr_cache(vnode_t *, vattr_t *, hrtime_t, cred_t *);
    882 extern void	nfs_attrcache_va(vnode_t *, struct vattr *);
    883 extern int	nfs_getattr_otw(vnode_t *, struct vattr *, cred_t *);
    884 extern int	nfsgetattr(vnode_t *, struct vattr *, cred_t *);
    885 extern int	nattr_to_vattr(vnode_t *, struct nfsfattr *, struct vattr *);
    886 extern void	nfs_async_manager(struct vfs *);
    887 extern void	nfs_async_manager_stop(struct vfs *);
    888 extern void	nfs_async_stop(struct vfs *);
    889 extern int	nfs_async_stop_sig(struct vfs *);
    890 extern int	nfs_clntinit(void);
    891 extern void	nfs_clntfini(void);
    892 extern int	nfstsize(void);
    893 extern int	nfs_srvinit(void);
    894 extern void	nfs_srvfini(void);
    895 extern int	vattr_to_sattr(struct vattr *, struct nfssattr *);
    896 extern void	setdiropargs(struct nfsdiropargs *, char *, vnode_t *);
    897 extern int	setdirgid(vnode_t *, gid_t *, cred_t *);
    898 extern int	setdirmode(vnode_t *, mode_t *, cred_t *);
    899 extern int	newnum(void);
    900 extern char	*newname(void);
    901 extern int	nfs_atoi(char *);
    902 extern int	nfs_subrinit(void);
    903 extern void	nfs_subrfini(void);
    904 extern enum nfsstat puterrno(int);
    905 extern int	geterrno(enum nfsstat);
    906 extern int	nfsinit(int, char *);
    907 extern void	nfsfini(void);
    908 extern int	nfs_vfsinit(void);
    909 extern void	nfs_vfsfini(void);
    910 extern int	nfs_dump(vnode_t *, caddr_t, int, int, caller_context_t *);
    911 extern void	nfs_perror(int error, char *fmt, ...);
    912 extern void	nfs_cmn_err(int error, int level, char *fmt, ...);
    913 extern int	nfs_addcllock(vnode_t *vp, struct flock64 *bfp);
    914 extern void	nfs_rmcllock(vnode_t *vp, struct flock64 *bfp);
    915 extern void	nfs_lockrelease(vnode_t *vp, int flag,
    916 		    offset_t offset, cred_t *credp);
    917 extern int	vattr_to_nattr(struct vattr *, struct nfsfattr *);
    918 extern int	mount_root(char *, char *, int, struct nfs_args *, int *);
    919 extern void	nfs_lockcompletion(vnode_t *vp, int cmd);
    920 extern void	nfs_add_locking_id(vnode_t *, pid_t, int, char *, int);
    921 extern void	nfs3copyfh(caddr_t, vnode_t *);
    922 extern void	nfscopyfh(caddr_t, vnode_t *);
    923 extern int	nfs3lookup(vnode_t *, char *, vnode_t **, struct pathname *,
    924 				int, vnode_t *, cred_t *, int);
    925 extern int	nfslookup(vnode_t *, char *, vnode_t **, struct pathname *,
    926 				int, vnode_t *, cred_t *, int);
    927 extern void	sv_free(struct servinfo *);
    928 extern int	nfsauth_access(struct exportinfo *exi, struct svc_req *req);
    929 extern void	nfsauth_init();
    930 extern void	nfsauth_fini();
    931 extern int	nfs_setopts(vnode_t *vp, model_t model, struct nfs_args *args);
    932 extern int	nfs_mount_label_policy(vfs_t *vfsp, struct netbuf *addr,
    933 		    struct knetconfig *knconf, cred_t *cr);
    934 extern boolean_t	nfs_has_ctty(void);
    935 extern void	nfs_srv_stop_all(void);
    936 extern void	nfs_srv_quiesce_all(void);
    937 extern void	(*nfs_srv_quiesce_func)(void);
    938 extern int	rfs4_dss_setpaths(char *, size_t);
    939 extern int	(*nfs_srv_dss_func)(char *, size_t);
    940 extern time_t	rfs4_lease_time;
    941 extern time_t	rfs4_grace_period;
    942 extern nvlist_t	*rfs4_dss_paths, *rfs4_dss_oldpaths;
    943 
    944 
    945 extern kstat_named_t	*global_svstat_ptr[];
    946 
    947 extern krwlock_t	rroklock;
    948 extern vtype_t		nf_to_vt[];
    949 extern kstat_named_t	*rfsproccnt_v2_ptr;
    950 extern kmutex_t		nfs_minor_lock;
    951 extern int		nfs_major;
    952 extern int		nfs_minor;
    953 extern vfsops_t		*nfs_vfsops;
    954 extern struct vnodeops	*nfs_vnodeops;
    955 extern const struct fs_operation_def nfs_vnodeops_template[];
    956 extern int		nfsfstyp;
    957 
    958 /*
    959  * Per-zone stats as consumed by nfsstat(1m)
    960  */
    961 struct nfs_version_stats {
    962 	kstat_named_t	*aclreqcnt_ptr;		/* nfs_acl:0:aclreqcnt_v? */
    963 	kstat_named_t	*aclproccnt_ptr;	/* nfs_acl:0:aclproccnt_v? */
    964 	kstat_named_t	*rfsreqcnt_ptr;		/* nfs:0:rfsreqcnt_v? */
    965 	kstat_named_t	*rfsproccnt_ptr;	/* nfs:0:rfsproccnt_v? */
    966 };
    967 
    968 /*
    969  * A bit of asymmetry: nfs:0:nfs_client isn't part of this structure.
    970  */
    971 struct nfs_stats {
    972 	kstat_named_t		*nfs_stats_svstat_ptr[NFS_VERSMAX + 1];
    973 	struct nfs_version_stats	nfs_stats_v2;
    974 	struct nfs_version_stats	nfs_stats_v3;
    975 	struct nfs_version_stats	nfs_stats_v4;
    976 };
    977 
    978 /*
    979  * Key used to retrieve counters.
    980  */
    981 extern zone_key_t nfsstat_zone_key;
    982 
    983 /*
    984  * Zone callback functions.
    985  */
    986 extern void *nfsstat_zone_init(zoneid_t);
    987 extern void nfsstat_zone_fini(zoneid_t, void *);
    988 
    989 #endif	/* _KERNEL */
    990 
    991 /*
    992  * Version 3 declarations and definitions.
    993  */
    994 
    995 #define	NFS3_FHSIZE 64
    996 #define	NFS3_COOKIEVERFSIZE 8
    997 #define	NFS3_CREATEVERFSIZE 8
    998 #define	NFS3_WRITEVERFSIZE 8
    999 
   1000 typedef char *filename3;
   1001 
   1002 typedef char *nfspath3;
   1003 
   1004 #define	nfs3nametoolong	((char *)-1)
   1005 
   1006 typedef uint64 fileid3;
   1007 
   1008 typedef uint64 cookie3;
   1009