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_H
     30 #define	_NFS_NFS_H
     31 
     32 /*	nfs.h 2.38 88/08/19 SMI 	*/
     33 
     34 #include <sys/isa_defs.h>
     35 #include <sys/vfs.h>
     36 #include <sys/stream.h>
     37 #include <rpc/types.h>
     38 #include <sys/types32.h>
     39 #ifdef _KERNEL
     40 #include <rpc/rpc_rdma.h>
     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 #ifdef _KERNEL
    474 	/* rdma related info */
    475 	struct clist	*wa_rlist;
    476 	CONN		*wa_conn;
    477 #endif /* _KERNEL */
    478 };
    479 #define	wa_fhandle	wa_args->otw_wa_fhandle
    480 #define	wa_begoff	wa_args->otw_wa_begoff
    481 #define	wa_offset	wa_args->otw_wa_offset
    482 #define	wa_totcount	wa_args->otw_wa_totcount
    483 
    484 /*
    485  * NFS timeval struct using unsigned int as specified in V2 protocol.
    486  * tv_sec and tv_usec used to match existing code.
    487  */
    488 struct nfs2_timeval {
    489 	uint32_t tv_sec;
    490 	uint32_t tv_usec;
    491 };
    492 typedef struct nfs2_timeval nfs2_timeval;
    493 
    494 /*
    495  * File attributes
    496  */
    497 struct nfsfattr {
    498 	enum nfsftype	na_type;	/* file type */
    499 	uint32_t	na_mode;	/* protection mode bits */
    500 	uint32_t	na_nlink;	/* # hard links */
    501 	uint32_t	na_uid;		/* owner user id */
    502 	uint32_t	na_gid;		/* owner group id */
    503 	uint32_t	na_size;	/* file size in bytes */
    504 	uint32_t	na_blocksize;	/* preferred block size */
    505 	uint32_t	na_rdev;	/* special device # */
    506 	uint32_t	na_blocks;	/* Kb of disk used by file */
    507 	uint32_t	na_fsid;	/* device # */
    508 	uint32_t	na_nodeid;	/* inode # */
    509 	struct nfs2_timeval na_atime;	/* time of last access */
    510 	struct nfs2_timeval na_mtime;	/* time of last modification */
    511 	struct nfs2_timeval na_ctime;	/* time of last change */
    512 };
    513 
    514 #define	n2v_type(x)	(NA_ISFIFO(x) ? VFIFO : nf_to_vt[(x)->na_type])
    515 #define	n2v_rdev(x)	(NA_ISFIFO(x) ? 0 : (x)->na_rdev)
    516 
    517 /*
    518  * Arguments to remote read
    519  */
    520 struct nfsreadargs {
    521 	fhandle_t	ra_fhandle;	/* handle for file */
    522 	uint32_t	ra_offset;	/* byte offset in file */
    523 	uint32_t	ra_count;	/* immediate read count */
    524 	uint32_t	ra_totcount;	/* total read cnt (from this offset) */
    525 #ifdef _KERNEL
    526 	/* used in rdma transports */
    527 	caddr_t		ra_data;	/* destination for read data */
    528 	struct clist	*ra_wlist;
    529 	CONN		*ra_conn;
    530 #endif
    531 };
    532 
    533 /*
    534  * Status OK portion of remote read reply
    535  */
    536 struct nfsrrok {
    537 	struct nfsfattr	rrok_attr;	/* attributes, need for pagin */
    538 	uint32_t	rrok_count;	/* bytes of data */
    539 	char		*rrok_data;	/* data (up to NFS_MAXDATA bytes) */
    540 	uint_t		rrok_bufsize;	/* size of kmem_alloc'd buffer */
    541 	mblk_t		*rrok_mp;	/* mblk_t contains data for reply */
    542 #ifdef _KERNEL
    543 	uint_t		rrok_wlist_len;
    544 	struct clist    *rrok_wlist;
    545 #endif
    546 };
    547 
    548 /*
    549  * Reply from remote read
    550  */
    551 struct nfsrdresult {
    552 	nfsstat	rr_status;			/* status of read */
    553 	union {
    554 		struct nfsrrok	rr_ok_u;	/* attributes, need for pagin */
    555 	} rr_u;
    556 };
    557 #define	rr_ok		rr_u.rr_ok_u
    558 #define	rr_attr		rr_u.rr_ok_u.rrok_attr
    559 #define	rr_count	rr_u.rr_ok_u.rrok_count
    560 #define	rr_bufsize	rr_u.rr_ok_u.rrok_bufsize
    561 #define	rr_data		rr_u.rr_ok_u.rrok_data
    562 #define	rr_mp		rr_u.rr_ok_u.rrok_mp
    563 
    564 /*
    565  * File attributes which can be set
    566  */
    567 struct nfssattr {
    568 	uint32_t	sa_mode;	/* protection mode bits */
    569 	uint32_t	sa_uid;		/* owner user id */
    570 	uint32_t	sa_gid;		/* owner group id */
    571 	uint32_t	sa_size;	/* file size in bytes */
    572 	struct nfs2_timeval sa_atime;	/* time of last access */
    573 	struct nfs2_timeval sa_mtime;	/* time of last modification */
    574 };
    575 
    576 
    577 /*
    578  * Reply status with file attributes
    579  */
    580 struct nfsattrstat {
    581 	nfsstat	ns_status;			/* reply status */
    582 	union {
    583 		struct nfsfattr ns_attr_u;	/* NFS_OK: file attributes */
    584 	} ns_u;
    585 };
    586 #define	ns_attr	ns_u.ns_attr_u
    587 
    588 
    589 /*
    590  * NFS_OK part of read sym link reply union
    591  */
    592 struct nfssrok {
    593 	uint32_t srok_count;	/* size of string */
    594 	char	*srok_data;	/* string (up to NFS_MAXPATHLEN bytes) */
    595 };
    596 
    597 /*
    598  * Result of reading symbolic link
    599  */
    600 struct nfsrdlnres {
    601 	nfsstat	rl_status;			/* status of symlink read */
    602 	union {
    603 		struct nfssrok	rl_srok_u;	/* name of linked to */
    604 	} rl_u;
    605 };
    606 #define	rl_srok		rl_u.rl_srok_u
    607 #define	rl_count	rl_u.rl_srok_u.srok_count
    608 #define	rl_data		rl_u.rl_srok_u.srok_data
    609 
    610 
    611 /*
    612  * Arguments to readdir
    613  */
    614 struct nfsrddirargs {
    615 	fhandle_t rda_fh;	/* directory handle */
    616 	uint32_t rda_offset;	/* offset in directory (opaque) */
    617 	uint32_t rda_count;	/* number of directory bytes to read */
    618 };
    619 
    620 /*
    621  * NFS_OK part of readdir result
    622  */
    623 struct nfsrdok {
    624 	uint32_t rdok_offset;		/* next offset (opaque) */
    625 	uint32_t rdok_size;		/* size in bytes of entries */
    626 	bool_t	rdok_eof;		/* true if last entry is in result */
    627 	struct dirent64 *rdok_entries;	/* variable number of entries */
    628 };
    629 
    630 /*
    631  * Readdir result
    632  */
    633 struct nfsrddirres {
    634 	nfsstat	rd_status;
    635 	uint_t		rd_bufsize;	/* client request size (not xdr'ed) */
    636 	union {
    637 		struct nfsrdok rd_rdok_u;
    638 	} rd_u;
    639 };
    640 #define	rd_rdok		rd_u.rd_rdok_u
    641 #define	rd_offset	rd_u.rd_rdok_u.rdok_offset
    642 #define	rd_size		rd_u.rd_rdok_u.rdok_size
    643 #define	rd_eof		rd_u.rd_rdok_u.rdok_eof
    644 #define	rd_entries	rd_u.rd_rdok_u.rdok_entries
    645 
    646 
    647 /*
    648  * Arguments for directory operations
    649  */
    650 struct nfsdiropargs {
    651 	fhandle_t	*da_fhandle;	/* pointer to directory file handle */
    652 	char		*da_name;	/* name (up to NFS_MAXNAMLEN bytes) */
    653 	fhandle_t	da_fhandle_buf;	/* directory file handle */
    654 	int		da_flags;	/* flags, see below */
    655 };
    656 #define	DA_FREENAME	1
    657 
    658 /*
    659  * NFS_OK part of directory operation result
    660  */
    661 struct  nfsdrok {
    662 	fhandle_t	drok_fhandle;	/* result file handle */
    663 	struct nfsfattr	drok_attr;	/* result file attributes */
    664 };
    665 
    666 /*
    667  * Results from directory operation
    668  */
    669 struct  nfsdiropres {
    670 	nfsstat	dr_status;			/* result status */
    671 	union {
    672 		struct  nfsdrok	dr_drok_u;	/* NFS_OK result */
    673 	} dr_u;
    674 };
    675 #define	dr_drok		dr_u.dr_drok_u
    676 #define	dr_fhandle	dr_u.dr_drok_u.drok_fhandle
    677 #define	dr_attr		dr_u.dr_drok_u.drok_attr
    678 
    679 /*
    680  * arguments to setattr
    681  */
    682 struct nfssaargs {
    683 	fhandle_t	saa_fh;		/* fhandle of file to be set */
    684 	struct nfssattr	saa_sa;		/* new attributes */
    685 };
    686 
    687 /*
    688  * arguments to create and mkdir
    689  */
    690 struct nfscreatargs {
    691 	struct nfsdiropargs	ca_da;	/* file name to create and parent dir */
    692 	struct nfssattr		*ca_sa;	/* initial attributes */
    693 	struct nfssattr		ca_sa_buf;	/* space to store attributes */
    694 };
    695 
    696 /*
    697  * arguments to link
    698  */
    699 struct nfslinkargs {
    700 	fhandle_t		*la_from;	/* old file */
    701 	fhandle_t		la_from_buf;	/* old file */
    702 	struct nfsdiropargs	la_to;		/* new file and parent dir */
    703 };
    704 
    705 /*
    706  * arguments to rename
    707  */
    708 struct nfsrnmargs {
    709 	struct nfsdiropargs rna_from;	/* old file and parent dir */
    710 	struct nfsdiropargs rna_to;	/* new file and parent dir */
    711 };
    712 
    713 /*
    714  * arguments to symlink
    715  */
    716 struct nfsslargs {
    717 	struct nfsdiropargs	sla_from;	/* old file and parent dir */
    718 	char			*sla_tnm;	/* new name */
    719 	int			sla_tnm_flags;	/* flags for name */
    720 	struct nfssattr		*sla_sa;	/* attributes */
    721 	struct nfssattr		sla_sa_buf;	/* attributes buffer */
    722 };
    723 #define	SLA_FREETNM	1
    724 
    725 /*
    726  * NFS_OK part of statfs operation
    727  */
    728 struct nfsstatfsok {
    729 	uint32_t fsok_tsize;	/* preferred transfer size in bytes */
    730 	uint32_t fsok_bsize;	/* fundamental file system block size */
    731 	uint32_t fsok_blocks;	/* total blocks in file system */
    732 	uint32_t fsok_bfree;	/* free blocks in fs */
    733 	uint32_t fsok_bavail;	/* free blocks avail to non-superuser */
    734 };
    735 
    736 /*
    737  * Results of statfs operation
    738  */
    739 struct nfsstatfs {
    740 	nfsstat	fs_status;			/* result status */
    741 	union {
    742 		struct	nfsstatfsok fs_fsok_u;	/* NFS_OK result */
    743 	} fs_u;
    744 };
    745 #define	fs_fsok		fs_u.fs_fsok_u
    746 #define	fs_tsize	fs_u.fs_fsok_u.fsok_tsize
    747 #define	fs_bsize	fs_u.fs_fsok_u.fsok_bsize
    748 #define	fs_blocks	fs_u.fs_fsok_u.fsok_blocks
    749 #define	fs_bfree	fs_u.fs_fsok_u.fsok_bfree
    750 #define	fs_bavail	fs_u.fs_fsok_u.fsok_bavail
    751 
    752 #ifdef _KERNEL
    753 /*
    754  * XDR routines for handling structures defined above
    755  */
    756 extern bool_t	xdr_attrstat(XDR *, struct nfsattrstat *);
    757 extern bool_t	xdr_fastattrstat(XDR *, struct nfsattrstat *);
    758 extern bool_t	xdr_creatargs(XDR *, struct nfscreatargs *);
    759 extern bool_t	xdr_diropargs(XDR *, struct nfsdiropargs *);
    760 extern bool_t	xdr_diropres(XDR *, struct nfsdiropres *);
    761 extern bool_t	xdr_fastdiropres(XDR *, struct nfsdiropres *);
    762 extern bool_t	xdr_drok(XDR *, struct nfsdrok *);
    763 #ifdef _LITTLE_ENDIAN
    764 extern bool_t	xdr_fastdrok(XDR *, struct nfsdrok *);
    765 extern bool_t	xdr_fastfattr(XDR *, struct nfsfattr *);
    766 #endif
    767 extern bool_t	xdr_fattr(XDR *, struct nfsfattr *);
    768 extern bool_t	xdr_fhandle(XDR *, fhandle_t *);
    769 extern bool_t	xdr_fastfhandle(XDR *, fhandle_t **);
    770 extern bool_t	xdr_linkargs(XDR *, struct nfslinkargs *);
    771 extern bool_t	xdr_rddirargs(XDR *, struct nfsrddirargs *);
    772 extern bool_t	xdr_putrddirres(XDR *, struct nfsrddirres *);
    773 extern bool_t	xdr_getrddirres(XDR *, struct nfsrddirres *);
    774 extern bool_t	xdr_rdlnres(XDR *, struct nfsrdlnres *);
    775 extern bool_t	xdr_rdresult(XDR *, struct nfsrdresult *);
    776 extern bool_t	xdr_readargs(XDR *, struct nfsreadargs *);
    777 extern bool_t	xdr_readlink(XDR *, fhandle_t *);
    778 extern bool_t	xdr_rnmargs(XDR *, struct nfsrnmargs *);
    779 extern bool_t	xdr_rrok(XDR *, struct nfsrrok *);
    780 extern bool_t	xdr_saargs(XDR *, struct nfssaargs *);
    781 extern bool_t	xdr_sattr(XDR *, struct nfssattr *);
    782 extern bool_t	xdr_slargs(XDR *, struct nfsslargs *);
    783 extern bool_t	xdr_srok(XDR *, struct nfssrok *);
    784 extern bool_t	xdr_nfs2_timeval(XDR *, struct nfs2_timeval *);
    785 extern bool_t	xdr_writeargs(XDR *, struct nfswriteargs *);
    786 extern bool_t	xdr_fsok(XDR *, struct nfsstatfsok *);
    787 #ifdef _LITTLE_ENDIAN
    788 extern bool_t	xdr_fastfsok(XDR *, struct nfsstatfsok *);
    789 extern bool_t	xdr_fastenum(XDR *, enum_t *);
    790 #endif
    791 extern bool_t	xdr_statfs(XDR *, struct nfsstatfs *);
    792 extern bool_t	xdr_faststatfs(XDR *, struct nfsstatfs *);
    793 #endif
    794 
    795 /*
    796  * Remote file service routines
    797  */
    798 #define	RFS_NULL	0
    799 #define	RFS_GETATTR	1
    800 #define	RFS_SETATTR	2
    801 #define	RFS_ROOT	3
    802 #define	RFS_LOOKUP	4
    803 #define	RFS_READLINK	5
    804 #define	RFS_READ	6
    805 #define	RFS_WRITECACHE	7
    806 #define	RFS_WRITE	8
    807 #define	RFS_CREATE	9
    808 #define	RFS_REMOVE	10
    809 #define	RFS_RENAME	11
    810 #define	RFS_LINK	12
    811 #define	RFS_SYMLINK	13
    812 #define	RFS_MKDIR	14
    813 #define	RFS_RMDIR	15
    814 #define	RFS_READDIR	16
    815 #define	RFS_STATFS	17
    816 #define	RFS_NPROC	18
    817 
    818 #ifdef _KERNEL
    819 /*
    820  * The NFS Version 2 service procedures
    821  */
    822 struct exportinfo;	/* defined in nfs/export.h */
    823 struct servinfo;	/* defined in nfs/nfs_clnt.h */
    824 struct mntinfo;		/* defined in nfs/nfs_clnt.h */
    825 
    826 extern void rfs_getattr(fhandle_t *, struct nfsattrstat *,
    827 			struct exportinfo *, struct svc_req *, cred_t *);
    828 extern void *rfs_getattr_getfh(fhandle_t *);
    829 extern void rfs_setattr(struct nfssaargs *, struct nfsattrstat *,
    830 			struct exportinfo *, struct svc_req *, cred_t *);
    831 extern void *rfs_setattr_getfh(struct nfssaargs *);
    832 extern void rfs_lookup(struct nfsdiropargs *, struct nfsdiropres *,
    833 			struct exportinfo *, struct svc_req *, cred_t *);
    834 extern void *rfs_lookup_getfh(struct nfsdiropargs *);
    835 extern void rfs_readlink(fhandle_t *, struct nfsrdlnres *,
    836 			struct exportinfo *, struct svc_req *, cred_t *);
    837 extern void *rfs_readlink_getfh(fhandle_t *);
    838 extern void rfs_rlfree(struct nfsrdlnres *);
    839 extern void rfs_read(struct nfsreadargs *, struct nfsrdresult *,
    840 			struct exportinfo *, struct svc_req *, cred_t *);
    841 extern void *rfs_read_getfh(struct nfsreadargs *);
    842 extern void rfs_rdfree(struct nfsrdresult *);
    843 extern void rfs_write_sync(struct nfswriteargs *, struct nfsattrstat *,
    844 			struct exportinfo *, struct svc_req *, cred_t *);
    845 extern void rfs_write(struct nfswriteargs *, struct nfsattrstat *,
    846 			struct exportinfo *, struct svc_req *, cred_t *);
    847 extern void *rfs_write_getfh(struct nfswriteargs *);
    848 extern void rfs_create(struct nfscreatargs *, struct nfsdiropres *,
    849 			struct exportinfo *, struct svc_req *, cred_t *);
    850 extern void *rfs_create_getfh(struct nfscreatargs *);
    851 extern void rfs_remove(struct nfsdiropargs *, enum nfsstat *,
    852 			struct exportinfo *, struct svc_req *, cred_t *);
    853 extern void *rfs_remove_getfh(struct nfsdiropargs *);
    854 extern void rfs_rename(struct nfsrnmargs *, enum nfsstat *,
    855 			struct exportinfo *, struct svc_req *, cred_t *);
    856 extern void *rfs_rename_getfh(struct nfsrnmargs *);
    857 extern void rfs_link(struct nfslinkargs *, enum nfsstat *,
    858 			struct exportinfo *, struct svc_req *, cred_t *);
    859 extern void *rfs_link_getfh(struct nfslinkargs *);
    860 extern void rfs_symlink(struct nfsslargs *, enum nfsstat *,
    861 			struct exportinfo *, struct svc_req *, cred_t *);
    862 extern void *rfs_symlink_getfh(struct nfsslargs *);
    863 extern void rfs_mkdir(struct nfscreatargs *, struct nfsdiropres *,
    864 			struct exportinfo *, struct svc_req *, cred_t *);
    865 extern void *rfs_mkdir_getfh(struct nfscreatargs *);
    866 extern void rfs_rmdir(struct nfsdiropargs *, enum nfsstat *,
    867 			struct exportinfo *, struct svc_req *, cred_t *);
    868 extern void *rfs_rmdir_getfh(struct nfsdiropargs *);
    869 extern void rfs_readdir(struct nfsrddirargs *, struct nfsrddirres *,
    870 			struct exportinfo *, struct svc_req *, cred_t *);
    871 extern void *rfs_readdir_getfh(struct nfsrddirargs *);
    872 extern void rfs_rddirfree(struct nfsrddirres *);
    873 extern void rfs_statfs(fhandle_t *, struct nfsstatfs *,
    874 			struct exportinfo *, struct svc_req *, cred_t *);
    875 extern void *rfs_statfs_getfh(fhandle_t *);
    876 extern void rfs_srvrinit(void);
    877 extern void rfs_srvrfini(void);
    878 
    879 /*
    880  * flags to define path types during Multi Component Lookups
    881  * using the public filehandle
    882  */
    883 #define	URLPATH		0x01	/* Universal Resource Locator path */
    884 #define	NATIVEPATH	0x02	/* Native path, i.e., via mount protocol */
    885 #define	SECURITY_QUERY	0x04	/* Security query */
    886 
    887 enum nfs_svccounts {NFS_CALLS, NFS_BADCALLS}; /* index for svstat_ptr */
    888 
    889 /*	function defs for NFS kernel */
    890 extern int	nfs_waitfor_purge_complete(vnode_t *);
    891 extern int	nfs_validate_caches(vnode_t *, cred_t *);
    892 extern void	nfs_purge_caches(vnode_t *, int, cred_t *);
    893 extern void	nfs_purge_rddir_cache(vnode_t *);
    894 extern void	nfs_attrcache(vnode_t *, struct nfsfattr *, hrtime_t);
    895 extern int	nfs_cache_fattr(vnode_t *, struct nfsfattr *, vattr_t *,
    896 				hrtime_t, cred_t *);
    897 extern void	nfs_attr_cache(vnode_t *, vattr_t *, hrtime_t, cred_t *);
    898 extern void	nfs_attrcache_va(vnode_t *, struct vattr *);
    899 extern int	nfs_getattr_otw(vnode_t *, struct vattr *, cred_t *);
    900 extern int	nfsgetattr(vnode_t *, struct vattr *, cred_t *);
    901 extern int	nattr_to_vattr(vnode_t *, struct nfsfattr *, struct vattr *);
    902 extern void	nfs_async_manager(struct vfs *);
    903 extern void	nfs_async_manager_stop(struct vfs *);
    904 extern void	nfs_async_stop(struct vfs *);
    905 extern int	nfs_async_stop_sig(struct vfs *);
    906 extern int	nfs_clntinit(void);
    907 extern void	nfs_clntfini(void);
    908 extern int	nfstsize(void);
    909 extern int	nfs_srvinit(void);
    910 extern void	nfs_srvfini(void);
    911 extern int	vattr_to_sattr(struct vattr *, struct nfssattr *);
    912 extern void	setdiropargs(struct nfsdiropargs *, char *, vnode_t *);
    913 extern int	setdirgid(vnode_t *, gid_t *, cred_t *);
    914 extern int	setdirmode(vnode_t *, mode_t *, cred_t *);
    915 extern int	newnum(void);
    916 extern char	*newname(void);
    917 extern int	nfs_atoi(char *);
    918 extern int	nfs_subrinit(void);
    919 extern void	nfs_subrfini(void);
    920 extern enum nfsstat puterrno(int);
    921 extern int	geterrno(enum nfsstat);
    922 extern int	nfsinit(int, char *);
    923 extern void	nfsfini(void);
    924 extern int	nfs_vfsinit(void);
    925 extern void	nfs_vfsfini(void);
    926 extern int	nfs_dump(vnode_t *, caddr_t, offset_t, offset_t,
    927     caller_context_t *);
    928 extern void	nfs_perror(int error, char *fmt, ...);
    929 extern void	nfs_cmn_err(int error, int level, char *fmt, ...);
    930 extern int	nfs_addcllock(vnode_t *vp, struct flock64 *bfp);
    931 extern void