changeset 14031:bcbb822da4dd

3630 NFS server should not allocate oversized buffers Reviewed by: Jeff Biseda <jeff.biseda@delphix.com> Reviewed by: Eric Schrock <Eric.Schrock@delphix.com> Reviewed by: Gordon Ross <gordon.ross@nexenta.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Marcel Telka <marcel.telka@nexenta.com> Approved by: Albert Lee <trisk@nexenta.com>
author Sebastien Roy <seb@delphix.com>
date Tue, 21 May 2013 15:31:47 -0800
parents ceba83929df4
children 11aad50aea32
files usr/src/uts/common/fs/nfs/nfs3_srv.c usr/src/uts/common/fs/nfs/nfs3_xdr.c usr/src/uts/common/fs/nfs/nfs4_srv.c usr/src/uts/common/fs/nfs/nfs4_xdr.c usr/src/uts/common/fs/nfs/nfs_server.c usr/src/uts/common/nfs/nfs.h usr/src/uts/common/rpc/sec_gss/rpcsec_gss_misc.c usr/src/uts/common/sys/kmem.h
diffstat 8 files changed, 514 insertions(+), 415 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/nfs/nfs3_srv.c	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs3_srv.c	Tue May 21 15:31:47 2013 -0800
@@ -20,8 +20,8 @@
  */
 /*
  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
- *
  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  */
 
 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -58,7 +58,6 @@
 #include <nfs/nfs_cmd.h>
 
 #include <sys/strsubr.h>
-
 #include <sys/tsol/label.h>
 #include <sys/tsol/tndb.h>
 
@@ -922,11 +921,11 @@
 	vnode_t *vp;
 	struct vattr *vap;
 	struct vattr va;
-	struct iovec iov;
+	struct iovec iov, *iovp = NULL;
+	int iovcnt;
 	struct uio uio;
 	u_offset_t offset;
 	mblk_t *mp = NULL;
-	int alloc_err = 0;
 	int in_crit = 0;
 	int need_rwunlock = 0;
 	caller_context_t ct;
@@ -1114,25 +1113,21 @@
 	 */
 	if (rdma_used) {
 		(void) rdma_get_wchunk(req, &iov, args->wlist);
+		uio.uio_iov = &iov;
+		uio.uio_iovcnt = 1;
 	} else {
 		/*
 		 * mp will contain the data to be sent out in the read reply.
-		 * This will be freed after the reply has been sent out (by the
-		 * driver).
-		 * Let's roundup the data to a BYTES_PER_XDR_UNIT multiple, so
-		 * that the call to xdrmblk_putmblk() never fails.
+		 * For UDP, this will be freed after the reply has been sent
+		 * out by the driver.  For TCP, it will be freed after the last
+		 * segment associated with the reply has been ACKed by the
+		 * client.
 		 */
-		mp = allocb_wait(RNDUP(args->count), BPRI_MED, STR_NOSIG,
-		    &alloc_err);
-		ASSERT(mp != NULL);
-		ASSERT(alloc_err == 0);
-
-		iov.iov_base = (caddr_t)mp->b_datap->db_base;
-		iov.iov_len = args->count;
+		mp = rfs_read_alloc(args->count, &iovp, &iovcnt);
+		uio.uio_iov = iovp;
+		uio.uio_iovcnt = iovcnt;
 	}
 
-	uio.uio_iov = &iov;
-	uio.uio_iovcnt = 1;
 	uio.uio_segflg = UIO_SYSSPACE;
 	uio.uio_extflg = UIO_COPY_CACHED;
 	uio.uio_loffset = args->offset;
@@ -1203,6 +1198,9 @@
 
 	VN_RELE(vp);
 
+	if (iovp != NULL)
+		kmem_free(iovp, iovcnt * sizeof (struct iovec));
+
 	return;
 
 out:
@@ -1223,6 +1221,9 @@
 		VN_RELE(vp);
 	}
 	vattr_to_post_op_attr(vap, &resp->resfail.file_attributes);
+
+	if (iovp != NULL)
+		kmem_free(iovp, iovcnt * sizeof (struct iovec));
 }
 
 void
@@ -3912,7 +3913,6 @@
 void *
 rfs3_fsinfo_getfh(FSINFO3args *args)
 {
-
 	return (&args->fsroot);
 }
 
--- a/usr/src/uts/common/fs/nfs/nfs3_xdr.c	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs3_xdr.c	Tue May 21 15:31:47 2013 -0800
@@ -26,6 +26,10 @@
 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
 /* All Rights Reserved */
 
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/systm.h>
@@ -1324,12 +1328,36 @@
 	if (xdrs->x_op == XDR_ENCODE) {
 
 		mp = resokp->data.mp;
-		if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
-			if (xdrmblk_putmblk(xdrs, mp, resokp->count) == TRUE) {
-				resokp->data.mp = NULL;
-				return (TRUE);
+		if (mp != NULL) {
+			if (xdrs->x_ops == &xdrmblk_ops) {
+				if (xdrmblk_putmblk(xdrs, mp, resokp->count)) {
+					resokp->data.mp = NULL;
+					return (TRUE);
+				} else {
+					return (FALSE);
+				}
+			} else if (mp->b_cont != NULL) {
+				/*
+				 * We have read results in an mblk chain, but
+				 * the encoding operations don't handle mblks
+				 * (they'll operate on data.data_val rather
+				 * than data.mp).  Because data_val can only
+				 * point at a single data buffer, we need to
+				 * pullup the read results into a single data
+				 * block and reset data_val to point to it.
+				 *
+				 * This happens with RPC GSS where the wrapping
+				 * function does XDR serialization into a
+				 * temporary buffer prior to applying GSS.
+				 * Because we're not in a performance sensitive
+				 * path, the pullupmsg() here shouldn't hurt us
+				 * too badly.
+				 */
+				if (pullupmsg(mp, -1) == 0)
+					return (FALSE);
+				resokp->data.data_val = (caddr_t)mp->b_rptr;
 			}
-		} else if (mp == NULL) {
+		} else {
 			if (xdr_u_int(xdrs, &resokp->count) == FALSE) {
 				return (FALSE);
 			}
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c	Tue May 21 15:31:47 2013 -0800
@@ -20,9 +20,8 @@
  */
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-/*
  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 /*
@@ -3141,7 +3140,8 @@
 	int verror;
 	vnode_t *vp;
 	struct vattr va;
-	struct iovec iov;
+	struct iovec iov, *iovp = NULL;
+	int iovcnt;
 	struct uio uio;
 	u_offset_t offset;
 	bool_t *deleg = &cs->deleg;
@@ -3305,32 +3305,20 @@
 	if (rdma_used) {
 		mp = NULL;
 		(void) rdma_get_wchunk(req, &iov, args->wlist);
+		uio.uio_iov = &iov;
+		uio.uio_iovcnt = 1;
 	} else {
 		/*
 		 * mp will contain the data to be sent out in the read reply.
-		 * It will be freed after the reply has been sent. Let's
-		 * roundup the data to a BYTES_PER_XDR_UNIT multiple, so that
-		 * the call to xdrmblk_putmblk() never fails. If the first
-		 * alloc of the requested size fails, then decrease the size to
-		 * something more reasonable and wait for the allocation to
-		 * occur.
+		 * It will be freed after the reply has been sent.
 		 */
-		mp = allocb(RNDUP(args->count), BPRI_MED);
-		if (mp == NULL) {
-			if (args->count > MAXBSIZE)
-				args->count = MAXBSIZE;
-			mp = allocb_wait(RNDUP(args->count), BPRI_MED,
-			    STR_NOSIG, &alloc_err);
-		}
+		mp = rfs_read_alloc(args->count, &iovp, &iovcnt);
 		ASSERT(mp != NULL);
 		ASSERT(alloc_err == 0);
-
-		iov.iov_base = (caddr_t)mp->b_datap->db_base;
-		iov.iov_len = args->count;
-	}
-
-	uio.uio_iov = &iov;
-	uio.uio_iovcnt = 1;
+		uio.uio_iov = iovp;
+		uio.uio_iovcnt = iovcnt;
+	}
+
 	uio.uio_segflg = UIO_SYSSPACE;
 	uio.uio_extflg = UIO_COPY_CACHED;
 	uio.uio_loffset = args->offset;
@@ -3386,6 +3374,9 @@
 	if (in_crit)
 		nbl_end_crit(vp);
 
+	if (iovp != NULL)
+		kmem_free(iovp, iovcnt * sizeof (struct iovec));
+
 	DTRACE_NFSV4_2(op__read__done, struct compound_state *, cs,
 	    READ4res *, resp);
 }
--- a/usr/src/uts/common/fs/nfs/nfs4_xdr.c	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_xdr.c	Tue May 21 15:31:47 2013 -0800
@@ -24,6 +24,7 @@
  */
 /*
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  */
 
 /*
@@ -3379,12 +3380,24 @@
 		return (FALSE);
 
 	mp = objp->mblk;
-	if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
-		if (xdrmblk_putmblk(xdrs, mp, objp->data_len) == TRUE) {
-			objp->mblk = NULL;
-			return (TRUE);
+	if (mp != NULL) {
+		if (xdrs->x_ops == &xdrmblk_ops) {
+			if (xdrmblk_putmblk(xdrs, mp, objp->data_len)) {
+				objp->mblk = NULL;
+				return (TRUE);
+			} else {
+				return (FALSE);
+			}
+		} else if (mp->b_cont != NULL) {
+			/*
+			 * See xdr_READ3res() for an explanation of why we need
+			 * to do a pullup here.
+			 */
+			if (pullupmsg(mp, -1) == 0)
+				return (FALSE);
+			objp->data_val = (caddr_t)mp->b_rptr;
 		}
-	} else if (mp == NULL) {
+	} else {
 		if (xdr_u_int(xdrs, &objp->data_len) == FALSE) {
 			return (FALSE);
 		}
--- a/usr/src/uts/common/fs/nfs/nfs_server.c	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c	Tue May 21 15:31:47 2013 -0800
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  */
 
 /*
@@ -49,6 +50,7 @@
 #include <sys/tiuser.h>
 #include <sys/statvfs.h>
 #include <sys/stream.h>
+#include <sys/strsun.h>
 #include <sys/strsubr.h>
 #include <sys/stropts.h>
 #include <sys/timod.h>
@@ -3308,45 +3310,109 @@
 	return (mp);
 }
 
+/*
+ * Allocate memory to hold data for a read request of len bytes.
+ *
+ * We don't allocate buffers greater than kmem_max_cached in size to avoid
+ * allocating memory from the kmem_oversized arena.  If we allocate oversized
+ * buffers, we incur heavy cross-call activity when freeing these large buffers
+ * in the TCP receive path. Note that we can't set b_wptr here since the
+ * length of the data returned may differ from the length requested when
+ * reading the end of a file; we set b_wptr in rfs_rndup_mblks() once the
+ * length of the read is known.
+ */
+mblk_t *
+rfs_read_alloc(uint_t len, struct iovec **iov, int *iovcnt)
+{
+	struct iovec *iovarr;
+	mblk_t *mp, **mpp = &mp;
+	size_t mpsize;
+	uint_t remain = len;
+	int i, err = 0;
+
+	*iovcnt = howmany(len, kmem_max_cached);
+
+	iovarr = kmem_alloc(*iovcnt * sizeof (struct iovec), KM_SLEEP);
+	*iov = iovarr;
+
+	for (i = 0; i < *iovcnt; remain -= mpsize, i++) {
+		ASSERT(remain <= len);
+		/*
+		 * We roundup the size we allocate to a multiple of
+		 * BYTES_PER_XDR_UNIT (4 bytes) so that the call to
+		 * xdrmblk_putmblk() never fails.
+		 */
+		ASSERT(kmem_max_cached % BYTES_PER_XDR_UNIT == 0);
+		mpsize = MIN(kmem_max_cached, remain);
+		*mpp = allocb_wait(RNDUP(mpsize), BPRI_MED, STR_NOSIG, &err);
+		ASSERT(*mpp != NULL);
+		ASSERT(err == 0);
+
+		iovarr[i].iov_base = (caddr_t)(*mpp)->b_rptr;
+		iovarr[i].iov_len = mpsize;
+		mpp = &(*mpp)->b_cont;
+	}
+	return (mp);
+}
+
 void
 rfs_rndup_mblks(mblk_t *mp, uint_t len, int buf_loaned)
 {
-	int i, rndup;
+	int i;
 	int alloc_err = 0;
 	mblk_t *rmp;
-
-	rndup = BYTES_PER_XDR_UNIT - (len % BYTES_PER_XDR_UNIT);
-
-	/* single mblk_t non copy-reduction case */
+	uint_t mpsize, remainder;
+
+	remainder = P2NPHASE(len, BYTES_PER_XDR_UNIT);
+
+	/*
+	 * Non copy-reduction case.  This function assumes that blocks were
+	 * allocated in multiples of BYTES_PER_XDR_UNIT bytes, which makes this
+	 * padding safe without bounds checking.
+	 */
 	if (!buf_loaned) {
+		/*
+		 * Set the size of each mblk in the chain until we've consumed
+		 * the specified length for all but the last one.
+		 */
+		while ((mpsize = MBLKSIZE(mp)) < len) {
+			ASSERT(mpsize % BYTES_PER_XDR_UNIT == 0);
+			mp->b_wptr += mpsize;
+			len -= mpsize;
+			mp = mp->b_cont;
+			ASSERT(mp != NULL);
+		}
+
+		ASSERT(len + remainder <= mpsize);
 		mp->b_wptr += len;
-		if (rndup != BYTES_PER_XDR_UNIT) {
-			for (i = 0; i < rndup; i++)
-				*mp->b_wptr++ = '\0';
-		}
+		for (i = 0; i < remainder; i++)
+			*mp->b_wptr++ = '\0';
 		return;
 	}
 
-	/* no need for extra rndup */
-	if (rndup == BYTES_PER_XDR_UNIT)
+	/*
+	 * No remainder mblk required.
+	 */
+	if (remainder == 0)
 		return;
 
-	while (mp->b_cont)
+	/*
+	 * Get to the last mblk in the chain.
+	 */
+	while (mp->b_cont != NULL)
 		mp = mp->b_cont;
 
 	/*
-	 * In case of copy-reduction mblks, the size of the mblks
-	 * are fixed and are of the size of the loaned buffers.
-	 * Allocate a roundup mblk and chain it to the data
-	 * buffers. This is sub-optimal, but not expected to
-	 * happen in regular common workloads.
+	 * In case of copy-reduction mblks, the size of the mblks are fixed
+	 * and are of the size of the loaned buffers.  Allocate a remainder
+	 * mblk and chain it to the data buffers. This is sub-optimal, but not
+	 * expected to happen commonly.
 	 */
-
-	rmp = allocb_wait(rndup, BPRI_MED, STR_NOSIG, &alloc_err);
+	rmp = allocb_wait(remainder, BPRI_MED, STR_NOSIG, &alloc_err);
 	ASSERT(rmp != NULL);
 	ASSERT(alloc_err == 0);
 
-	for (i = 0; i < rndup; i++)
+	for (i = 0; i < remainder; i++)
 		*rmp->b_wptr++ = '\0';
 
 	rmp->b_datap->db_type = M_DATA;
--- a/usr/src/uts/common/nfs/nfs.h	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/nfs/nfs.h	Tue May 21 15:31:47 2013 -0800
@@ -22,6 +22,7 @@
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  *
  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  */
 
 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
@@ -749,43 +750,43 @@
 /*
  * XDR routines for handling structures defined above
  */
-extern bool_t	xdr_attrstat(XDR *, struct nfsattrstat *);
-extern bool_t	xdr_fastattrstat(XDR *, struct nfsattrstat *);
-extern bool_t	xdr_creatargs(XDR *, struct nfscreatargs *);
-extern bool_t	xdr_diropargs(XDR *, struct nfsdiropargs *);
-extern bool_t	xdr_diropres(XDR *, struct nfsdiropres *);
-extern bool_t	xdr_fastdiropres(XDR *, struct nfsdiropres *);
-extern bool_t	xdr_drok(XDR *, struct nfsdrok *);
+bool_t	xdr_attrstat(XDR *, struct nfsattrstat *);
+bool_t	xdr_fastattrstat(XDR *, struct nfsattrstat *);
+bool_t	xdr_creatargs(XDR *, struct nfscreatargs *);
+bool_t	xdr_diropargs(XDR *, struct nfsdiropargs *);
+bool_t	xdr_diropres(XDR *, struct nfsdiropres *);
+bool_t	xdr_fastdiropres(XDR *, struct nfsdiropres *);
+bool_t	xdr_drok(XDR *, struct nfsdrok *);
 #ifdef _LITTLE_ENDIAN
-extern bool_t	xdr_fastdrok(XDR *, struct nfsdrok *);
-extern bool_t	xdr_fastfattr(XDR *, struct nfsfattr *);
+bool_t	xdr_fastdrok(XDR *, struct nfsdrok *);
+bool_t	xdr_fastfattr(XDR *, struct nfsfattr *);
 #endif
-extern bool_t	xdr_fattr(XDR *, struct nfsfattr *);
-extern bool_t	xdr_fhandle(XDR *, fhandle_t *);
-extern bool_t	xdr_fastfhandle(XDR *, fhandle_t **);
-extern bool_t	xdr_linkargs(XDR *, struct nfslinkargs *);
-extern bool_t	xdr_rddirargs(XDR *, struct nfsrddirargs *);
-extern bool_t	xdr_putrddirres(XDR *, struct nfsrddirres *);
-extern bool_t	xdr_getrddirres(XDR *, struct nfsrddirres *);
-extern bool_t	xdr_rdlnres(XDR *, struct nfsrdlnres *);
-extern bool_t	xdr_rdresult(XDR *, struct nfsrdresult *);
-extern bool_t	xdr_readargs(XDR *, struct nfsreadargs *);
-extern bool_t	xdr_readlink(XDR *, fhandle_t *);
-extern bool_t	xdr_rnmargs(XDR *, struct nfsrnmargs *);
-extern bool_t	xdr_rrok(XDR *, struct nfsrrok *);
-extern bool_t	xdr_saargs(XDR *, struct nfssaargs *);
-extern bool_t	xdr_sattr(XDR *, struct nfssattr *);
-extern bool_t	xdr_slargs(XDR *, struct nfsslargs *);
-extern bool_t	xdr_srok(XDR *, struct nfssrok *);
-extern bool_t	xdr_nfs2_timeval(XDR *, struct nfs2_timeval *);
-extern bool_t	xdr_writeargs(XDR *, struct nfswriteargs *);
-extern bool_t	xdr_fsok(XDR *, struct nfsstatfsok *);
+bool_t	xdr_fattr(XDR *, struct nfsfattr *);
+bool_t	xdr_fhandle(XDR *, fhandle_t *);
+bool_t	xdr_fastfhandle(XDR *, fhandle_t **);
+bool_t	xdr_linkargs(XDR *, struct nfslinkargs *);
+bool_t	xdr_rddirargs(XDR *, struct nfsrddirargs *);
+bool_t	xdr_putrddirres(XDR *, struct nfsrddirres *);
+bool_t	xdr_getrddirres(XDR *, struct nfsrddirres *);
+bool_t	xdr_rdlnres(XDR *, struct nfsrdlnres *);
+bool_t	xdr_rdresult(XDR *, struct nfsrdresult *);
+bool_t	xdr_readargs(XDR *, struct nfsreadargs *);
+bool_t	xdr_readlink(XDR *, fhandle_t *);
+bool_t	xdr_rnmargs(XDR *, struct nfsrnmargs *);
+bool_t	xdr_rrok(XDR *, struct nfsrrok *);
+bool_t	xdr_saargs(XDR *, struct nfssaargs *);
+bool_t	xdr_sattr(XDR *, struct nfssattr *);
+bool_t	xdr_slargs(XDR *, struct nfsslargs *);
+bool_t	xdr_srok(XDR *, struct nfssrok *);
+bool_t	xdr_nfs2_timeval(XDR *, struct nfs2_timeval *);
+bool_t	xdr_writeargs(XDR *, struct nfswriteargs *);
+bool_t	xdr_fsok(XDR *, struct nfsstatfsok *);
 #ifdef _LITTLE_ENDIAN
-extern bool_t	xdr_fastfsok(XDR *, struct nfsstatfsok *);
-extern bool_t	xdr_fastenum(XDR *, enum_t *);
+bool_t	xdr_fastfsok(XDR *, struct nfsstatfsok *);
+bool_t	xdr_fastenum(XDR *, enum_t *);
 #endif
-extern bool_t	xdr_statfs(XDR *, struct nfsstatfs *);
-extern bool_t	xdr_faststatfs(XDR *, struct nfsstatfs *);
+bool_t	xdr_statfs(XDR *, struct nfsstatfs *);
+bool_t	xdr_faststatfs(XDR *, struct nfsstatfs *);
 #endif
 
 /*
@@ -819,58 +820,58 @@
 struct servinfo;	/* defined in nfs/nfs_clnt.h */
 struct mntinfo;		/* defined in nfs/nfs_clnt.h */
 
-extern void rfs_getattr(fhandle_t *, struct nfsattrstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_getattr_getfh(fhandle_t *);
-extern void rfs_setattr(struct nfssaargs *, struct nfsattrstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_setattr_getfh(struct nfssaargs *);
-extern void rfs_lookup(struct nfsdiropargs *, struct nfsdiropres *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_lookup_getfh(struct nfsdiropargs *);
-extern void rfs_readlink(fhandle_t *, struct nfsrdlnres *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_readlink_getfh(fhandle_t *);
-extern void rfs_rlfree(struct nfsrdlnres *);
-extern void rfs_read(struct nfsreadargs *, struct nfsrdresult *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_read_getfh(struct nfsreadargs *);
-extern void rfs_rdfree(struct nfsrdresult *);
-extern void rfs_write_sync(struct nfswriteargs *, struct nfsattrstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void rfs_write(struct nfswriteargs *, struct nfsattrstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_write_getfh(struct nfswriteargs *);
-extern void rfs_create(struct nfscreatargs *, struct nfsdiropres *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_create_getfh(struct nfscreatargs *);
-extern void rfs_remove(struct nfsdiropargs *, enum nfsstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_remove_getfh(struct nfsdiropargs *);
-extern void rfs_rename(struct nfsrnmargs *, enum nfsstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_rename_getfh(struct nfsrnmargs *);
-extern void rfs_link(struct nfslinkargs *, enum nfsstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_link_getfh(struct nfslinkargs *);
-extern void rfs_symlink(struct nfsslargs *, enum nfsstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_symlink_getfh(struct nfsslargs *);
-extern void rfs_mkdir(struct nfscreatargs *, struct nfsdiropres *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_mkdir_getfh(struct nfscreatargs *);
-extern void rfs_rmdir(struct nfsdiropargs *, enum nfsstat *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_rmdir_getfh(struct nfsdiropargs *);
-extern void rfs_readdir(struct nfsrddirargs *, struct nfsrddirres *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_readdir_getfh(struct nfsrddirargs *);
-extern void rfs_rddirfree(struct nfsrddirres *);
-extern void rfs_statfs(fhandle_t *, struct nfsstatfs *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs_statfs_getfh(fhandle_t *);
-extern void rfs_srvrinit(void);
-extern void rfs_srvrfini(void);
+void	rfs_getattr(fhandle_t *, struct nfsattrstat *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_getattr_getfh(fhandle_t *);
+void	rfs_setattr(struct nfssaargs *, struct nfsattrstat *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_setattr_getfh(struct nfssaargs *);
+void	rfs_lookup(struct nfsdiropargs *, struct nfsdiropres *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_lookup_getfh(struct nfsdiropargs *);
+void	rfs_readlink(fhandle_t *, struct nfsrdlnres *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_readlink_getfh(fhandle_t *);
+void	rfs_rlfree(struct nfsrdlnres *);
+void	rfs_read(struct nfsreadargs *, struct nfsrdresult *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_read_getfh(struct nfsreadargs *);
+void	rfs_rdfree(struct nfsrdresult *);
+void	rfs_write_sync(struct nfswriteargs *, struct nfsattrstat *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	rfs_write(struct nfswriteargs *, struct nfsattrstat *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_write_getfh(struct nfswriteargs *);
+void	rfs_create(struct nfscreatargs *, struct nfsdiropres *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_create_getfh(struct nfscreatargs *);
+void	rfs_remove(struct nfsdiropargs *, enum nfsstat *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_remove_getfh(struct nfsdiropargs *);
+void	rfs_rename(struct nfsrnmargs *, enum nfsstat *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_rename_getfh(struct nfsrnmargs *);
+void	rfs_link(struct nfslinkargs *, enum nfsstat *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_link_getfh(struct nfslinkargs *);
+void	rfs_symlink(struct nfsslargs *, enum nfsstat *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_symlink_getfh(struct nfsslargs *);
+void	rfs_mkdir(struct nfscreatargs *, struct nfsdiropres *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_mkdir_getfh(struct nfscreatargs *);
+void	rfs_rmdir(struct nfsdiropargs *, enum nfsstat *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_rmdir_getfh(struct nfsdiropargs *);
+void	rfs_readdir(struct nfsrddirargs *, struct nfsrddirres *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs_readdir_getfh(struct nfsrddirargs *);
+void	rfs_rddirfree(struct nfsrddirres *);
+void	rfs_statfs(fhandle_t *, struct nfsstatfs *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs_statfs_getfh(fhandle_t *);
+void	rfs_srvrinit(void);
+void	rfs_srvrfini(void);
 
 /*
  * flags to define path types during Multi Component Lookups
@@ -884,78 +885,74 @@
 enum nfs_svccounts {NFS_CALLS, NFS_BADCALLS, NFS_REFERRALS, NFS_REFERLINKS};
 
 /*	function defs for NFS kernel */
-extern int	nfs_waitfor_purge_complete(vnode_t *);
-extern int	nfs_validate_caches(vnode_t *, cred_t *);
-extern void	nfs_purge_caches(vnode_t *, int, cred_t *);
-extern void	nfs_purge_rddir_cache(vnode_t *);
-extern void	nfs_attrcache(vnode_t *, struct nfsfattr *, hrtime_t);
-extern int	nfs_cache_fattr(vnode_t *, struct nfsfattr *, vattr_t *,
-				hrtime_t, cred_t *);
-extern void	nfs_attr_cache(vnode_t *, vattr_t *, hrtime_t, cred_t *);
-extern void	nfs_attrcache_va(vnode_t *, struct vattr *);
-extern int	nfs_getattr_otw(vnode_t *, struct vattr *, cred_t *);
-extern int	nfsgetattr(vnode_t *, struct vattr *, cred_t *);
-extern int	nattr_to_vattr(vnode_t *, struct nfsfattr *, struct vattr *);
-extern void	nfs_async_manager(struct vfs *);
-extern void	nfs_async_manager_stop(struct vfs *);
-extern void	nfs_async_stop(struct vfs *);
-extern int	nfs_async_stop_sig(struct vfs *);
-extern int	nfs_clntinit(void);
-extern void	nfs_clntfini(void);
-extern int	nfstsize(void);
-extern int	nfs_srvinit(void);
-extern void	nfs_srvfini(void);
-extern int	vattr_to_sattr(struct vattr *, struct nfssattr *);
-extern void	setdiropargs(struct nfsdiropargs *, char *, vnode_t *);
-extern int	setdirgid(vnode_t *, gid_t *, cred_t *);
-extern int	setdirmode(vnode_t *, mode_t *, cred_t *);
-extern int	newnum(void);
-extern char	*newname(void);
-extern int	nfs_subrinit(void);
-extern void	nfs_subrfini(void);
-extern enum nfsstat puterrno(int);
-extern int	geterrno(enum nfsstat);
-extern int	nfsinit(int, char *);
-extern void	nfsfini(void);
-extern int	nfs_vfsinit(void);
-extern void	nfs_vfsfini(void);
-extern int	nfs_dump(vnode_t *, caddr_t, offset_t, offset_t,
-    caller_context_t *);
-extern void	nfs_perror(int error, char *fmt, ...);
-extern void	nfs_cmn_err(int error, int level, char *fmt, ...);
-extern int	nfs_addcllock(vnode_t *vp, struct flock64 *bfp);
-extern void	nfs_rmcllock(vnode_t *vp, struct flock64 *bfp);
-extern void	nfs_lockrelease(vnode_t *vp, int flag,
-		    offset_t offset, cred_t *credp);
-extern int	vattr_to_nattr(struct vattr *, struct nfsfattr *);
-extern int	mount_root(char *, char *, int, struct nfs_args *, int *);
-extern void	nfs_lockcompletion(vnode_t *vp, int cmd);
-extern void	nfs_add_locking_id(vnode_t *, pid_t, int, char *, int);
-extern void	nfs3copyfh(caddr_t, vnode_t *);
-extern void	nfscopyfh(caddr_t, vnode_t *);
-extern int	nfs3lookup(vnode_t *, char *, vnode_t **, struct pathname *,
-				int, vnode_t *, cred_t *, int);
-extern int	nfslookup(vnode_t *, char *, vnode_t **, struct pathname *,
-				int, vnode_t *, cred_t *, int);
-extern void	sv_free(struct servinfo *);
-extern int	nfsauth_access(struct exportinfo *exi, struct svc_req *req);
-extern void	nfsauth_init();
-extern void	nfsauth_fini();
-extern int	nfs_setopts(vnode_t *vp, model_t model, struct nfs_args *args);
-extern int	nfs_mount_label_policy(vfs_t *vfsp, struct netbuf *addr,
-		    struct knetconfig *knconf, cred_t *cr);
-extern boolean_t	nfs_has_ctty(void);
-extern void	nfs_srv_stop_all(void);
-extern void	nfs_srv_quiesce_all(void);
-extern void	(*nfs_srv_quiesce_func)(void);
-extern int	rfs4_dss_setpaths(char *, size_t);
-extern int	(*nfs_srv_dss_func)(char *, size_t);
-extern int	nfs_setmod_check(page_t *pp);
+int	nfs_waitfor_purge_complete(vnode_t *);
+int	nfs_validate_caches(vnode_t *, cred_t *);
+void	nfs_purge_caches(vnode_t *, int, cred_t *);
+void	nfs_purge_rddir_cache(vnode_t *);
+void	nfs_attrcache(vnode_t *, struct nfsfattr *, hrtime_t);
+int	nfs_cache_fattr(vnode_t *, struct nfsfattr *, vattr_t *, hrtime_t,
+    cred_t *);
+void	nfs_attr_cache(vnode_t *, vattr_t *, hrtime_t, cred_t *);
+void	nfs_attrcache_va(vnode_t *, struct vattr *);
+int	nfs_getattr_otw(vnode_t *, struct vattr *, cred_t *);
+int	nfsgetattr(vnode_t *, struct vattr *, cred_t *);
+int	nattr_to_vattr(vnode_t *, struct nfsfattr *, struct vattr *);
+void	nfs_async_manager(struct vfs *);
+void	nfs_async_manager_stop(struct vfs *);
+void	nfs_async_stop(struct vfs *);
+int	nfs_async_stop_sig(struct vfs *);
+int	nfs_clntinit(void);
+void	nfs_clntfini(void);
+int	nfstsize(void);
+int	nfs_srvinit(void);
+void	nfs_srvfini(void);
+int	vattr_to_sattr(struct vattr *, struct nfssattr *);
+void	setdiropargs(struct nfsdiropargs *, char *, vnode_t *);
+int	setdirgid(vnode_t *, gid_t *, cred_t *);
+int	setdirmode(vnode_t *, mode_t *, cred_t *);
+int	newnum(void);
+char	*newname(void);
+int	nfs_subrinit(void);
+void	nfs_subrfini(void);
+enum nfsstat puterrno(int);
+int	geterrno(enum nfsstat);
+int	nfsinit(int, char *);
+void	nfsfini(void);
+int	nfs_vfsinit(void);
+void	nfs_vfsfini(void);
+int	nfs_dump(vnode_t *, caddr_t, offset_t, offset_t, caller_context_t *);
+void	nfs_perror(int error, char *fmt, ...);
+void	nfs_cmn_err(int error, int level, char *fmt, ...);
+int	nfs_addcllock(vnode_t *vp, struct flock64 *bfp);
+void	nfs_rmcllock(vnode_t *vp, struct flock64 *bfp);
+void	nfs_lockrelease(vnode_t *vp, int flag, offset_t offset, cred_t *credp);
+int	vattr_to_nattr(struct vattr *, struct nfsfattr *);
+int	mount_root(char *, char *, int, struct nfs_args *, int *);
+void	nfs_lockcompletion(vnode_t *vp, int cmd);
+void	nfs_add_locking_id(vnode_t *, pid_t, int, char *, int);
+void	nfs3copyfh(caddr_t, vnode_t *);
+void	nfscopyfh(caddr_t, vnode_t *);
+int	nfs3lookup(vnode_t *, char *, vnode_t **, struct pathname *, int,
+    vnode_t *, cred_t *, int);
+int	nfslookup(vnode_t *, char *, vnode_t **, struct pathname *, int,
+    vnode_t *, cred_t *, int);
+void	sv_free(struct servinfo *);
+int	nfsauth_access(struct exportinfo *exi, struct svc_req *req);
+void	nfsauth_init();
+void	nfsauth_fini();
+int	nfs_setopts(vnode_t *vp, model_t model, struct nfs_args *args);
+int	nfs_mount_label_policy(vfs_t *vfsp, struct netbuf *addr,
+    struct knetconfig *knconf, cred_t *cr);
+boolean_t nfs_has_ctty(void);
+void	nfs_srv_stop_all(void);
+void	nfs_srv_quiesce_all(void);
+int	rfs4_dss_setpaths(char *, size_t);
+int	nfs_setmod_check(page_t *pp);
+
 extern time_t	rfs4_lease_time;
 extern time_t	rfs4_grace_period;
 extern nvlist_t	*rfs4_dss_paths, *rfs4_dss_oldpaths;
 
-
 extern kstat_named_t	*global_svstat_ptr[];
 
 extern krwlock_t	rroklock;
@@ -968,6 +965,8 @@
 extern struct vnodeops	*nfs_vnodeops;
 extern const struct fs_operation_def nfs_vnodeops_template[];
 extern int		nfsfstyp;
+extern void		(*nfs_srv_quiesce_func)(void);
+extern int		(*nfs_srv_dss_func)(char *, size_t);
 
 /*
  * Per-zone stats as consumed by nfsstat(1m)
@@ -997,8 +996,8 @@
 /*
  * Zone callback functions.
  */
-extern void *nfsstat_zone_init(zoneid_t);
-extern void nfsstat_zone_fini(zoneid_t, void *);
+void	*nfsstat_zone_init(zoneid_t);
+void	nfsstat_zone_fini(zoneid_t, void *);
 
 #endif	/* _KERNEL */
 
@@ -2093,82 +2092,82 @@
 #define	NFSPROC3_COMMIT ((rpcproc_t)21)
 
 #ifndef _KERNEL
-extern  void * nfsproc3_null_3();
-extern  GETATTR3res * nfsproc3_getattr_3();
-extern  SETATTR3res * nfsproc3_setattr_3();
-extern  LOOKUP3res * nfsproc3_lookup_3();
-extern  ACCESS3res * nfsproc3_access_3();
-extern  READLINK3res * nfsproc3_readlink_3();
-extern  READ3res * nfsproc3_read_3();
-extern  WRITE3res * nfsproc3_write_3();
-extern  CREATE3res * nfsproc3_create_3();
-extern  MKDIR3res * nfsproc3_mkdir_3();
-extern  SYMLINK3res * nfsproc3_symlink_3();
-extern  MKNOD3res * nfsproc3_mknod_3();
-extern  REMOVE3res * nfsproc3_remove_3();
-extern  RMDIR3res * nfsproc3_rmdir_3();
-extern  RENAME3res * nfsproc3_rename_3();
-extern  LINK3res * nfsproc3_link_3();
-extern  READDIR3res * nfsproc3_readdir_3();
-extern  READDIRPLUS3res * nfsproc3_readdirplus_3();
-extern  FSSTAT3res * nfsproc3_fsstat_3();
-extern  FSINFO3res * nfsproc3_fsinfo_3();
-extern  PATHCONF3res * nfsproc3_pathconf_3();
-extern  COMMIT3res * nfsproc3_commit_3();
+void		*nfsproc3_null_3();
+GETATTR3res	*nfsproc3_getattr_3();
+SETATTR3res	*nfsproc3_setattr_3();
+LOOKUP3res	*nfsproc3_lookup_3();
+ACCESS3res	*nfsproc3_access_3();
+READLINK3res	*nfsproc3_readlink_3();
+READ3res	*nfsproc3_read_3();
+WRITE3res	*nfsproc3_write_3();
+CREATE3res	*nfsproc3_create_3();
+MKDIR3res	*nfsproc3_mkdir_3();
+SYMLINK3res	*nfsproc3_symlink_3();
+MKNOD3res	*nfsproc3_mknod_3();
+REMOVE3res	*nfsproc3_remove_3();
+RMDIR3res	*nfsproc3_rmdir_3();
+RENAME3res	*nfsproc3_rename_3();
+LINK3res	*nfsproc3_link_3();
+READDIR3res	*nfsproc3_readdir_3();
+READDIRPLUS3res	*nfsproc3_readdirplus_3();
+FSSTAT3res	*nfsproc3_fsstat_3();
+FSINFO3res	*nfsproc3_fsinfo_3();
+PATHCONF3res	*nfsproc3_pathconf_3();
+COMMIT3res	*nfsproc3_commit_3();
 #endif	/* !_KERNEL */
 
 #ifdef _KERNEL
 /* the NFS Version 3 XDR functions */
 
-extern bool_t xdr_nfs_fh3(XDR *, nfs_fh3 *);
-extern bool_t xdr_nfslog_nfs_fh3(XDR *, nfs_fh3 *);
-extern bool_t xdr_nfs_fh3_server(XDR *, nfs_fh3 *);
-extern bool_t xdr_diropargs3(XDR *, diropargs3 *);
-extern bool_t xdr_post_op_attr(XDR *, post_op_attr *);
-extern bool_t xdr_post_op_fh3(XDR *, post_op_fh3 *);
-extern bool_t xdr_GETATTR3res(XDR *, GETATTR3res *);
-extern bool_t xdr_GETATTR3vres(XDR *, GETATTR3vres *);
-extern bool_t xdr_SETATTR3args(XDR *, SETATTR3args *);
-extern bool_t xdr_SETATTR3res(XDR *, SETATTR3res *);
-extern bool_t xdr_LOOKUP3res(XDR *, LOOKUP3res *);
-extern bool_t xdr_LOOKUP3vres(XDR *, LOOKUP3vres *);
-extern bool_t xdr_ACCESS3args(XDR *, ACCESS3args *);
-extern bool_t xdr_ACCESS3res(XDR *, ACCESS3res *);
-extern bool_t xdr_READLINK3args(XDR *, READLINK3args *);
-extern bool_t xdr_READLINK3res(XDR *, READLINK3res *);
-extern bool_t xdr_READ3args(XDR *, READ3args *);
-extern bool_t xdr_READ3res(XDR *, READ3res *);
-extern bool_t xdr_READ3vres(XDR *, READ3vres *);
-extern bool_t xdr_READ3uiores(XDR *, READ3uiores *);
-extern bool_t xdr_WRITE3args(XDR *, WRITE3args *);
-extern bool_t xdr_WRITE3res(XDR *, WRITE3res *);
-extern bool_t xdr_CREATE3args(XDR *, CREATE3args *);
-extern bool_t xdr_CREATE3res(XDR *, CREATE3res *);
-extern bool_t xdr_MKDIR3args(XDR *, MKDIR3args *);
-extern bool_t xdr_MKDIR3res(XDR *, MKDIR3res *);
-extern bool_t xdr_SYMLINK3args(XDR *, SYMLINK3args *);
-extern bool_t xdr_SYMLINK3res(XDR *, SYMLINK3res *);
-extern bool_t xdr_MKNOD3args(XDR *, MKNOD3args *);
-extern bool_t xdr_MKNOD3res(XDR *, MKNOD3res *);
-extern bool_t xdr_REMOVE3res(XDR *, REMOVE3res *);
-extern bool_t xdr_RMDIR3resfail(XDR *, RMDIR3resfail *);
-extern bool_t xdr_RMDIR3res(XDR *, RMDIR3res *);
-extern bool_t xdr_RENAME3args(XDR *, RENAME3args *);
-extern bool_t xdr_RENAME3res(XDR *, RENAME3res *);
-extern bool_t xdr_LINK3args(XDR *, LINK3args *);
-extern bool_t xdr_LINK3res(XDR *, LINK3res *);
-extern bool_t xdr_READDIR3args(XDR *, READDIR3args *);
-extern bool_t xdr_READDIR3res(XDR *, READDIR3res *);
-extern bool_t xdr_READDIR3vres(XDR *, READDIR3vres *);
-extern bool_t xdr_READDIRPLUS3args(XDR *, READDIRPLUS3args *);
-extern bool_t xdr_READDIRPLUS3res(XDR *, READDIRPLUS3res *);
-extern bool_t xdr_READDIRPLUS3vres(XDR *, READDIRPLUS3vres *);
-extern bool_t xdr_FSSTAT3res(XDR *, FSSTAT3res *);
-extern bool_t xdr_FSINFO3res(XDR *, FSINFO3res *);
-extern bool_t xdr_PATHCONF3res(XDR *, PATHCONF3res *);
-extern bool_t xdr_COMMIT3args(XDR *, COMMIT3args *);
-extern bool_t xdr_COMMIT3res(XDR *, COMMIT3res *);
-extern bool_t xdr_fastnfs_fh3(XDR *, nfs_fh3 **);
+bool_t xdr_nfs_fh3(XDR *, nfs_fh3 *);
+bool_t xdr_nfslog_nfs_fh3(XDR *, nfs_fh3 *);
+bool_t xdr_nfs_fh3_server(XDR *, nfs_fh3 *);
+bool_t xdr_diropargs3(XDR *, diropargs3 *);
+bool_t xdr_post_op_attr(XDR *, post_op_attr *);
+bool_t xdr_post_op_fh3(XDR *, post_op_fh3 *);
+bool_t xdr_GETATTR3res(XDR *, GETATTR3res *);
+bool_t xdr_GETATTR3vres(XDR *, GETATTR3vres *);
+bool_t xdr_SETATTR3args(XDR *, SETATTR3args *);
+bool_t xdr_SETATTR3res(XDR *, SETATTR3res *);
+bool_t xdr_LOOKUP3res(XDR *, LOOKUP3res *);
+bool_t xdr_LOOKUP3vres(XDR *, LOOKUP3vres *);
+bool_t xdr_ACCESS3args(XDR *, ACCESS3args *);
+bool_t xdr_ACCESS3res(XDR *, ACCESS3res *);
+bool_t xdr_READLINK3args(XDR *, READLINK3args *);
+bool_t xdr_READLINK3res(XDR *, READLINK3res *);
+bool_t xdr_READ3args(XDR *, READ3args *);
+bool_t xdr_READ3res(XDR *, READ3res *);
+bool_t xdr_READ3vres(XDR *, READ3vres *);
+bool_t xdr_READ3uiores(XDR *, READ3uiores *);
+bool_t xdr_WRITE3args(XDR *, WRITE3args *);
+bool_t xdr_WRITE3res(XDR *, WRITE3res *);
+bool_t xdr_CREATE3args(XDR *, CREATE3args *);
+bool_t xdr_CREATE3res(XDR *, CREATE3res *);
+bool_t xdr_MKDIR3args(XDR *, MKDIR3args *);
+bool_t xdr_MKDIR3res(XDR *, MKDIR3res *);
+bool_t xdr_SYMLINK3args(XDR *, SYMLINK3args *);
+bool_t xdr_SYMLINK3res(XDR *, SYMLINK3res *);
+bool_t xdr_MKNOD3args(XDR *, MKNOD3args *);
+bool_t xdr_MKNOD3res(XDR *, MKNOD3res *);
+bool_t xdr_REMOVE3res(XDR *, REMOVE3res *);
+bool_t xdr_RMDIR3resfail(XDR *, RMDIR3resfail *);
+bool_t xdr_RMDIR3res(XDR *, RMDIR3res *);
+bool_t xdr_RENAME3args(XDR *, RENAME3args *);
+bool_t xdr_RENAME3res(XDR *, RENAME3res *);
+bool_t xdr_LINK3args(XDR *, LINK3args *);
+bool_t xdr_LINK3res(XDR *, LINK3res *);
+bool_t xdr_READDIR3args(XDR *, READDIR3args *);
+bool_t xdr_READDIR3res(XDR *, READDIR3res *);
+bool_t xdr_READDIR3vres(XDR *, READDIR3vres *);
+bool_t xdr_READDIRPLUS3args(XDR *, READDIRPLUS3args *);
+bool_t xdr_READDIRPLUS3res(XDR *, READDIRPLUS3res *);
+bool_t xdr_READDIRPLUS3vres(XDR *, READDIRPLUS3vres *);
+bool_t xdr_FSSTAT3res(XDR *, FSSTAT3res *);
+bool_t xdr_FSINFO3res(XDR *, FSINFO3res *);
+bool_t xdr_PATHCONF3res(XDR *, PATHCONF3res *);
+bool_t xdr_COMMIT3args(XDR *, COMMIT3args *);
+bool_t xdr_COMMIT3res(XDR *, COMMIT3res *);
+bool_t xdr_fastnfs_fh3(XDR *, nfs_fh3 **);
 
 /*
  * The NFS Version 3 service procedures.
@@ -2178,105 +2177,103 @@
 struct mntinfo;		/* defined in nfs/nfs_clnt.h */
 struct sec_ol;		/* defined in nfs/export.h */
 
-extern void rfs3_getattr(GETATTR3args *, GETATTR3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_getattr_getfh(GETATTR3args *);
-extern void rfs3_setattr(SETATTR3args *, SETATTR3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_setattr_getfh(SETATTR3args *);
-extern void rfs3_lookup(LOOKUP3args *, LOOKUP3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_lookup_getfh(LOOKUP3args *);
-extern void rfs3_access(ACCESS3args *, ACCESS3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_access_getfh(ACCESS3args *);
-extern void rfs3_readlink(READLINK3args *, READLINK3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_readlink_getfh(READLINK3args *);
-extern void rfs3_readlink_free(READLINK3res *);
-extern void rfs3_read(READ3args *, READ3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_read_getfh(READ3args *);
-extern void rfs3_read_free(READ3res *);
-extern void rfs3_write(WRITE3args *, WRITE3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_write_getfh(WRITE3args *);
-extern void rfs3_create(CREATE3args *, CREATE3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_create_getfh(CREATE3args *);
-extern void rfs3_mkdir(MKDIR3args *, MKDIR3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_mkdir_getfh(MKDIR3args *);
-extern void rfs3_symlink(SYMLINK3args *, SYMLINK3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_symlink_getfh(SYMLINK3args *);
-extern void rfs3_mknod(MKNOD3args *, MKNOD3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_mknod_getfh(MKNOD3args *);
-extern void rfs3_remove(REMOVE3args *, REMOVE3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_remove_getfh(REMOVE3args *);
-extern void rfs3_rmdir(RMDIR3args *, RMDIR3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_rmdir_getfh(RMDIR3args *);
-extern void rfs3_rename(RENAME3args *, RENAME3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_rename_getfh(RENAME3args *);
-extern void rfs3_link(LINK3args *, LINK3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_link_getfh(LINK3args *);
-extern void rfs3_readdir(READDIR3args *, READDIR3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_readdir_getfh(READDIR3args *);
-extern void rfs3_readdir_free(READDIR3res *);
-extern void rfs3_readdirplus(READDIRPLUS3args *, READDIRPLUS3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_readdirplus_getfh(READDIRPLUS3args *);
-extern void rfs3_readdirplus_free(READDIRPLUS3res *);
-extern void rfs3_fsstat(FSSTAT3args *, FSSTAT3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_fsstat_getfh(FSSTAT3args *);
-extern void rfs3_fsinfo(FSINFO3args *, FSINFO3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_fsinfo_getfh(FSINFO3args *);
-extern void rfs3_pathconf(PATHCONF3args *, PATHCONF3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_pathconf_getfh(PATHCONF3args *);
-extern void rfs3_commit(COMMIT3args *, COMMIT3res *,
-			struct exportinfo *, struct svc_req *, cred_t *);
-extern void *rfs3_commit_getfh(COMMIT3args *);
-extern void rfs3_srvrinit(void);
-extern void rfs3_srvrfini(void);
+void	rfs3_getattr(GETATTR3args *, GETATTR3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_getattr_getfh(GETATTR3args *);
+void	rfs3_setattr(SETATTR3args *, SETATTR3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_setattr_getfh(SETATTR3args *);
+void	rfs3_lookup(LOOKUP3args *, LOOKUP3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_lookup_getfh(LOOKUP3args *);
+void	rfs3_access(ACCESS3args *, ACCESS3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_access_getfh(ACCESS3args *);
+void	rfs3_readlink(READLINK3args *, READLINK3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_readlink_getfh(READLINK3args *);
+void	rfs3_readlink_free(READLINK3res *);
+void	rfs3_read(READ3args *, READ3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_read_getfh(READ3args *);
+void	rfs3_read_free(READ3res *);
+void	rfs3_write(WRITE3args *, WRITE3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_write_getfh(WRITE3args *);
+void	rfs3_create(CREATE3args *, CREATE3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_create_getfh(CREATE3args *);
+void	rfs3_mkdir(MKDIR3args *, MKDIR3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_mkdir_getfh(MKDIR3args *);
+void	rfs3_symlink(SYMLINK3args *, SYMLINK3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_symlink_getfh(SYMLINK3args *);
+void	rfs3_mknod(MKNOD3args *, MKNOD3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_mknod_getfh(MKNOD3args *);
+void	rfs3_remove(REMOVE3args *, REMOVE3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_remove_getfh(REMOVE3args *);
+void	rfs3_rmdir(RMDIR3args *, RMDIR3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_rmdir_getfh(RMDIR3args *);
+void	rfs3_rename(RENAME3args *, RENAME3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_rename_getfh(RENAME3args *);
+void	rfs3_link(LINK3args *, LINK3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_link_getfh(LINK3args *);
+void	rfs3_readdir(READDIR3args *, READDIR3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_readdir_getfh(READDIR3args *);
+void	rfs3_readdir_free(READDIR3res *);
+void	rfs3_readdirplus(READDIRPLUS3args *, READDIRPLUS3res *,
+    struct exportinfo *, struct svc_req *, cred_t *);
+void	*rfs3_readdirplus_getfh(READDIRPLUS3args *);
+void	rfs3_readdirplus_free(READDIRPLUS3res *);
+void	rfs3_fsstat(FSSTAT3args *, FSSTAT3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_fsstat_getfh(FSSTAT3args *);
+void	rfs3_fsinfo(FSINFO3args *, FSINFO3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_fsinfo_getfh(FSINFO3args *);
+void	rfs3_pathconf(PATHCONF3args *, PATHCONF3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_pathconf_getfh(PATHCONF3args *);
+void	rfs3_commit(COMMIT3args *, COMMIT3res *, struct exportinfo *,
+    struct svc_req *, cred_t *);
+void	*rfs3_commit_getfh(COMMIT3args *);
+void	rfs3_srvrinit(void);
+void	rfs3_srvrfini(void);
 
-extern int	nfs3_validate_caches(vnode_t *, cred_t *);
-extern void	nfs3_cache_post_op_attr(vnode_t *, post_op_attr *, hrtime_t,
-			cred_t *);
-extern void	nfs3_cache_post_op_vattr(vnode_t *, post_op_vattr *, hrtime_t,
-			cred_t *);
-extern void	nfs3_cache_wcc_data(vnode_t *, wcc_data *, hrtime_t, cred_t *);
-extern void	nfs3_attrcache(vnode_t *, fattr3 *, hrtime_t);
-extern int	nfs3_cache_fattr3(vnode_t *, fattr3 *, vattr_t *, hrtime_t,
-			cred_t *);
-extern int	nfs3_getattr_otw(vnode_t *, struct vattr *, cred_t *);
-extern int	nfs3getattr(vnode_t *, struct vattr *, cred_t *);
-extern int	fattr3_to_vattr(vnode_t *, fattr3 *, struct vattr *);
-extern int	nfs3tsize(void);
-extern uint_t	nfs3_tsize(struct knetconfig *);
-extern uint_t	rfs3_tsize(struct svc_req *);
-extern int	vattr_to_sattr3(struct vattr *, sattr3 *);
-extern void	setdiropargs3(diropargs3 *, char *, vnode_t *);
-extern enum nfsstat3 puterrno3(int);
-extern int	geterrno3(enum nfsstat3);
-extern int	nfs3init(int, char *);
-extern void	nfs3fini(void);
-extern int	nfs3_vfsinit(void);
-extern void	nfs3_vfsfini(void);
-extern void	vattr_to_post_op_attr(struct vattr *, post_op_attr *);
-extern void	mblk_to_iov(mblk_t *, int, struct iovec *);
-extern int	rfs_publicfh_mclookup(char *, vnode_t *, cred_t *,
-			vnode_t **, struct exportinfo **, struct sec_ol *);
-extern int	rfs_pathname(char *, vnode_t **, vnode_t **,
-			vnode_t *, cred_t *, int);
+int	nfs3_validate_caches(vnode_t *, cred_t *);
+void	nfs3_cache_post_op_attr(vnode_t *, post_op_attr *, hrtime_t, cred_t *);
+void	nfs3_cache_post_op_vattr(vnode_t *, post_op_vattr *, hrtime_t,
+    cred_t *);
+void	nfs3_cache_wcc_data(vnode_t *, wcc_data *, hrtime_t, cred_t *);
+void	nfs3_attrcache(vnode_t *, fattr3 *, hrtime_t);
+int	nfs3_cache_fattr3(vnode_t *, fattr3 *, vattr_t *, hrtime_t, cred_t *);
+int	nfs3_getattr_otw(vnode_t *, struct vattr *, cred_t *);
+int	nfs3getattr(vnode_t *, struct vattr *, cred_t *);
+int	fattr3_to_vattr(vnode_t *, fattr3 *, struct vattr *);
+int	nfs3tsize(void);
+uint_t	nfs3_tsize(struct knetconfig *);
+uint_t	rfs3_tsize(struct svc_req *);
+int	vattr_to_sattr3(struct vattr *, sattr3 *);
+void	setdiropargs3(diropargs3 *, char *, vnode_t *);
+enum nfsstat3 puterrno3(int);
+int	geterrno3(enum nfsstat3);
+int	nfs3init(int, char *);
+void	nfs3fini(void);
+int	nfs3_vfsinit(void);
+void	nfs3_vfsfini(void);
+void	vattr_to_post_op_attr(struct vattr *, post_op_attr *);
+void	mblk_to_iov(mblk_t *, int, struct iovec *);
+int	rfs_publicfh_mclookup(char *, vnode_t *, cred_t *, vnode_t **,
+    struct exportinfo **, struct sec_ol *);
+int	rfs_pathname(char *, vnode_t **, vnode_t **, vnode_t *, cred_t *, int);
+
 extern vtype_t		nf3_to_vt[];
 extern kstat_named_t	*rfsproccnt_v3_ptr;
 extern vfsops_t		*nfs3_vfsops;
@@ -2294,28 +2291,27 @@
 /*
  * External functions called by the v2/v3 code into the v4 code
  */
-extern void		nfs4_clnt_init(void);
-extern void		nfs4_clnt_fini(void);
+void	nfs4_clnt_init(void);
+void	nfs4_clnt_fini(void);
 
 /*
  * Does NFS4 server have a vnode delegated?  TRUE if so, FALSE if not.
  */
-extern bool_t rfs4_check_delegated(int mode, vnode_t *, bool_t trunc);
+bool_t	rfs4_check_delegated(int mode, vnode_t *, bool_t trunc);
 /*
  * VOP_GETATTR call. If a NFS4 delegation is present on the supplied vnode
  * call back to the delegated client to get attributes for AT_MTIME and
  * AT_SIZE. Invoke VOP_GETATTR to get all other attributes or all attributes
  * if no delegation is present.
  */
-extern int rfs4_delegated_getattr(vnode_t *, vattr_t *, int, cred_t *);
-extern void rfs4_hold_deleg_policy(void);
-extern void rfs4_rele_deleg_policy(void);
+int	rfs4_delegated_getattr(vnode_t *, vattr_t *, int, cred_t *);
+void	rfs4_hold_deleg_policy(void);
+void	rfs4_rele_deleg_policy(void);
 
-extern int do_xattr_exists_check(vnode_t *, ulong_t *, cred_t *);
+int	do_xattr_exists_check(vnode_t *, ulong_t *, cred_t *);
 
-extern ts_label_t	*nfs_getflabel(vnode_t *, struct exportinfo *);
-extern boolean_t	do_rfs_label_check(bslabel_t *, vnode_t *, int,
-			    struct exportinfo *);
+ts_label_t *nfs_getflabel(vnode_t *, struct exportinfo *);
+boolean_t do_rfs_label_check(bslabel_t *, vnode_t *, int, struct exportinfo *);
 
 /*
  * Copy Reduction support.
@@ -2329,10 +2325,11 @@
 	frtn_t nu_frtn;
 } nfs_xuio_t;
 
-xuio_t *rfs_setup_xuio(vnode_t *);
-mblk_t *uio_to_mblk(uio_t *);
-void rfs_rndup_mblks(mblk_t *, uint_t, int);
-void rfs_free_xuio(void *);
+xuio_t	*rfs_setup_xuio(vnode_t *);
+mblk_t	*uio_to_mblk(uio_t *);
+mblk_t	*rfs_read_alloc(uint_t, struct iovec **, int *);
+void	rfs_rndup_mblks(mblk_t *, uint_t, int);
+void	rfs_free_xuio(void *);
 
 #endif	/* _KERNEL */
 
--- a/usr/src/uts/common/rpc/sec_gss/rpcsec_gss_misc.c	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/rpc/sec_gss/rpcsec_gss_misc.c	Tue May 21 15:31:47 2013 -0800
@@ -24,8 +24,6 @@
  * All rights reserved.  Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
  *
@@ -34,6 +32,10 @@
  * 1994/10/27 12:39:23 jik Exp $
  */
 
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stream.h>
@@ -142,7 +144,7 @@
 	OM_uint32		major, minor;
 	gss_buffer_desc		in_buf, out_buf;
 	XDR			temp_xdrs;
-	char			*mp;
+	char			*temp_data;
 /* EXPORT DELETE START */
 	bool_t			conf_state;
 /* EXPORT DELETE END */
@@ -154,10 +156,10 @@
 	 * We need an extra bit for the sequence number serialized first.
 	 */
 	size = xdr_sizeof(xdr_func, xdr_ptr) + BYTES_PER_XDR_UNIT;
-	mp = kmem_alloc(size, KM_SLEEP);
+	temp_data = kmem_alloc(size, KM_SLEEP);
 	out_buf.length = 0;
 
-	xdrmem_create(&temp_xdrs, mp, size, XDR_ENCODE);
+	xdrmem_create(&temp_xdrs, temp_data, size, XDR_ENCODE);
 
 	/*
 	 * serialize the sequence number into tmp memory
@@ -221,7 +223,7 @@
 		goto fail;
 	ret = TRUE;
 fail:
-	kmem_free(mp, size);
+	kmem_free(temp_data, size);
 	if (out_buf.length != 0)
 		(void) gss_release_buffer(&minor, &out_buf);
 	return (ret);
--- a/usr/src/uts/common/sys/kmem.h	Fri May 17 11:06:02 2013 -0800
+++ b/usr/src/uts/common/sys/kmem.h	Tue May 21 15:31:47 2013 -0800
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -106,6 +107,7 @@
 
 extern int kmem_ready;
 extern pgcnt_t kmem_reapahead;
+extern size_t kmem_max_cached;
 
 extern void kmem_init(void);
 extern void kmem_thread_init(void);