changeset 4068:b443cd39eced

backout 4689230/6224349: needs more work
author dm120769
date Thu, 19 Apr 2007 14:39:35 -0700
parents 54aaa1fa93ec
children ad1037792ded
files usr/src/cmd/fs.d/autofs/autod_main.c usr/src/cmd/fs.d/autofs/autod_nfs.c usr/src/cmd/fs.d/autofs/autod_xdr.c usr/src/uts/common/fs/autofs/auto_subr.c usr/src/uts/common/fs/autofs/auto_xdr.c
diffstat 5 files changed, 358 insertions(+), 1552 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fs.d/autofs/autod_main.c	Thu Apr 19 14:35:48 2007 -0700
+++ b/usr/src/cmd/fs.d/autofs/autod_main.c	Thu Apr 19 14:39:35 2007 -0700
@@ -80,7 +80,6 @@
 static int start_autofs_svcs();
 static void automountd_wait_for_cleanup(pid_t);
 
-
 /*
  * Private autofs system call
  */
@@ -455,9 +454,8 @@
 			m->path, m->isdirect);
 	}
 
-	bzero(res, sizeof (*res));
 	status = do_mount1(m->map, m->name, m->subdir, m->opts, m->path,
-			(uint_t)m->isdirect, m->uid, &alp, DOMOUNT_KERNEL);
+			(uint_t)m->isdirect, m->uid, &alp, DOMOUNT_USER);
 	if (status != 0) {
 		/*
 		 * An error occurred, free action list if allocated.
@@ -468,6 +466,9 @@
 		}
 	}
 	if (alp != NULL) {
+		/*
+		 * Return action list to kernel.
+		 */
 		res->mr_type.status = AUTOFS_ACTION;
 		res->mr_type.mount_result_type_u.list = alp;
 	} else {
@@ -730,7 +731,7 @@
 			failed_res.res_status = error;
 			failed_res.xdr_len = 0;
 			res = (caddr_t)&failed_res;
-			res_size = sizeof (autofs_door_res_t);
+			res_size = 0;
 			break;
 		}
 		bzero(&lookup_res, sizeof (autofs_lookupres));
@@ -739,19 +740,14 @@
 
 		autofs_lookup_1_free_args(xdrargs);
 		free(xdrargs);
-		door_res = NULL;
+
 		if (!encode_res(xdr_autofs_lookupres, &door_res,
 					(caddr_t)&lookup_res, &res_size)) {
-			res_size = sizeof (autofs_door_res_t);
-			if (door_res == NULL) {
-				syslog(LOG_ERR, "error allocating lookup"
-				"results buffer");
-				failed_res.res_status = ENOMEM;
-				failed_res.xdr_len = 0;
-				res = (caddr_t)&failed_res;
-			} else {
-				res = (caddr_t)door_res;
-			}
+			syslog(LOG_ERR, "error allocating lookup"
+			"results buffer");
+			failed_res.res_status = EINVAL;
+			failed_res.xdr_len = 0;
+			res = (caddr_t)&failed_res;
 		} else {
 			door_res->res_status = 0;
 			res = (caddr_t)door_res;
@@ -767,13 +763,11 @@
 			failed_res.res_status = error;
 			failed_res.xdr_len = 0;
 			res = (caddr_t)&failed_res;
-			res_size = sizeof (autofs_door_res_t);
+			res_size = 0;
 			break;
 		}
 
-		bzero(&mount_res, sizeof (struct autofs_mountres));
-		autofs_mntinfo_1_r((autofs_lookupargs *)xdrargs,
-					&mount_res);
+		autofs_mntinfo_1_r((autofs_lookupargs *)xdrargs, &mount_res);
 
 		autofs_lookup_1_free_args(xdrargs);
 		free(xdrargs);
@@ -781,26 +775,20 @@
 		/*
 		 * Only reason we would get a NULL res is because
 		 * we could not allocate a results buffer.  Use
-		 * a local result buffer to return ENOMEM.
+		 * a local one to return the error EAGAIN as has
+		 * always been done when memory allocations fail.
 		 */
-		door_res = NULL;
 		if (!encode_res(xdr_autofs_mountres, &door_res,
 					(caddr_t)&mount_res, &res_size)) {
-			res_size = sizeof (autofs_door_res_t);
-			if (door_res == NULL) {
-				syslog(LOG_ERR, "error allocating mount"
-					"results buffer");
-				failed_res.res_status = ENOMEM;
-				failed_res.xdr_len = 0;
-				res = (caddr_t)&failed_res;
-			} else {
-				res = (caddr_t)door_res;
-			}
+			syslog(LOG_ERR, "error allocating mount"
+				"results buffer");
+			failed_res.res_status = EAGAIN;
+			failed_res.xdr_len = 0;
+			res = (caddr_t)&failed_res;
 		} else {
 			door_res->res_status = 0;
 			res = (caddr_t)door_res;
 		}
-
 		autofs_mount_1_free_r(&mount_res);
 		break;
 
@@ -823,19 +811,15 @@
 
 		autofs_unmount_1_free_args(umnt_args);
 		free(umnt_args);
-		door_res = NULL;
+
 		if (!encode_res(xdr_umntres, &door_res, (caddr_t)&umount_res,
 				&res_size)) {
+			syslog(LOG_ERR, "error allocating unmount"
+			    "results buffer");
+			failed_res.res_status = EINVAL;
+			failed_res.xdr_len = 0;
+			res = (caddr_t)&failed_res;
 			res_size = sizeof (autofs_door_res_t);
-			if (door_res == NULL) {
-				syslog(LOG_ERR, "error allocating unmount"
-					"results buffer");
-				failed_res.res_status = ENOMEM;
-				failed_res.xdr_len = 0;
-				res = (caddr_t)&failed_res;
-			} else {
-				res = (caddr_t)door_res;
-			}
 		} else {
 			door_res->res_status = 0;
 			res = (caddr_t)door_res;
@@ -860,19 +844,15 @@
 
 		free(rddir_args->rda_map);
 		free(rddir_args);
-		door_res = NULL;
+
 		if (!encode_res(xdr_autofs_rddirres, &door_res,
 		    (caddr_t)&rddir_res, &res_size)) {
+			syslog(LOG_ERR, "error allocating readdir"
+			    "results buffer");
+			failed_res.res_status = ENOMEM;
+			failed_res.xdr_len = 0;
+			res = (caddr_t)&failed_res;
 			res_size = sizeof (autofs_door_res_t);
-			if (door_res == NULL) {
-				syslog(LOG_ERR, "error allocating readdir"
-					"results buffer");
-				failed_res.res_status = ENOMEM;
-				failed_res.xdr_len = 0;
-				res = (caddr_t)&failed_res;
-			} else {
-				res = (caddr_t)door_res;
-			}
 		} else {
 			door_res->res_status = 0;
 			res = (caddr_t)door_res;
@@ -904,11 +884,8 @@
 	/*
 	 * If we got here, door_return failed.
 	 */
-
-	syslog(LOG_ERR,
-		"door_return failed %d, errno: %d, proc: %d,"
-		"  buffer %p, buffer size %d",
-		error, errno, which, (void *)res, res_size);
+	syslog(LOG_ERR, "door_return failed %d, buffer %p, buffer size %d",
+		error, (void *)res, res_size);
 }
 
 static int
@@ -1012,13 +989,13 @@
 	caddr_t resp,
 	int *size)
 {
-	XDR 	xdrs;
-	int	status;
+	XDR xdrs;
 
 	*size = xdr_sizeof((*xdrfunc), resp);
 	*results = autofs_get_buffer(
 	    sizeof (autofs_door_res_t) + *size);
 	if (*results == NULL) {
+		(*results)->res_status = ENOMEM;
 		return (FALSE);
 	}
 	(*results)->xdr_len = *size;
@@ -1026,10 +1003,9 @@
 	xdrmem_create(&xdrs, (caddr_t)((*results)->xdr_res),
 		(*results)->xdr_len,
 		XDR_ENCODE);
-	status = (*xdrfunc)(&xdrs, resp);
-	if (!status) {
-		(*results)->res_status = status;
-		syslog(LOG_ERR, "error encoding results %p", xdrfunc);
+	if (!(*xdrfunc)(&xdrs, resp)) {
+		(*results)->res_status = EINVAL;
+		syslog(LOG_ERR, "error encoding results");
 		return (FALSE);
 	}
 	(*results)->res_status = 0;
--- a/usr/src/cmd/fs.d/autofs/autod_nfs.c	Thu Apr 19 14:35:48 2007 -0700
+++ b/usr/src/cmd/fs.d/autofs/autod_nfs.c	Thu Apr 19 14:39:35 2007 -0700
@@ -279,14 +279,6 @@
 			trace_prt(1, "	Couldn't mount %s:%s, err=%d\n",
 				mfs->mfs_host, mfs->mfs_dir, err);
 		}
-		/*
-		 * Free Action list as it is not needed here if cached
-		 * because nfsmount would have done the mount.
-		 */
-		if (cached && (alp)) {
-			free(alp);
-			*alpp = NULL;
-		}
 	}
 	free_mfs(mfs);
 	return (err);
--- a/usr/src/cmd/fs.d/autofs/autod_xdr.c	Thu Apr 19 14:35:48 2007 -0700
+++ b/usr/src/cmd/fs.d/autofs/autod_xdr.c	Thu Apr 19 14:39:35 2007 -0700
@@ -38,28 +38,6 @@
 #include <string.h>
 #include <rpcsvc/autofs_prot.h>
 #include <rpc/xdr.h>
-#include <sys/pathconf.h>
-#include <rpc/auth.h>
-#include <rpc/rpcsec_gss.h>
-#include <nfs/mount.h>
-#include <sys/thread.h>
-#include <sys/utsname.h>
-#include <nfs/rnode.h>
-
-#define	FS_NFS2	2
-#define	FS_NFS3	3
-#define	FS_NFS4	4
-#define	NFS4_FHSIZE 128
-
-static bool_t
-xdr_nfs_args(XDR *xdrs, struct nfs_args *objp);
-
-static bool_t
-xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp);
-
-static bool_t
-xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp);
-
 
 bool_t
 xdr_autofs_stat(register XDR *xdrs, autofs_stat *objp)
@@ -127,539 +105,6 @@
 }
 
 bool_t
-xdr_knetconfig(xdrs, objp)
-	XDR *xdrs;
-struct knetconfig *objp;
-{
-
-	rpc_inline_t *buf;
-
-	int i;
-
-	if (xdrs->x_op == XDR_ENCODE) {
-		if (!xdr_u_int(xdrs, &objp->knc_semantics))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE))
-			return (FALSE);
-		if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev))
-			return (FALSE);
-		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
-				sizeof (uint_t), (xdrproc_t)xdr_u_int))
-				return (FALSE);
-		} else {
-#if defined(_LP64) || defined(_KERNEL)
-			{
-				uint_t *genp;
-
-				for (i = 0, genp = objp->knc_unused; i < 8;
-				    i++) {
-					IXDR_PUT_U_INT32(buf, *genp++);
-				}
-			}
-#else
-			{
-				uint_t *genp;
-
-				for (i = 0, genp = objp->knc_unused; i < 8;
-				    i++) {
-					IXDR_PUT_U_LONG(buf, *genp++);
-				}
-			}
-#endif
-		}
-		return (TRUE);
-
-	}
-	if (!xdr_u_int(xdrs, &objp->knc_semantics))
-		return (FALSE);
-	if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE))
-		return (FALSE);
-	if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE))
-		return (FALSE);
-
-	if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev))
-		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
-		sizeof (uint_t), (xdrproc_t)xdr_u_int))
-		return (FALSE);
-	return (TRUE);
-}
-
-
-bool_t
-xdr_pathcnf(XDR *xdrs, struct pathcnf *objp)
-{
-
-	rpc_inline_t *buf;
-
-	int i;
-
-	if (xdrs->x_op == XDR_ENCODE) {
-		buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_int(xdrs, &objp->pc_link_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_max_canon))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_max_input))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_name_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_path_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_pipe_buf))
-				return (FALSE);
-		} else {
-#if defined(_LP64) || defined(_KERNEL)
-			IXDR_PUT_INT32(buf, objp->pc_link_max);
-			IXDR_PUT_SHORT(buf, objp->pc_max_canon);
-			IXDR_PUT_SHORT(buf, objp->pc_max_input);
-			IXDR_PUT_SHORT(buf, objp->pc_name_max);
-			IXDR_PUT_SHORT(buf, objp->pc_path_max);
-			IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
-#else
-			IXDR_PUT_LONG(buf, objp->pc_link_max);
-			IXDR_PUT_SHORT(buf, objp->pc_max_canon);
-			IXDR_PUT_SHORT(buf, objp->pc_max_input);
-			IXDR_PUT_SHORT(buf, objp->pc_name_max);
-			IXDR_PUT_SHORT(buf, objp->pc_path_max);
-			IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
-#endif
-		}
-		if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
-			return (FALSE);
-		if (!xdr_char(xdrs, &objp->pc_xxx))
-			return (FALSE);
-		buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N,
-				sizeof (short), (xdrproc_t)xdr_short))
-				return (FALSE);
-		} else {
-#if defined(_LP64) || defined(_KERNEL)
-				short *genp;
-
-				for (i = 0, genp = objp->pc_mask; i < _PC_N;
-				    i++) {
-					IXDR_PUT_SHORT(buf, *genp++);
-				}
-#else
-				short *genp;
-
-				for (i = 0, genp = objp->pc_mask; i < _PC_N;
-				    i++) {
-					IXDR_PUT_SHORT(buf, *genp++);
-				}
-#endif
-		}
-		return (TRUE);
-	} else if (xdrs->x_op == XDR_DECODE) {
-		buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_int(xdrs, &objp->pc_link_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_max_canon))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_max_input))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_name_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_path_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_pipe_buf))
-				return (FALSE);
-		} else {
-#if defined(_LP64) || defined(_KERNEL)
-			objp->pc_link_max = IXDR_GET_INT32(buf);
-			objp->pc_max_canon = IXDR_GET_SHORT(buf);
-			objp->pc_max_input = IXDR_GET_SHORT(buf);
-			objp->pc_name_max = IXDR_GET_SHORT(buf);
-			objp->pc_path_max = IXDR_GET_SHORT(buf);
-			objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
-#else
-			objp->pc_link_max = IXDR_GET_LONG(buf);
-			objp->pc_max_canon = IXDR_GET_SHORT(buf);
-			objp->pc_max_input = IXDR_GET_SHORT(buf);
-			objp->pc_name_max = IXDR_GET_SHORT(buf);
-			objp->pc_path_max = IXDR_GET_SHORT(buf);
-			objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
-#endif
-		}
-		if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
-			return (FALSE);
-		if (!xdr_char(xdrs, &objp->pc_xxx))
-			return (FALSE);
-		buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N,
-				sizeof (short), (xdrproc_t)xdr_short))
-				return (FALSE);
-		} else {
-#if defined(_LP64) || defined(_KERNEL)
-				short *genp;
-
-				for (i = 0, genp = objp->pc_mask; i < _PC_N;
-				    i++) {
-					*genp++ = IXDR_GET_SHORT(buf);
-				}
-#else
-				short *genp;
-
-				for (i = 0, genp = objp->pc_mask;
-				    i < _PC_N; i++) {
-					*genp++ = IXDR_GET_SHORT(buf);
-				}
-#endif
-		}
-		return (TRUE);
-	}
-
-	if (!xdr_int(xdrs, &objp->pc_link_max))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_max_canon))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_max_input))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_name_max))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_path_max))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_pipe_buf))
-		return (FALSE);
-	if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
-		return (FALSE);
-	if (!xdr_char(xdrs, &objp->pc_xxx))
-		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N,
-		sizeof (short), (xdrproc_t)xdr_short))
-		return (FALSE);
-	return (TRUE);
-}
-
-bool_t
-xdr_des_clnt_data(XDR *xdrs, dh_k4_clntdata_t *objp)
-{
-
-	rpc_inline_t *buf;
-
-	if (!xdr_autofs_netbuf(xdrs, &objp->syncaddr))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
-		sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
-		return (FALSE);
-	if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->netnamelen))
-		return (FALSE);
-	return (TRUE);
-}
-
-bool_t
-xdr_gss_clnt_data(XDR *xdrs, struct gss_clnt_data *objp)
-{
-
-	rpc_inline_t *buf;
-
-
-	if (!xdr_u_int(xdrs, &objp->mechanism.length))
-		return (FALSE);
-	if (!xdr_enum(xdrs, (enum_t *)&objp->service))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, objp->mechanism.elements,
-		objp->mechanism.length))
-		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->uname, MAX_NAME_LEN,
-		sizeof (char), (xdrproc_t)xdr_char))
-		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->inst, MAX_NAME_LEN,
-		sizeof (char), (xdrproc_t)xdr_char))
-		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->realm, MAX_NAME_LEN,
-		sizeof (char), (xdrproc_t)xdr_char))
-		return (FALSE);
-	if (!xdr_u_int(xdrs, &objp->qop))
-		return (FALSE);
-	return (TRUE);
-}
-
-bool_t
-xdr_sec_data(XDR *xdrs, struct sec_data *objp)
-{
-
-	rpc_inline_t *buf;
-
-	if (!xdr_u_int(xdrs, &objp->secmod))
-		return (FALSE);
-	if (!xdr_u_int(xdrs, &objp->rpcflavor))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->flags))
-		return (FALSE);
-	if (!xdr_uid_t(xdrs, &objp->uid))
-		return (FALSE);
-
-	switch (objp->rpcflavor) {
-	case AUTH_NONE:
-	case AUTH_UNIX:
-	case AUTH_LOOPBACK:
-		break;
-	case AUTH_DES:
-		if (!xdr_pointer(xdrs, (char **)&objp->data,
-			sizeof (dh_k4_clntdata_t),
-			(xdrproc_t)xdr_des_clnt_data))
-			return (FALSE);
-		break;
-	case RPCSEC_GSS:
-		if (!xdr_pointer(xdrs, (char **)&objp->data,
-			sizeof (gss_clntdata_t),
-			(xdrproc_t)xdr_gss_clnt_data))
-			return (FALSE);
-		break;
-	default:
-		return (FALSE);
-	}
-
-	return (TRUE);
-}
-
-bool_t
-xdr_nfs2_fh(XDR *xdrs, void *objp)
-{
-	if (!xdr_opaque(xdrs, (char *)objp, NFS_FHSIZE))
-		return (B_FALSE);
-	return (B_TRUE);
-}
-
-bool_t
-xdr_nfs3_fhandle(XDR *xdrs, nfs_fhandle *objp)
-{
-	if (!xdr_int(xdrs, &objp->fh_len))
-		return (B_FALSE);
-	if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, objp->fh_len))
-		return (B_FALSE);
-	return (B_TRUE);
-}
-
-bool_t
-xdr_nfs(XDR *xdrs, struct nfs_args *objp, int nfsv)
-{
-
-	rpc_inline_t *buf;
-
-	if (objp == NULL)
-		return (TRUE);
-
-	if (xdrs->x_op == XDR_ENCODE) {
-		if (!xdr_pointer(xdrs, (char **)&objp->addr,
-			sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-			return (FALSE);
-		if (!xdr_pointer(xdrs, (char **)&objp->syncaddr,
-			sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-			return (FALSE);
-		if (!xdr_pointer(xdrs, (char **)&objp->knconf,
-			sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
-			return (FALSE);
-		if (nfsv == FS_NFS4) {
-			if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE))
-				return (B_FALSE);
-		} else if (nfsv == FS_NFS3) {
-			if (!xdr_pointer(xdrs, (char **)&objp->fh,
-				sizeof (nfs_fhandle),
-				(xdrproc_t)xdr_nfs3_fhandle))
-				return (B_FALSE);
-		} else {
-			if (!xdr_pointer(xdrs, (char **)&objp->fh,
-				NFS_FHSIZE,
-				(xdrproc_t)xdr_nfs2_fh))
-				return (B_FALSE);
-		}
-		buf = XDR_INLINE(xdrs, 9 * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_int(xdrs, &objp->flags))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->wsize))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->rsize))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->timeo))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->retrans))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acregmin))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acregmax))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acdirmin))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acdirmax))
-				return (FALSE);
-		} else {
-#if defined(_LP64) || defined(_KERNEL)
-			IXDR_PUT_INT32(buf, objp->flags);
-			IXDR_PUT_INT32(buf, objp->wsize);
-			IXDR_PUT_INT32(buf, objp->rsize);
-			IXDR_PUT_INT32(buf, objp->timeo);
-			IXDR_PUT_INT32(buf, objp->retrans);
-			IXDR_PUT_INT32(buf, objp->acregmin);
-			IXDR_PUT_INT32(buf, objp->acregmax);
-			IXDR_PUT_INT32(buf, objp->acdirmin);
-			IXDR_PUT_INT32(buf, objp->acdirmax);
-#else
-			IXDR_PUT_LONG(buf, objp->flags);
-			IXDR_PUT_LONG(buf, objp->wsize);
-			IXDR_PUT_LONG(buf, objp->rsize);
-			IXDR_PUT_LONG(buf, objp->timeo);
-			IXDR_PUT_LONG(buf, objp->retrans);
-			IXDR_PUT_LONG(buf, objp->acregmin);
-			IXDR_PUT_LONG(buf, objp->acregmax);
-			IXDR_PUT_LONG(buf, objp->acdirmin);
-			IXDR_PUT_LONG(buf, objp->acdirmax);
-#endif
-		}
-		if (!xdr_pointer(xdrs, (char **)&objp->pathconf,
-			sizeof (struct pathcnf),
-			(xdrproc_t)xdr_pathcnf))
-			return (FALSE);
-		if (!xdr_int(xdrs, &objp->nfs_args_ext))
-			return (FALSE);
-		if (!xdr_pointer(xdrs,
-			(char **)&objp->nfs_ext_u.nfs_extA.secdata,
-			sizeof (struct sec_data),
-			(xdrproc_t)xdr_sec_data))
-			return (FALSE);
-		if (objp->nfs_args_ext == NFS_ARGS_EXTB) {
-			if (nfsv == FS_NFS4) {
-				if (!xdr_pointer(xdrs,
-					(char **)&objp->nfs_ext_u.nfs_extB.next,
-					sizeof (struct nfs_args),
-					(xdrproc_t)xdr_nfs4_args))
-					return (FALSE);
-			} else if (nfsv == FS_NFS3) {
-				if (!xdr_pointer(xdrs,
-					(char **)&objp->nfs_ext_u.nfs_extB.next,
-					sizeof (struct nfs_args),
-					(xdrproc_t)xdr_nfs3_args))
-					return (FALSE);
-			} else {
-				if (!xdr_pointer(xdrs,
-					(char **)&objp->nfs_ext_u.nfs_extB.next,
-					sizeof (struct nfs_args),
-					(xdrproc_t)xdr_nfs_args))
-					return (FALSE);
-			}
-		}
-		return (TRUE);
-	}
-
-	/* Not a DECODE operation */
-	if (!xdr_pointer(xdrs, (char **)&objp->addr,
-		sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->syncaddr,
-		sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
-		sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->hostname,
-		sizeof (char), (xdrproc_t)xdr_char))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->netname,
-		sizeof (char), (xdrproc_t)xdr_char))
-		return (FALSE);
-	if (nfsv == FS_NFS4) {
-		if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE))
-			return (B_FALSE);
-	} else if (nfsv == FS_NFS3) {
-		if (!xdr_pointer(xdrs, (char **)&objp->fh,
-			sizeof (nfs_fhandle),
-			(xdrproc_t)xdr_nfs3_fhandle))
-			return (B_FALSE);
-	} else {
-		if (!xdr_pointer(xdrs, (char **)&objp->fh,
-			NFS_FHSIZE,
-			(xdrproc_t)xdr_nfs2_fh))
-			return (B_FALSE);
-	}
-
-	if (!xdr_int(xdrs, &objp->flags))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->wsize))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->rsize))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->timeo))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->retrans))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acregmin))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acregmax))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acdirmin))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acdirmax))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->pathconf,
-		sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->nfs_args_ext))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->nfs_ext_u.nfs_extA.secdata,
-		sizeof (struct sec_data), (xdrproc_t)xdr_sec_data))
-		return (FALSE);
-	if (objp->nfs_args_ext == NFS_ARGS_EXTB) {
-		if (nfsv == FS_NFS4) {
-			if (!xdr_pointer(xdrs,
-				(char **)&objp->nfs_ext_u.nfs_extB.next,
-				sizeof (struct nfs_args),
-				(xdrproc_t)xdr_nfs4_args))
-				return (FALSE);
-		} else if (nfsv == FS_NFS3) {
-			if (!xdr_pointer(xdrs,
-				(char **)&objp->nfs_ext_u.nfs_extB.next,
-				sizeof (struct nfs_args),
-				(xdrproc_t)xdr_nfs3_args))
-				return (FALSE);
-		} else {
-			if (!xdr_pointer(xdrs,
-				(char **)&objp->nfs_ext_u.nfs_extB.next,
-				sizeof (struct nfs_args),
-				(xdrproc_t)xdr_nfs_args))
-				return (FALSE);
-		}
-
-	}
-	return (TRUE);
-}
-
-static bool_t
-xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp)
-{
-	return (xdr_nfs(xdrs, objp, FS_NFS4));
-}
-
-static bool_t
-xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp)
-{
-	return (xdr_nfs(xdrs, objp, FS_NFS3));
-}
-
-static bool_t
-xdr_nfs_args(XDR *xdrs, struct nfs_args *objp)
-{
-	return (xdr_nfs(xdrs, objp, FS_NFS2));
-}
-
-
-bool_t
 xdr_mounta(register XDR *xdrs, struct mounta *objp)
 {
 	if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN))
@@ -670,30 +115,11 @@
 		return (FALSE);
 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
 		return (FALSE);
-	if (strncmp(objp->fstype, "autofs", 6) == 0) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (autofs_args),
-			(xdrproc_t)xdr_autofs_args))
-			return (FALSE);
-	} else if (strncmp(objp->fstype, "nfs4", 4) == 0) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (struct nfs_args),
-			(xdrproc_t)xdr_nfs4_args))
-			return (FALSE);
-	} else if (strncmp(objp->fstype, "nfs3", 4) == 0) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (struct nfs_args),
-			(xdrproc_t)xdr_nfs3_args))
-			return (FALSE);
-	} else {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (struct nfs_args),
-			(xdrproc_t)xdr_nfs_args))
-			return (FALSE);
-	}
+	if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args),
+	    (xdrproc_t)xdr_autofs_args))
+		return (FALSE);
 	if (!xdr_int(xdrs, &objp->datalen))
 		return (FALSE);
-
 	if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
 		return (FALSE);
 	if (!xdr_int(xdrs, &objp->optlen))
--- a/usr/src/uts/common/fs/autofs/auto_subr.c	Thu Apr 19 14:35:48 2007 -0700
+++ b/usr/src/uts/common/fs/autofs/auto_subr.c	Thu Apr 19 14:39:35 2007 -0700
@@ -775,6 +775,56 @@
 	return (0);
 }
 
+static void
+auto_free_autofs_args(struct mounta *m)
+{
+	autofs_args	*aargs = (autofs_args *)m->dataptr;
+
+	if (aargs->addr.buf)
+		kmem_free(aargs->addr.buf, aargs->addr.len);
+	if (aargs->path)
+		kmem_free(aargs->path, strlen(aargs->path) + 1);
+	if (aargs->opts)
+		kmem_free(aargs->opts, strlen(aargs->opts) + 1);
+	if (aargs->map)
+		kmem_free(aargs->map, strlen(aargs->map) + 1);
+	if (aargs->subdir)
+		kmem_free(aargs->subdir, strlen(aargs->subdir) + 1);
+	if (aargs->key)
+		kmem_free(aargs->key, strlen(aargs->key) + 1);
+	kmem_free(aargs, sizeof (*aargs));
+}
+
+static void
+auto_free_action_list(action_list *alp)
+{
+	struct	mounta	*m;
+	action_list	*lastalp;
+	char		*fstype;
+
+	m = &alp->action.action_list_entry_u.mounta;
+	while (alp != NULL) {
+		fstype = alp->action.action_list_entry_u.mounta.fstype;
+		m = &alp->action.action_list_entry_u.mounta;
+		if (m->dataptr) {
+			if (strcmp(fstype, "autofs") == 0) {
+				auto_free_autofs_args(m);
+			}
+		}
+		if (m->spec)
+			kmem_free(m->spec, strlen(m->spec) + 1);
+		if (m->dir)
+			kmem_free(m->dir, strlen(m->dir) + 1);
+		if (m->fstype)
+			kmem_free(m->fstype, strlen(m->fstype) + 1);
+		if (m->optptr)
+			kmem_free(m->optptr, m->optlen);
+		lastalp = alp;
+		alp = alp->next;
+		kmem_free(lastalp, sizeof (*lastalp));
+	}
+}
+
 static boolean_t
 auto_invalid_autofs(fninfo_t *dfnip, fnnode_t *dfnp, action_list *p)
 {
@@ -784,6 +834,7 @@
 	char buff[AUTOFS_MAXPATHLEN];
 	size_t len;
 	struct autofs_globals *fngp;
+
 	fngp = dfnp->fn_globals;
 	dvp = fntovn(dfnp);
 
@@ -795,10 +846,10 @@
 	 * We also only want to perform autofs mounts, so make sure
 	 * no-one is trying to trick us into doing anything else.
 	 */
-	if (m->dir[0] != '.' ||
+	if (m->spec == NULL || m->dir == NULL || m->dir[0] != '.' ||
 	    (m->dir[1] != '/' && m->dir[1] != '\0') ||
-	    strcmp(m->fstype, "autofs") != 0 ||
-	    m->datalen != sizeof (struct autofs_args) ||
+	    m->fstype == NULL || strcmp(m->fstype, "autofs") != 0 ||
+	    m->dataptr == NULL || m->datalen != sizeof (struct autofs_args) ||
 	    m->optptr == NULL)
 		return (B_TRUE);
 	/*
@@ -853,47 +904,19 @@
 
 /*
  * auto_invalid_action will validate the action_list received.  If all is good
- * this function returns FALSE, if there is a problem it returned TRUE.
- * Based on the mount type, autofs or nfs, it dispatchs to auto_invalid_autofs
- * or validates the fstype is nfs.  For nfs mounts, the spec, dir, datalen
- * etc should all either be good here, or have already been checked.
+ * this function returns FALSE, if there is a problem it returns TRUE.
  */
-
 static boolean_t
 auto_invalid_action(fninfo_t *dfnip, fnnode_t *dfnp, action_list *alistpp)
 {
-	struct mounta	*m;
 
 	/*
 	 * Before we go any further, this better be a mount request.
 	 */
 	if (alistpp->action.action != AUTOFS_MOUNT_RQ)
 		return (B_TRUE);
-
-	m = &alistpp->action.action_list_entry_u.mounta;
-	/*
-	 * Make sure we aren't geting passed NULL values or a "dir" that
-	 * isn't "." and doesn't begin with "./".
-	 *
-	 * We also only want to perform autofs mounts, so make sure
-	 * no-one is trying to trick us into doing anything else.
-	 */
-	if (m->spec == NULL || m->dir == NULL ||
-	    m->fstype == NULL || m->dataptr == NULL)
-		return (B_TRUE);
+	return (auto_invalid_autofs(dfnip, dfnp, alistpp));
 
-	/*
-	 * Dispatch to the appropriate validation routine based
-	 * on the filesystem type.
-	 */
-	if (strncmp(alistpp->action.action_list_entry_u.mounta.fstype,
-		"autofs", 6) == 0) {
-		return (auto_invalid_autofs(dfnip, dfnp, alistpp));
-	} else if (strncmp(alistpp->action.action_list_entry_u.mounta.fstype,
-		"nfs", 3) == 0) {
-		return (B_FALSE);
-	}
-	return (B_TRUE);
 }
 
 static int
@@ -946,7 +969,6 @@
 			 * This conversation is over.
 			 */
 			xdr_free(xdr_action_list, (char *)alp);
-			kmem_free(alp, sizeof (*alp));
 			return (EINVAL);
 		}
 	}
@@ -954,21 +976,6 @@
 	zcred = zone_get_kcred(getzoneid());
 	ASSERT(zcred != NULL);
 
-	/*
-	 * Clear MF_MOUNTPOINT, if the NFS mount is required and
-	 * completes successfully, we will then set MF_MOUNTPOINT.
-	 */
-	mutex_enter(&dfnp->fn_lock);
-	if (dfnp->fn_flags & MF_MOUNTPOINT) {
-		AUTOFS_DPRINT((10, "autofs: clearing mountpoint "
-			"flag on %s.", dfnp->fn_name));
-		ASSERT(dfnp->fn_dirents == NULL);
-		ASSERT(dfnp->fn_trigger == NULL);
-	}
-	dfnp->fn_flags &= ~MF_MOUNTPOINT;
-	mutex_exit(&dfnp->fn_lock);
-
-
 	if (vn_mountedvfs(dvp) != NULL) {
 		/*
 		 * The daemon successfully mounted a filesystem
@@ -1003,300 +1010,261 @@
 
 		m = &p->action.action_list_entry_u.mounta;
 		argsp = (struct autofs_args *)m->dataptr;
-		if (strncmp(m->fstype, "nfs", 3) == 0) {
-			if (vn_mountedvfs(dvp) != NULL) {
-				/*
-				 * Its possible that the filesystem is
-				 * already mounted if nfs because we are
-				 * being called from unmount_tree when
-				 * if failed to unmount a node from a
-				 * trigger point, and is remounting again and
-				 * this particular filesystem was not
-				 * unmounted.
-				 */
-				mutex_enter(&dfnp->fn_lock);
-				dfnp->fn_flags |= MF_MOUNTPOINT;
-				mutex_exit(&dfnp->fn_lock);
-			} else {
-				m->flags |= MS_SYSSPACE;
-				VN_HOLD(dvp);
-				error = domount(NULL, m, dvp, zcred, &vfsp);
-				if (!error) {
-					VFS_RELE(vfsp);
-					mutex_enter(&dfnp->fn_lock);
-					dfnp->fn_flags |= MF_MOUNTPOINT;
-					ASSERT(dfnp->fn_dirents == NULL);
-					mutex_exit(&dfnp->fn_lock);
-					success++;
-				}
-				VN_RELE(dvp);
-			}
-		} else {
-			ASSERT(strcmp(m->fstype, "autofs") == 0);
+		ASSERT(strcmp(m->fstype, "autofs") == 0);
+		/*
+		 * use the parent directory's timeout since it's the
+		 * one specified/inherited by automount.
+		 */
+		argsp->mount_to = dfnip->fi_mount_to;
+		/*
+		 * The mountpoint is relative, and it is guaranteed to
+		 * begin with "."
+		 *
+		 */
+		ASSERT(m->dir[0] == '.');
+		if (m->dir[0] == '.' && m->dir[1] == '\0') {
 			/*
-			 * use the parent directory's timeout since it's the
-			 * one specified/inherited by automount.
-			 */
-			argsp->mount_to = dfnip->fi_mount_to;
-			/*
-			 * The mountpoint is relative, and it is guaranteed to
-			 * begin with "."
-			 *
+			 * mounting on the trigger node
 			 */
-			ASSERT(m->dir[0] == '.');
-			if (m->dir[0] == '.' && m->dir[1] == '\0') {
-				/*
-				 * mounting on the trigger node
-				 */
-				mvp = dvp;
-				VN_HOLD(mvp);
-				goto mount;
-			}
-			/*
-			 * ignore "./" in front of mountpoint
-			 */
-			ASSERT(m->dir[1] == '/');
-			mntpnt = m->dir + 2;
+			mvp = dvp;
+			VN_HOLD(mvp);
+			goto mount;
+		}
+		/*
+		 * ignore "./" in front of mountpoint
+		 */
+		ASSERT(m->dir[1] == '/');
+		mntpnt = m->dir + 2;
 
-			AUTOFS_DPRINT((10, "\tdfnip->fi_path=%s\n",
-				dfnip->fi_path));
-			AUTOFS_DPRINT((10, "\tdfnip->fi_flags=%x\n",
-				dfnip->fi_flags));
-			AUTOFS_DPRINT((10, "\tmntpnt=%s\n", mntpnt));
+		AUTOFS_DPRINT((10, "\tdfnip->fi_path=%s\n", dfnip->fi_path));
+		AUTOFS_DPRINT((10, "\tdfnip->fi_flags=%x\n", dfnip->fi_flags));
+		AUTOFS_DPRINT((10, "\tmntpnt=%s\n", mntpnt));
 
-			if (dfnip->fi_flags & MF_DIRECT) {
-				AUTOFS_DPRINT((10, "\tDIRECT\n"));
-				(void) sprintf(buff, "%s/%s", dfnip->fi_path,
-					mntpnt);
-			} else {
-				AUTOFS_DPRINT((10, "\tINDIRECT\n"));
-				(void) sprintf(buff, "%s/%s/%s",
-					dfnip->fi_path,
-					dfnp->fn_name, mntpnt);
-			}
+		if (dfnip->fi_flags & MF_DIRECT) {
+			AUTOFS_DPRINT((10, "\tDIRECT\n"));
+			(void) sprintf(buff, "%s/%s", dfnip->fi_path,
+				mntpnt);
+		} else {
+			AUTOFS_DPRINT((10, "\tINDIRECT\n"));
+			(void) sprintf(buff, "%s/%s/%s",
+				dfnip->fi_path,
+				dfnp->fn_name, mntpnt);
+		}
 
-			if (vn_mountedvfs(dvp) == NULL) {
+		if (vn_mountedvfs(dvp) == NULL) {
+			/*
+			 * Daemon didn't mount anything on the root
+			 * We have to create the mountpoint if it
+			 * doesn't exist already
+			 *
+			 * We use the caller's credentials in case a
+			 * UID-match is required
+			 * (MF_THISUID_MATCH_RQD).
+			 */
+			rw_enter(&dfnp->fn_rwlock, RW_WRITER);
+			error = auto_search(dfnp, mntpnt, &mfnp, cred);
+			if (error == 0) {
 				/*
-				 * Daemon didn't mount anything on the root
-				 * We have to create the mountpoint if it
-				 * doesn't exist already
-				 *
-				 * We use the caller's credentials in case a
-				 * UID-match is required
-				 * (MF_THISUID_MATCH_RQD).
+				 * AUTOFS mountpoint exists
 				 */
-				rw_enter(&dfnp->fn_rwlock, RW_WRITER);
-				error = auto_search(dfnp, mntpnt, &mfnp, cred);
-				if (error == 0) {
-					/*
-					 * AUTOFS mountpoint exists
-					 */
-					if (vn_mountedvfs(fntovn(mfnp))
-						!= NULL) {
-						cmn_err(CE_PANIC,
-							"auto_perform_actions:"
-							" mfnp=%p covered",
-							(void *)mfnp);
-					}
-				} else {
-					/*
-					 * Create AUTOFS mountpoint
-					 */
-					ASSERT((dfnp->fn_flags &
-						MF_MOUNTPOINT) == 0);
-					error = auto_enter(dfnp, mntpnt,
-						&mfnp, cred);
-					ASSERT(mfnp->fn_linkcnt == 1);
-					mfnp->fn_linkcnt++;
-				}
-				if (!error)
-					update_times = 1;
-				rw_exit(&dfnp->fn_rwlock);
-				ASSERT(error != EEXIST);
-				if (!error) {
-					/*
-					 * mfnp is already held.
-					 */
-					mvp = fntovn(mfnp);
-				} else {
-					auto_log(fngp->fng_verbose,
-						fngp->fng_zoneid,
-						CE_WARN, "autofs: mount of %s "
-						"failed - can't create"
-						" mountpoint.", buff);
-					continue;
+				if (vn_mountedvfs(fntovn(mfnp)) != NULL) {
+					cmn_err(CE_PANIC,
+						"auto_perform_actions:"
+						" mfnp=%p covered",
+						(void *)mfnp);
 				}
 			} else {
 				/*
-				 * Find mountpoint in VFS mounted here. If not
-				 * found, fail the submount, though the overall
-				 * mount has succeeded since the root is
-				 * mounted.
+				 * Create AUTOFS mountpoint
 				 */
-				if (error = auto_getmntpnt(dvp, mntpnt, &mvp,
-					kcred)) {
-					auto_log(fngp->fng_verbose,
-						fngp->fng_zoneid,
-						CE_WARN, "autofs: mount of %s "
-						"failed - mountpoint doesn't"
-						" exist.", buff);
+				ASSERT((dfnp->fn_flags & MF_MOUNTPOINT) == 0);
+				error = auto_enter(dfnp, mntpnt, &mfnp, cred);
+				ASSERT(mfnp->fn_linkcnt == 1);
+				mfnp->fn_linkcnt++;
+			}
+			if (!error)
+				update_times = 1;
+			rw_exit(&dfnp->fn_rwlock);
+			ASSERT(error != EEXIST);
+			if (!error) {
+				/*
+				 * mfnp is already held.
+				 */
+				mvp = fntovn(mfnp);
+			} else {
+				auto_log(fngp->fng_verbose, fngp->fng_zoneid,
+					CE_WARN, "autofs: mount of %s "
+					"failed - can't create"
+					" mountpoint.", buff);
 					continue;
-				}
-				if (mvp->v_type == VLNK) {
-					auto_log(fngp->fng_verbose,
-						fngp->fng_zoneid,
-						CE_WARN, "autofs: %s symbolic "
-						"link: not a valid mountpoint "
-						"- mount failed", buff);
-					VN_RELE(mvp);
-					error = ENOENT;
-					continue;
-				}
 			}
+		} else {
+			/*
+			 * Find mountpoint in VFS mounted here. If not
+			 * found, fail the submount, though the overall
+			 * mount has succeeded since the root is
+			 * mounted.
+			 */
+			if (error = auto_getmntpnt(dvp, mntpnt, &mvp,
+				kcred)) {
+				auto_log(fngp->fng_verbose,
+					fngp->fng_zoneid,
+					CE_WARN, "autofs: mount of %s "
+					"failed - mountpoint doesn't"
+					" exist.", buff);
+				continue;
+			}
+			if (mvp->v_type == VLNK) {
+				auto_log(fngp->fng_verbose,
+					fngp->fng_zoneid,
+					CE_WARN, "autofs: %s symbolic "
+					"link: not a valid mountpoint "
+					"- mount failed", buff);
+				VN_RELE(mvp);
+				error = ENOENT;
+				continue;
+			}
+		}
 mount:
-			m->flags |= MS_SYSSPACE | MS_OPTIONSTR;
+		m->flags |= MS_SYSSPACE | MS_OPTIONSTR;
+
+		/*
+		 * Copy mounta struct here so we can substitute a
+		 * buffer that is large enough to hold the returned
+		 * option string, if that string is longer than the
+		 * input option string.
+		 * This can happen if there are default options enabled
+		 * that were not in the input option string.
+		 */
+		bcopy(m, &margs, sizeof (*m));
+		margs.optptr = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP);
+		margs.optlen = MAX_MNTOPT_STR;
+		(void) strcpy(margs.optptr, m->optptr);
+		margs.dir = argsp->path;
+
+		/*
+		 * We use the zone's kcred because we don't want the
+		 * zone to be able to thus do something it wouldn't
+		 * normally be able to.
+		 */
+		error = domount(NULL, &margs, mvp, zcred, &vfsp);
+		kmem_free(margs.optptr, MAX_MNTOPT_STR);
+		if (error != 0) {
+			auto_log(fngp->fng_verbose, fngp->fng_zoneid,
+				CE_WARN, "autofs: domount of %s failed "
+				"error=%d", buff, error);
+			VN_RELE(mvp);
+			continue;
+		}
+		VFS_RELE(vfsp);
 
-			/*
-			 * Copy mounta struct here so we can substitute a
-			 * buffer that is large enough to hold the returned
-			 * option string, if that string is longer than the
-			 * input option string.
-			 * This can happen if there are default options enabled
-			 * that were not in the input option string.
-			 */
-			bcopy(m, &margs, sizeof (*m));
-			margs.optptr = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP);
-			margs.optlen = MAX_MNTOPT_STR;
-			(void) strcpy(margs.optptr, m->optptr);
-			margs.dir = argsp->path;
+		/*
+		 * If mountpoint is an AUTOFS node, then I'm going to
+		 * flag it that the Filesystem mounted on top was
+		 * mounted in the kernel so that the unmount can be
+		 * done inside the kernel as well.
+		 * I don't care to flag non-AUTOFS mountpoints when an
+		 * AUTOFS in-kernel mount was done on top, because the
+		 * unmount routine already knows that such case was
+		 * done in the kernel.
+		 */
+		if (vfs_matchops(dvp->v_vfsp,
+			vfs_getops(mvp->v_vfsp))) {
+			mfnp = vntofn(mvp);
+			mutex_enter(&mfnp->fn_lock);
+			mfnp->fn_flags |= MF_IK_MOUNT;
+			mutex_exit(&mfnp->fn_lock);
+		}
 
-			/*
-			 * We use the zone's kcred because we don't want the
-			 * zone to be able to thus do something it wouldn't
-			 * normally be able to.
-			 */
-			error = domount(NULL, &margs, mvp, zcred, &vfsp);
-			kmem_free(margs.optptr, MAX_MNTOPT_STR);
-			if (error != 0) {
-				auto_log(fngp->fng_verbose, fngp->fng_zoneid,
-					CE_WARN,
-					"autofs: domount of %s failed "
-					"error=%d", buff, error);
+		(void) vn_vfswlock_wait(mvp);
+		mvfsp = vn_mountedvfs(mvp);
+		if (mvfsp != NULL) {
+			vfs_lock_wait(mvfsp);
+			vn_vfsunlock(mvp);
+			error = VFS_ROOT(mvfsp, &newvp);
+			vfs_unlock(mvfsp);
+			if (error) {
+				/*
+				 * We've dropped the locks, so let's
+				 * get the mounted vfs again in case
+				 * it changed.
+				 */
+				(void) vn_vfswlock_wait(mvp);
+				mvfsp = vn_mountedvfs(mvp);
+				if (mvfsp != NULL) {
+					error = dounmount(mvfsp, 0, CRED());
+					if (error) {
+						cmn_err(CE_WARN,
+							"autofs: could"
+							" not unmount"
+							" vfs=%p",
+							(void *)mvfsp);
+					}
+				} else
+					vn_vfsunlock(mvp);
 				VN_RELE(mvp);
 				continue;
 			}
-			VFS_RELE(vfsp);
-
-			/*
-			 * If mountpoint is an AUTOFS node, then I'm going to
-			 * flag it that the Filesystem mounted on top was
-			 * mounted in the kernel so that the unmount can be
-			 * done inside the kernel as well.
-			 * I don't care to flag non-AUTOFS mountpoints when an
-			 * AUTOFS in-kernel mount was done on top, because the
-			 * unmount routine already knows that such case was
-			 * done in the kernel.
-			 */
-			if (vfs_matchops(dvp->v_vfsp,
-				vfs_getops(mvp->v_vfsp))) {
-				mfnp = vntofn(mvp);
-				mutex_enter(&mfnp->fn_lock);
-				mfnp->fn_flags |= MF_IK_MOUNT;
-				mutex_exit(&mfnp->fn_lock);
-			}
+		} else {
+			vn_vfsunlock(mvp);
+			VN_RELE(mvp);
+			continue;
+		}
 
-			(void) vn_vfswlock_wait(mvp);
-			mvfsp = vn_mountedvfs(mvp);
-			if (mvfsp != NULL) {
-				vfs_lock_wait(mvfsp);
-				vn_vfsunlock(mvp);
-				error = VFS_ROOT(mvfsp, &newvp);
-				vfs_unlock(mvfsp);
-				if (error) {
-					/*
-					 * We've dropped the locks, so let's
-					 * get the mounted vfs again in case
-					 * it changed.
-					 */
-					(void) vn_vfswlock_wait(mvp);
-					mvfsp = vn_mountedvfs(mvp);
-					if (mvfsp != NULL) {
-						error = dounmount(mvfsp, 0,
-							CRED());
-						if (error) {
-							cmn_err(CE_WARN,
-								"autofs: could"
-								" not unmount"
-								" vfs=%p",
-								(void *)mvfsp);
-						}
-					} else
-						vn_vfsunlock(mvp);
-					VN_RELE(mvp);
-					continue;
-				}
-			} else {
-				vn_vfsunlock(mvp);
-				VN_RELE(mvp);
-				continue;
-			}
+		auto_mount = vfs_matchops(dvp->v_vfsp,
+			vfs_getops(newvp->v_vfsp));
+		newfnp = vntofn(newvp);
+		newfnp->fn_parent = dfnp;
 
-			auto_mount = vfs_matchops(dvp->v_vfsp,
-				vfs_getops(newvp->v_vfsp));
-			newfnp = vntofn(newvp);
-			newfnp->fn_parent = dfnp;
-
+		/*
+		 * At this time we want to save the AUTOFS filesystem
+		 * as a trigger node. (We only do this if the mount
+		 * occurred on a node different from the root.
+		 * We look at the trigger nodes during
+		 * the automatic unmounting to make sure we remove them
+		 * as a unit and remount them as a unit if the
+		 * filesystem mounted at the root could not be
+		 * unmounted.
+		 */
+		if (auto_mount && (error == 0) && (mvp != dvp)) {
+			save_triggers++;
 			/*
-			 * At this time we want to save the AUTOFS filesystem
-			 * as a trigger node. (We only do this if the mount
-			 * occurred on a node different from the root.
-			 * We look at the trigger nodes during
-			 * the automatic unmounting to make sure we remove them
-			 * as a unit and remount them as a unit if the
-			 * filesystem mounted at the root could not be
-			 * unmounted.
+			 * Add AUTOFS mount to hierarchy
 			 */
-			if (auto_mount && (error == 0) && (mvp != dvp)) {
-				save_triggers++;
-				/*
-				 * Add AUTOFS mount to hierarchy
-				 */
-				newfnp->fn_flags |= MF_TRIGGER;
-				rw_enter(&newfnp->fn_rwlock, RW_WRITER);
-				newfnp->fn_next = dfnp->fn_trigger;
-				rw_exit(&newfnp->fn_rwlock);
-				rw_enter(&dfnp->fn_rwlock, RW_WRITER);
-				dfnp->fn_trigger = newfnp;
-				rw_exit(&dfnp->fn_rwlock);
-				/*
-				 * Don't VN_RELE(newvp) here since dfnp now
-				 * holds reference to it as its trigger node.
-				 */
-				AUTOFS_DPRINT((10,
-					"\tadding trigger %s to %s\n",
+			newfnp->fn_flags |= MF_TRIGGER;
+			rw_enter(&newfnp->fn_rwlock, RW_WRITER);
+			newfnp->fn_next = dfnp->fn_trigger;
+			rw_exit(&newfnp->fn_rwlock);
+			rw_enter(&dfnp->fn_rwlock, RW_WRITER);
+			dfnp->fn_trigger = newfnp;
+			rw_exit(&dfnp->fn_rwlock);
+			/*
+			 * Don't VN_RELE(newvp) here since dfnp now
+			 * holds reference to it as its trigger node.
+			 */
+			AUTOFS_DPRINT((10, "\tadding trigger %s to %s\n",
 				newfnp->fn_name, dfnp->fn_name));
-				AUTOFS_DPRINT((10, "\tfirst trigger is %s\n",
-					dfnp->fn_trigger->fn_name));
-				if (newfnp->fn_next != NULL)
-					AUTOFS_DPRINT((10,
-						"\tnext trigger is %s\n",
-						newfnp->fn_next->fn_name));
-				else
-					AUTOFS_DPRINT((10,
-						"\tno next trigger\n"));
-			} else
-				VN_RELE(newvp);
+			AUTOFS_DPRINT((10, "\tfirst trigger is %s\n",
+				dfnp->fn_trigger->fn_name));
+			if (newfnp->fn_next != NULL)
+				AUTOFS_DPRINT((10,
+					"\tnext trigger is %s\n",
+					newfnp->fn_next->fn_name));
+			else
+				AUTOFS_DPRINT((10,
+					"\tno next trigger\n"));
+		} else
+			VN_RELE(newvp);
 
-			if (!error)
-				success++;
+		if (!error)
+			success++;
 
-			if (update_times) {
-				gethrestime(&now);
-				dfnp->fn_atime = dfnp->fn_mtime = now;
-			}
+		if (update_times) {
+			gethrestime(&now);
+			dfnp->fn_atime = dfnp->fn_mtime = now;
+		}
 
-			VN_RELE(mvp);
-		}
+		VN_RELE(mvp);
 	}
 
 	if (save_triggers) {
@@ -1333,7 +1301,6 @@
 			 * free the action list now,
 			 */
 			xdr_free(xdr_action_list, (char *)alp);
-			kmem_free(alp, sizeof (*alp));
 		}
 	}
 	AUTOFS_DPRINT((5, "auto_perform_actions: error=%d\n", error));
@@ -2471,7 +2438,6 @@
 		 */
 		if (alp != NULL) {
 			xdr_free(xdr_action_list, (char *)alp);
-			kmem_free(alp, sizeof (*alp));
 			alp = NULL;
 		}
 	}
--- a/usr/src/uts/common/fs/autofs/auto_xdr.c	Thu Apr 19 14:35:48 2007 -0700
+++ b/usr/src/uts/common/fs/autofs/auto_xdr.c	Thu Apr 19 14:39:35 2007 -0700
@@ -45,7 +45,6 @@
 #include <sys/cmn_err.h>
 #include <sys/debug.h>
 #include <sys/systm.h>
-#include <sys/utsname.h>
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 #include <rpc/auth.h>
@@ -55,33 +54,11 @@
 #include <sys/sysmacros.h>
 #include <fs/fs_subr.h>
 #include <sys/fs/autofs.h>
-#include <sys/pathconf.h>
-#include <rpc/auth.h>
-#include <rpc/rpcsec_gss.h>
-#include <nfs/mount.h>
-#include <sys/thread.h>
-#include <nfs/rnode.h>
-
-#define	FS_NFS2	2
-#define	FS_NFS3	3
-#define	FS_NFS4	4
-#define	FS_AUTOFS	1
-
-#define	NFS4_FHSIZE 128
 
 bool_t xdr_autofs_netbuf(XDR *, struct netbuf *);
 bool_t xdr_mounta(XDR *, struct mounta *);
 
 bool_t
-xdr_nfs2_args(XDR *xdrs, struct nfs_args *objp);
-
-bool_t
-xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp);
-
-bool_t
-xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp);
-
-bool_t
 xdr_umntrequest(XDR *xdrs, umntrequest *objp)
 {
 	bool_t more_data;
@@ -143,452 +120,6 @@
 	return (TRUE);
 }
 
-
-
-bool_t
-xdr_knetconfig(XDR *xdrs, struct knetconfig *objp)
-{
-
-	rpc_inline_t *buf;
-	char	*knstring;
-	uint_t	d;
-
-	int i;
-
-	if (xdrs->x_op == XDR_DECODE) {
-		if (!xdr_u_int(xdrs, &objp->knc_semantics))
-			return (FALSE);
-		/*
-		 * The knc_protofmly and knc_proto strings will
-		 * be freed as a size of KNC_STRSIZE, make sure the
-		 * buffer allocated is also this size, and not just
-		 * the string size.
-		 */
-		if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE))
-			return (FALSE);
-		knstring = kmem_zalloc(KNC_STRSIZE, KM_SLEEP);
-		bcopy(objp->knc_protofmly, knstring,
-			strlen(objp->knc_protofmly));
-		kmem_free(objp->knc_protofmly, strlen(objp->knc_protofmly) + 1);
-		objp->knc_protofmly = knstring;
-
-		if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE))
-			return (FALSE);
-		knstring = kmem_zalloc(KNC_STRSIZE, KM_SLEEP);
-		bcopy(objp->knc_proto, knstring, strlen(objp->knc_proto));
-		kmem_free(objp->knc_proto, strlen(objp->knc_proto) + 1);
-		objp->knc_proto = knstring;
-
-		if (!xdr_u_int(xdrs, &d))
-			return (FALSE);
-		objp->knc_rdev = expldev(d);
-
-		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_opaque(xdrs, (char *)&objp->knc_unused,
-				sizeof (objp->knc_unused)))
-				return (FALSE);
-		} else {
-			uint_t *genp;
-
-				for (i = 0, genp = objp->knc_unused; i < 8;
-				    i++) {
-					*genp++ = IXDR_GET_U_INT32(buf);
-				}
-		}
-		return (TRUE);
-	}
-
-	if (!xdr_u_int(xdrs, &objp->knc_semantics))
-		return (FALSE);
-	if (xdrs->x_op == XDR_FREE) {
-		kmem_free(objp->knc_protofmly, KNC_STRSIZE);
-		kmem_free(objp->knc_proto, KNC_STRSIZE);
-	} else {
-		if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE))
-			return (FALSE);
-	}
-	if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, (char *)&objp->knc_unused,
-		sizeof (objp->knc_unused)))
-		return (FALSE);
-	return (TRUE);
-}
-
-
-bool_t
-xdr_pathcnf(XDR *xdrs, struct pathcnf *objp)
-{
-
-	rpc_inline_t *buf;
-
-	int i;
-
-
-	if (xdrs->x_op == XDR_DECODE) {
-		buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_int(xdrs, &objp->pc_link_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_max_canon))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_max_input))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_name_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_path_max))
-				return (FALSE);
-			if (!xdr_short(xdrs, &objp->pc_pipe_buf))
-				return (FALSE);
-		} else {
-			objp->pc_link_max = IXDR_GET_INT32(buf);
-			objp->pc_max_canon = IXDR_GET_SHORT(buf);
-			objp->pc_max_input = IXDR_GET_SHORT(buf);
-			objp->pc_name_max = IXDR_GET_SHORT(buf);
-			objp->pc_path_max = IXDR_GET_SHORT(buf);
-			objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
-		}
-		if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
-			return (FALSE);
-		if (!xdr_char(xdrs, &objp->pc_xxx))
-			return (FALSE);
-		buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_opaque(xdrs, (char *)objp->pc_mask,
-				sizeof (objp->pc_mask)))
-				return (FALSE);
-		} else {
-			{
-				short *genp;
-
-				for (i = 0, genp = objp->pc_mask; i < _PC_N;
-				    i++) {
-					*genp++ = IXDR_GET_SHORT(buf);
-				}
-			}
-
-		}
-		return (TRUE);
-	}
-
-	if (!xdr_int(xdrs, &objp->pc_link_max))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_max_canon))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_max_input))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_name_max))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_path_max))
-		return (FALSE);
-	if (!xdr_short(xdrs, &objp->pc_pipe_buf))
-		return (FALSE);
-	if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
-		return (FALSE);
-	if (!xdr_char(xdrs, &objp->pc_xxx))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, (char *)objp->pc_mask,
-		sizeof (objp->pc_mask)))
-		return (FALSE);
-	return (TRUE);
-}
-
-
-bool_t
-xdr_des_clnt_data(XDR *xdrs, dh_k4_clntdata_t *objp)
-{
-	if (!xdr_autofs_netbuf(xdrs, &objp->syncaddr))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
-		sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
-		return (FALSE);
-	if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->netnamelen))
-		return (FALSE);
-	objp->netnamelen = strlen(objp->netname) + 1;
-	return (TRUE);
-}
-
-bool_t
-xdr_gss_clnt_data(XDR *xdrs, struct gss_clnt_data *objp)
-{
-	if (!xdr_u_int(xdrs, &objp->mechanism.length))
-		return (FALSE);
-	if (!xdr_enum(xdrs, (enum_t *)&objp->service))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, objp->mechanism.elements,
-		objp->mechanism.length))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, (char *)&objp->uname, MAX_NAME_LEN))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, (char *)&objp->inst, MAX_NAME_LEN))
-		return (FALSE);
-	if (!xdr_opaque(xdrs, (char *)&objp->realm, MAX_NAME_LEN))
-		return (FALSE);
-	if (!xdr_u_int(xdrs, &objp->qop))
-		return (FALSE);
-	return (TRUE);
-}
-
-bool_t
-xdr_sec_data(XDR *xdrs, struct sec_data *objp)
-{
-	if (!xdr_u_int(xdrs, &objp->secmod))
-		return (FALSE);
-	if (!xdr_u_int(xdrs, &objp->rpcflavor))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->flags))
-		return (FALSE);
-	if (!xdr_uid_t(xdrs, &objp->uid))
-		return (FALSE);
-
-	switch (objp->rpcflavor) {
-	case AUTH_NONE:
-	case AUTH_UNIX:
-	case AUTH_LOOPBACK:
-		break;
-	case AUTH_DES:
-		if (!xdr_pointer(xdrs, (char **)&objp->data,
-			sizeof (dh_k4_clntdata_t),
-			(xdrproc_t)xdr_des_clnt_data))
-			return (FALSE);
-		break;
-	case RPCSEC_GSS:
-		if (!xdr_pointer(xdrs, (char **)&objp->data,
-			sizeof (gss_clntdata_t),
-			(xdrproc_t)xdr_gss_clnt_data))
-			return (FALSE);
-		break;
-	default:
-		return (FALSE);
-	}
-
-	return (TRUE);
-}
-
-bool_t
-xdr_nfs2_fh(XDR *xdrs, nfs_fhandle *objp)
-{
-	objp->fh_len = NFS_FHSIZE;
-	if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, NFS_FHSIZE))
-		return (B_FALSE);
-	return (B_TRUE);
-}
-
-bool_t
-xdr_nfs3_fhandle(XDR *xdrs, nfs_fhandle *objp)
-{
-	if (!xdr_int(xdrs, &objp->fh_len))
-		return (B_FALSE);
-	if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, objp->fh_len))
-		return (B_FALSE);
-	return (B_TRUE);
-}
-
-bool_t
-xdr_nfs(XDR *xdrs, struct nfs_args *objp, int nfsv)
-{
-
-	rpc_inline_t *buf;
-
-	if (objp == NULL)
-		return (TRUE);
-
-	if (xdrs->x_op == XDR_DECODE) {
-		if (!xdr_pointer(xdrs, (char **)&objp->addr,
-			sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-			return (FALSE);
-		if (!xdr_pointer(xdrs, (char **)&objp->syncaddr,
-			sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-			return (FALSE);
-		if (!xdr_pointer(xdrs, (char **)&objp->knconf,
-			sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN))
-			return (FALSE);
-		if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
-			return (FALSE);
-		if (nfsv == FS_NFS4) {
-			if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE))
-				return (B_FALSE);
-		} else if (nfsv == FS_NFS3) {
-			if (!xdr_pointer(xdrs, (char **)&objp->fh,
-				sizeof (nfs_fhandle),
-				(xdrproc_t)xdr_nfs3_fhandle))
-				return (B_FALSE);
-		} else {
-			if (!xdr_pointer(xdrs, (char **)&objp->fh,
-				sizeof (nfs_fhandle),
-				(xdrproc_t)xdr_nfs2_fh))
-				return (B_FALSE);
-		}
-		buf = XDR_INLINE(xdrs, 9 * BYTES_PER_XDR_UNIT);
-		if (buf == NULL) {
-			if (!xdr_int(xdrs, &objp->flags))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->wsize))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->rsize))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->timeo))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->retrans))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acregmin))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acregmax))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acdirmin))
-				return (FALSE);
-			if (!xdr_int(xdrs, &objp->acdirmax))
-				return (FALSE);
-		} else {
-			objp->flags = IXDR_GET_INT32(buf);
-			objp->wsize = IXDR_GET_INT32(buf);
-			objp->rsize = IXDR_GET_INT32(buf);
-			objp->timeo = IXDR_GET_INT32(buf);
-			objp->retrans = IXDR_GET_INT32(buf);
-			objp->acregmin = IXDR_GET_INT32(buf);
-			objp->acregmax = IXDR_GET_INT32(buf);
-			objp->acdirmin = IXDR_GET_INT32(buf);
-			objp->acdirmax = IXDR_GET_INT32(buf);
-		}
-		if (!xdr_pointer(xdrs, (char **)&objp->pathconf,
-			sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf))
-			return (FALSE);
-		if (!xdr_int(xdrs, &objp->nfs_args_ext))
-			return (FALSE);
-		if (!xdr_pointer(xdrs,
-			(char **)&objp->nfs_ext_u.nfs_extA.secdata,
-			sizeof (struct sec_data), (xdrproc_t)xdr_sec_data))
-			return (FALSE);
-		if (objp->nfs_args_ext == NFS_ARGS_EXTB) {
-			if (nfsv == FS_NFS4) {
-				if (!xdr_pointer(xdrs,
-					(char **)&objp->nfs_ext_u.nfs_extB.next,
-					sizeof (struct nfs_args),
-					(xdrproc_t)xdr_nfs4_args))
-					return (FALSE);
-			} else if (nfsv == FS_NFS3) {
-				if (!xdr_pointer(xdrs,
-					(char **)&objp->nfs_ext_u.nfs_extB.next,
-					sizeof (struct nfs_args),
-					(xdrproc_t)xdr_nfs3_args))
-					return (FALSE);
-			} else {
-				if (!xdr_pointer(xdrs,
-					(char **)&objp->nfs_ext_u.nfs_extB.next,
-					sizeof (struct nfs_args),
-					(xdrproc_t)xdr_nfs2_args))
-					return (FALSE);
-			}
-		}
-		return (TRUE);
-	}
-
-	ASSERT(xdrs->x_op != XDR_DECODE);
-	if (!xdr_pointer(xdrs, (char **)&objp->addr,
-		sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->syncaddr,
-		sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
-		sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
-		return (FALSE);
-	if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN))
-		return (FALSE);
-	if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
-		return (FALSE);
-	if (nfsv == FS_NFS4) {
-		if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE))
-			return (B_FALSE);
-	} else if (nfsv == FS_NFS3) {
-		if (!xdr_pointer(xdrs, (char **)&objp->fh,
-			sizeof (nfs_fhandle),
-			(xdrproc_t)xdr_nfs3_fhandle))
-			return (B_FALSE);
-	} else {
-		if (!xdr_pointer(xdrs, (char **)&objp->fh,
-			sizeof (nfs_fhandle),
-			(xdrproc_t)xdr_nfs2_fh))
-			return (B_FALSE);
-	}
-
-	if (!xdr_int(xdrs, &objp->flags))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->wsize))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->rsize))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->timeo))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->retrans))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acregmin))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acregmax))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acdirmin))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->acdirmax))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->pathconf,
-		sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf))
-		return (FALSE);
-	if (!xdr_int(xdrs, &objp->nfs_args_ext))
-		return (FALSE);
-	if (!xdr_pointer(xdrs, (char **)&objp->nfs_ext_u.nfs_extA.secdata,
-		sizeof (struct sec_data), (xdrproc_t)xdr_sec_data))
-		return (FALSE);
-	if (objp->nfs_args_ext == NFS_ARGS_EXTB) {
-		if (nfsv == FS_NFS4) {
-			if (!xdr_pointer(xdrs,
-				(char **)&objp->nfs_ext_u.nfs_extB.next,
-				sizeof (struct nfs_args),
-				(xdrproc_t)xdr_nfs4_args))
-				return (FALSE);
-		} else if (nfsv == FS_NFS3) {
-			if (!xdr_pointer(xdrs,
-				(char **)&objp->nfs_ext_u.nfs_extB.next,
-				sizeof (struct nfs_args),
-				(xdrproc_t)xdr_nfs3_args))
-				return (FALSE);
-		} else {
-			if (!xdr_pointer(xdrs,
-				(char **)&objp->nfs_ext_u.nfs_extB.next,
-				sizeof (struct nfs_args),
-				(xdrproc_t)xdr_nfs2_args))
-				return (FALSE);
-		}
-	}
-	return (TRUE);
-}
-
-bool_t
-xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp)
-{
-	return (xdr_nfs(xdrs, objp, FS_NFS4));
-}
-
-bool_t
-xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp)
-{
-	return (xdr_nfs(xdrs, objp, FS_NFS3));
-}
-
-bool_t
-xdr_nfs2_args(XDR *xdrs, struct nfs_args *objp)
-{
-	return (xdr_nfs(xdrs, objp, FS_NFS2));
-}
-
-
-
 bool_t
 xdr_autofs_args(XDR *xdrs, autofs_args *objp)
 {
@@ -638,53 +169,47 @@
 {
 	bool_t more_data = TRUE;
 	bool_t status = TRUE;
-	action_list *p, *last;
+	action_list *p;
 
 	ASSERT((xdrs->x_op == XDR_DECODE) || (xdrs->x_op == XDR_FREE));
 
 	more_data = (objp != NULL);
 	p = objp;
 
-	if (xdrs->x_op == XDR_FREE) {
-		while (p != NULL) {
-			if (!xdr_action_list_entry(xdrs, &p->action))
-				cmn_err(CE_WARN, "xdr_action_list: "
-					"action_list_entry free failed %p\n",
-					(void *)&p->action);
-			last = p;
-			p = p->next;
-			/*
-			 * Don't need this kmem_free the first action_list
-			 * as xdr_reference using xdr_action_list will free
-			 * it when called with the XDR_FREE op.
-			 */
-			if (last != objp)
-				kmem_free(last, sizeof (*last));
-		}
-		return (status);
-	}
+	if (xdrs->x_op == XDR_FREE)
+		goto free;
 
 	while (more_data) {
-		if (!xdr_action_list_entry(xdrs, &p->action)) {
-			status = FALSE;
-			break;
-		}
+		if (!xdr_action_list_entry(xdrs, &p->action))
+			goto free;
 
-		if (!xdr_bool(xdrs, &more_data)) {
-			status = FALSE;
-			break;
-		}
+		if (!xdr_bool(xdrs, &more_data))
+			goto free;
 
 		if (more_data) {
 			p->next = kmem_zalloc(sizeof (action_list), KM_SLEEP);
 			p = p->next;
 			if (p == NULL) {
 				status = FALSE;
-				break;
+				goto free;
 			}
 		} else
 			p->next = NULL;
 	}
+	return (TRUE);
+
+free:
+	for (p = objp; p != NULL; ) {
+		if (!xdr_action_list_entry(xdrs, &objp->action))
+			cmn_err(CE_WARN, "xdr_action_list: "
+			    "action_list_entry free failed %p\n",
+			    (void *)&objp->action);
+		p = p->next;
+		kmem_free(objp, sizeof (*objp));
+		objp = p;
+	}
+	objp = NULL;
+
 	return (status);
 }
 
@@ -703,50 +228,17 @@
 bool_t
 xdr_mounta(XDR *xdrs, struct mounta *objp)
 {
-	int	fstype = 0;
 	if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN))
 		return (FALSE);
 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
 		return (FALSE);
 	if (!xdr_int(xdrs, &objp->flags))
 		return (FALSE);
-	/*
-	 * For a free we must first determine the fstype before calling
-	 * xdr_string on it, as the xdr_string will free it.  For a
-	 * decode we must first call xdr_string to get the value to
-	 * determine the fstype.
-	 */
-	if (xdrs->x_op == XDR_FREE) {
-		if (strncmp(objp->fstype, "autofs", sizeof ("autofs")) == 0) {
-			fstype = FS_AUTOFS;
-		} else if (strncmp(objp->fstype, "nfs4",
-				sizeof ("nfs4")) == 0) {
-			fstype = FS_NFS4;
-		} else if (strncmp(objp->fstype, "nfs3",
-			sizeof ("nfs3")) == 0) {
-			fstype = FS_NFS3;
-		} else {
-			fstype = FS_NFS2;
-		}
-	}
-
 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
 		return (FALSE);
-
-	if (xdrs->x_op == XDR_DECODE) {
-		if (strncmp(objp->fstype, "autofs", sizeof ("autofs")) == 0) {
-			fstype = FS_AUTOFS;
-		} else if (strncmp(objp->fstype, "nfs4",
-			sizeof ("nfs4")) == 0) {
-			fstype = FS_NFS4;
-		} else if (strncmp(objp->fstype, "nfs3",
-			sizeof ("nfs3")) == 0) {
-			fstype = FS_NFS3;
-		} else {
-			fstype = FS_NFS2;
-		}
-	}
-
+	if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args),
+	    (xdrproc_t)xdr_autofs_args))
+		return (FALSE);
 	/*
 	 * The length is the original user-land length, not the
 	 * length of the native kernel autofs_args structure provided
@@ -754,61 +246,15 @@
 	 * the length is wrong and we need to stuff the length field with
 	 * the length of the native structure.
 	 */
-	if (fstype == FS_AUTOFS) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (autofs_args),
-			(xdrproc_t)xdr_autofs_args))
-			return (FALSE);
-		if (!xdr_int(xdrs, &objp->datalen))
-			return (FALSE);
-		if (xdrs->x_op == XDR_DECODE)
-			objp->datalen = sizeof (struct autofs_args);
-	} else if (fstype == FS_NFS4) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (struct nfs_args),
-			(xdrproc_t)xdr_nfs4_args))
-			return (FALSE);
-		if (!xdr_int(xdrs, &objp->datalen))
-			return (FALSE);
-		if (xdrs->x_op == XDR_DECODE)
-			objp->datalen = sizeof (struct nfs_args);
-	} else if (fstype == FS_NFS3) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (struct nfs_args),
-			(xdrproc_t)xdr_nfs3_args))
-			return (FALSE);
-		if (!xdr_int(xdrs, &objp->datalen))
-			return (FALSE);
-		if (xdrs->x_op == XDR_DECODE)
-			objp->datalen = sizeof (struct nfs_args);
-	} else if (fstype == FS_NFS2) {
-		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
-			sizeof (struct nfs_args),
-			(xdrproc_t)xdr_nfs2_args))
-			return (FALSE);
-		if (!xdr_int(xdrs, &objp->datalen))
-			return (FALSE);
-		if (xdrs->x_op == XDR_DECODE)
-			objp->datalen = sizeof (struct nfs_args);
-	}
-
-	/*
-	 * domount's call to vfs_buildoptionstr() can alter the contents
-	 * of the options string, resulting in a shorter string
-	 * length.  Thus, xdr_string can not be used to free this
-	 * string as it may be freed using a different size than allocated.
-	 */
-	if (xdrs->x_op == XDR_DECODE) {
-		if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
-			return (FALSE);
-	} else {
-		ASSERT(xdrs->x_op == XDR_FREE);
-		kmem_free(objp->optptr, objp->optlen);
-	}
+	if (!xdr_int(xdrs, &objp->datalen))
+		return (FALSE);
+	if (xdrs->x_op == XDR_DECODE)
+		objp->datalen = sizeof (struct autofs_args);
+	if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
+		return (FALSE);
 	if (!xdr_int(xdrs, &objp->optlen))
 		return (FALSE);
-	if (xdrs->x_op == XDR_DECODE)
-		ASSERT((strlen(objp->optptr) + 1) == objp->optlen);
+	ASSERT((xdrs->x_op == XDR_DECODE) || (xdrs->x_op == XDR_FREE));
 	return (TRUE);
 }