xref: /titanic_51/usr/src/uts/common/fs/nfs/nfs_sys.c (revision b89a8333f5e1f75ec0c269b22524bd2eccb972ba)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5cee86682Scalum  * Common Development and Distribution License (the "License").
6cee86682Scalum  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  * Copyright (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
267c478bd9Sstevel@tonic-gate  * All rights reserved.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <rpc/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/systm.h>
327c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
337c478bd9Sstevel@tonic-gate #include <sys/errno.h>
347c478bd9Sstevel@tonic-gate #include <sys/cred.h>
357c478bd9Sstevel@tonic-gate #include <sys/policy.h>
367c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
377c478bd9Sstevel@tonic-gate #include <sys/proc.h>		/* for exit() declaration */
38cee86682Scalum #include <sys/kmem.h>
397c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
407c478bd9Sstevel@tonic-gate #include <nfs/nfssys.h>
417c478bd9Sstevel@tonic-gate #include <sys/thread.h>
427c478bd9Sstevel@tonic-gate #include <rpc/auth.h>
437c478bd9Sstevel@tonic-gate #include <rpc/rpcsys.h>
447c478bd9Sstevel@tonic-gate #include <rpc/svc.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate  * This is filled in with an appropriate address for the
487c478bd9Sstevel@tonic-gate  * function that will traverse the rfs4_client_t table
497c478bd9Sstevel@tonic-gate  * and mark any matching IP Address as "forced_expire".
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  * It is the server init() function that plops the
527c478bd9Sstevel@tonic-gate  * function pointer.
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate void (*rfs4_client_clrst)(struct nfs4clrst_args *) = NULL;
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /* This filled in by nfssrv:_init() */
577c478bd9Sstevel@tonic-gate void (*nfs_srv_quiesce_func)(void) = NULL;
587c478bd9Sstevel@tonic-gate 
59*b89a8333Snatalie li - Sun Microsystems - Irvine United States extern void nfscmd_args(uint_t);
60*b89a8333Snatalie li - Sun Microsystems - Irvine United States 
617c478bd9Sstevel@tonic-gate /*
627c478bd9Sstevel@tonic-gate  * These will be reset by klmmod:lm_svc(), when lockd starts NLM service,
637c478bd9Sstevel@tonic-gate  * based on values read by lockd from /etc/default/nfs. Since nfssrv depends on
647c478bd9Sstevel@tonic-gate  * klmmod, the declarations need to be here (in nfs, on which both depend) so
657c478bd9Sstevel@tonic-gate  * that nfssrv can see the klmmod changes.
667c478bd9Sstevel@tonic-gate  * When the dependency of NFSv4 on NLM/lockd is removed, this will need to
677c478bd9Sstevel@tonic-gate  * be adjusted.
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate #define	RFS4_LEASETIME 90			/* seconds */
707c478bd9Sstevel@tonic-gate time_t rfs4_lease_time = RFS4_LEASETIME;
717c478bd9Sstevel@tonic-gate time_t rfs4_grace_period = RFS4_LEASETIME;
727c478bd9Sstevel@tonic-gate 
73cee86682Scalum /* DSS: distributed stable storage */
74cee86682Scalum size_t nfs4_dss_buflen = 0;
75cee86682Scalum /* This filled in by nfssrv:_init() */
76cee86682Scalum int (*nfs_srv_dss_func)(char *, size_t) = NULL;
77cee86682Scalum 
78ecd6cf80Smarks int
79ecd6cf80Smarks nfs_export(void *arg)
80ecd6cf80Smarks {
81ecd6cf80Smarks 	STRUCT_DECL(exportfs_args, ea);
82ecd6cf80Smarks 
83ecd6cf80Smarks 	if (!INGLOBALZONE(curproc))
84ecd6cf80Smarks 		return (set_errno(EPERM));
85ecd6cf80Smarks 	STRUCT_INIT(ea, get_udatamodel());
86ecd6cf80Smarks 	if (copyin(arg, STRUCT_BUF(ea), STRUCT_SIZE(ea)))
87ecd6cf80Smarks 		return (set_errno(EFAULT));
88ecd6cf80Smarks 
89ecd6cf80Smarks 	return (exportfs(STRUCT_BUF(ea), get_udatamodel(), CRED()));
90ecd6cf80Smarks }
91cee86682Scalum 
927c478bd9Sstevel@tonic-gate int
937c478bd9Sstevel@tonic-gate nfssys(enum nfssys_op opcode, void *arg)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate 	int error = 0;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	if (!(opcode == NFS_REVAUTH || opcode == NFS4_SVC) &&
987c478bd9Sstevel@tonic-gate 	    secpolicy_nfs(CRED()) != 0)
997c478bd9Sstevel@tonic-gate 		return (set_errno(EPERM));
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	switch (opcode) {
1027c478bd9Sstevel@tonic-gate 	case NFS4_CLR_STATE: { /* Clear NFS4 client state */
1037c478bd9Sstevel@tonic-gate 		struct nfs4clrst_args clr;
1047c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs4clrst_args, u_clr);
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 		/*
1077c478bd9Sstevel@tonic-gate 		 * If the server is not loaded then no point in
1087c478bd9Sstevel@tonic-gate 		 * clearing nothing :-)
1097c478bd9Sstevel@tonic-gate 		 */
1107c478bd9Sstevel@tonic-gate 		if (rfs4_client_clrst == NULL) {
1117c478bd9Sstevel@tonic-gate 			break;
1127c478bd9Sstevel@tonic-gate 		}
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 		if (!INGLOBALZONE(curproc))
1157c478bd9Sstevel@tonic-gate 			return (set_errno(EPERM));
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 		STRUCT_INIT(u_clr, get_udatamodel());
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(u_clr), STRUCT_SIZE(u_clr)))
1207c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 		clr.vers = STRUCT_FGET(u_clr, vers);
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 		if (clr.vers != NFS4_CLRST_VERSION)
1257c478bd9Sstevel@tonic-gate 			return (set_errno(EINVAL));
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 		clr.addr_type = STRUCT_FGET(u_clr, addr_type);
1287c478bd9Sstevel@tonic-gate 		clr.ap = STRUCT_FGETP(u_clr, ap);
1297c478bd9Sstevel@tonic-gate 		rfs4_client_clrst(&clr);
1307c478bd9Sstevel@tonic-gate 		break;
1317c478bd9Sstevel@tonic-gate 	}
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	case SVCPOOL_CREATE: { /* setup an RPC server thread pool */
1347c478bd9Sstevel@tonic-gate 		struct svcpool_args p;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 		if (copyin(arg, &p, sizeof (p)))
1377c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 		error = svc_pool_create(&p);
1407c478bd9Sstevel@tonic-gate 		break;
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	case SVCPOOL_WAIT: { /* wait in kernel for threads to be needed */
1447c478bd9Sstevel@tonic-gate 		int id;
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 		if (copyin(arg, &id, sizeof (id)))
1477c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 		error = svc_wait(id);
1507c478bd9Sstevel@tonic-gate 		break;
1517c478bd9Sstevel@tonic-gate 	}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	case SVCPOOL_RUN: { /* give work to a runnable thread */
1547c478bd9Sstevel@tonic-gate 		int id;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 		if (copyin(arg, &id, sizeof (id)))
1577c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 		error = svc_do_run(id);
1607c478bd9Sstevel@tonic-gate 		break;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	case RDMA_SVC_INIT: {
1647c478bd9Sstevel@tonic-gate 		struct rdma_svc_args rsa;
1657c478bd9Sstevel@tonic-gate 		char netstore[20] = "tcp";
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 		if (!INGLOBALZONE(curproc))
1687c478bd9Sstevel@tonic-gate 			return (set_errno(EPERM));
1697c478bd9Sstevel@tonic-gate 		if (get_udatamodel() != DATAMODEL_NATIVE) {
1707c478bd9Sstevel@tonic-gate 			STRUCT_DECL(rdma_svc_args, ursa);
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 			STRUCT_INIT(ursa, get_udatamodel());
1737c478bd9Sstevel@tonic-gate 			if (copyin(arg, STRUCT_BUF(ursa), STRUCT_SIZE(ursa)))
1747c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 			rsa.poolid = STRUCT_FGET(ursa, poolid);
1777c478bd9Sstevel@tonic-gate 			rsa.nfs_versmin = STRUCT_FGET(ursa, nfs_versmin);
1787c478bd9Sstevel@tonic-gate 			rsa.nfs_versmax = STRUCT_FGET(ursa, nfs_versmax);
1797c478bd9Sstevel@tonic-gate 			rsa.delegation = STRUCT_FGET(ursa, delegation);
1807c478bd9Sstevel@tonic-gate 		} else {
1817c478bd9Sstevel@tonic-gate 			if (copyin(arg, &rsa, sizeof (rsa)))
1827c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
1837c478bd9Sstevel@tonic-gate 		}
1847c478bd9Sstevel@tonic-gate 		rsa.netid = netstore;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 		error = rdma_start(&rsa);
1877c478bd9Sstevel@tonic-gate 		break;
1887c478bd9Sstevel@tonic-gate 	}
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	case NFS_SVC: { /* NFS server daemon */
1917c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs_svc_args, nsa);
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 		if (!INGLOBALZONE(curproc))
1947c478bd9Sstevel@tonic-gate 			return (set_errno(EPERM));
1957c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nsa, get_udatamodel());
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
1987c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 		error = nfs_svc(STRUCT_BUF(nsa), get_udatamodel());
2017c478bd9Sstevel@tonic-gate 		break;
2027c478bd9Sstevel@tonic-gate 	}
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	case EXPORTFS: { /* export a file system */
205ecd6cf80Smarks 		error = nfs_export(arg);
2067c478bd9Sstevel@tonic-gate 		break;
2077c478bd9Sstevel@tonic-gate 	}
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	case NFS_GETFH: { /* get a file handle */
2107c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs_getfh_args, nga);
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		if (!INGLOBALZONE(curproc))
2137c478bd9Sstevel@tonic-gate 			return (set_errno(EPERM));
2147c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nga, get_udatamodel());
2157c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nga), STRUCT_SIZE(nga)))
2167c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 		error = nfs_getfh(STRUCT_BUF(nga), get_udatamodel(), CRED());
2197c478bd9Sstevel@tonic-gate 		break;
2207c478bd9Sstevel@tonic-gate 	}
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	case NFS_REVAUTH: { /* revoke the cached credentials for the uid */
2237c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs_revauth_args, nra);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nra, get_udatamodel());
2267c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nra), STRUCT_SIZE(nra)))
2277c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 		/* This call performs its own privilege checking */
2307c478bd9Sstevel@tonic-gate 		error = sec_clnt_revoke(STRUCT_FGET(nra, authtype),
2317c478bd9Sstevel@tonic-gate 		    STRUCT_FGET(nra, uid), CRED(), NULL, get_udatamodel());
2327c478bd9Sstevel@tonic-gate 		break;
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	case LM_SVC: { /* LM server daemon */
2367c478bd9Sstevel@tonic-gate 		struct lm_svc_args lsa;
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate 		if (get_udatamodel() != DATAMODEL_NATIVE) {
2397c478bd9Sstevel@tonic-gate 			STRUCT_DECL(lm_svc_args, ulsa);
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 			STRUCT_INIT(ulsa, get_udatamodel());
2427c478bd9Sstevel@tonic-gate 			if (copyin(arg, STRUCT_BUF(ulsa), STRUCT_SIZE(ulsa)))
2437c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 			lsa.version = STRUCT_FGET(ulsa, version);
2467c478bd9Sstevel@tonic-gate 			lsa.fd = STRUCT_FGET(ulsa, fd);
2477c478bd9Sstevel@tonic-gate 			lsa.n_fmly = STRUCT_FGET(ulsa, n_fmly);
2487c478bd9Sstevel@tonic-gate 			lsa.n_proto = STRUCT_FGET(ulsa, n_proto);
2497c478bd9Sstevel@tonic-gate 			lsa.n_rdev = expldev(STRUCT_FGET(ulsa, n_rdev));
2507c478bd9Sstevel@tonic-gate 			lsa.debug = STRUCT_FGET(ulsa, debug);
2517c478bd9Sstevel@tonic-gate 			lsa.timout = STRUCT_FGET(ulsa, timout);
2527c478bd9Sstevel@tonic-gate 			lsa.grace = STRUCT_FGET(ulsa, grace);
2537c478bd9Sstevel@tonic-gate 			lsa.retransmittimeout = STRUCT_FGET(ulsa,
2547c478bd9Sstevel@tonic-gate 			    retransmittimeout);
2557c478bd9Sstevel@tonic-gate 		} else {
2567c478bd9Sstevel@tonic-gate 			if (copyin(arg, &lsa, sizeof (lsa)))
2577c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
2587c478bd9Sstevel@tonic-gate 		}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		error = lm_svc(&lsa);
2617c478bd9Sstevel@tonic-gate 		break;
2627c478bd9Sstevel@tonic-gate 	}
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	case KILL_LOCKMGR: {
2657c478bd9Sstevel@tonic-gate 		error = lm_shutdown();
2667c478bd9Sstevel@tonic-gate 		break;
2677c478bd9Sstevel@tonic-gate 	}
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	case LOG_FLUSH:	{	/* Flush log buffer and possibly rename */
2707c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfsl_flush_args, nfa);
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nfa, get_udatamodel());
2737c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nfa), STRUCT_SIZE(nfa)))
2747c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 		error = nfsl_flush(STRUCT_BUF(nfa), get_udatamodel());
2777c478bd9Sstevel@tonic-gate 		break;
2787c478bd9Sstevel@tonic-gate 	}
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	case NFS4_SVC: { /* NFS client callback daemon */
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs4_svc_args, nsa);
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nsa, get_udatamodel());
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
2877c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 		error = nfs4_svc(STRUCT_BUF(nsa), get_udatamodel());
2907c478bd9Sstevel@tonic-gate 		break;
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 
293cee86682Scalum 	/* Request that NFSv4 server quiesce on next shutdown */
294cee86682Scalum 	case NFS4_SVC_REQUEST_QUIESCE: {
295cee86682Scalum 		int id;
296cee86682Scalum 
297cee86682Scalum 		/* check that nfssrv module is loaded */
298cee86682Scalum 		if (nfs_srv_quiesce_func == NULL)
299cee86682Scalum 			return (set_errno(ENOTSUP));
300cee86682Scalum 
301cee86682Scalum 		if (copyin(arg, &id, sizeof (id)))
302cee86682Scalum 			return (set_errno(EFAULT));
303cee86682Scalum 
304cee86682Scalum 		error = svc_pool_control(id, SVCPSET_SHUTDOWN_PROC,
305cee86682Scalum 		    (void *)nfs_srv_quiesce_func);
306cee86682Scalum 		break;
307cee86682Scalum 	}
308cee86682Scalum 
3097c478bd9Sstevel@tonic-gate 	case NFS_IDMAP: {
3107c478bd9Sstevel@tonic-gate 		struct nfsidmap_args idm;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 		if (copyin(arg, &idm, sizeof (idm)))
3137c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 		nfs_idmap_args(&idm);
3167c478bd9Sstevel@tonic-gate 		error = 0;
3177c478bd9Sstevel@tonic-gate 		break;
3187c478bd9Sstevel@tonic-gate 	}
3197c478bd9Sstevel@tonic-gate 
320cee86682Scalum 	case NFS4_DSS_SETPATHS_SIZE: {
321cee86682Scalum 		/* crosses ILP32/LP64 boundary */
322cee86682Scalum 		uint32_t nfs4_dss_bufsize = 0;
323cee86682Scalum 
324cee86682Scalum 		if (copyin(arg, &nfs4_dss_bufsize, sizeof (nfs4_dss_bufsize)))
325cee86682Scalum 			return (set_errno(EFAULT));
326cee86682Scalum 		nfs4_dss_buflen = (long)nfs4_dss_bufsize;
327cee86682Scalum 		error = 0;
328cee86682Scalum 		break;
329cee86682Scalum 	}
330cee86682Scalum 
331cee86682Scalum 	case NFS4_DSS_SETPATHS: {
332cee86682Scalum 		char *nfs4_dss_bufp;
333cee86682Scalum 
334cee86682Scalum 		/* check that nfssrv module is loaded */
335cee86682Scalum 		if (nfs_srv_dss_func == NULL)
336cee86682Scalum 			return (set_errno(ENOTSUP));
337cee86682Scalum 
338cee86682Scalum 		/*
339cee86682Scalum 		 * NFS4_DSS_SETPATHS_SIZE must be called before
340cee86682Scalum 		 * NFS4_DSS_SETPATHS, to tell us how big a buffer we need
341cee86682Scalum 		 * to allocate.
342cee86682Scalum 		 */
343cee86682Scalum 		if (nfs4_dss_buflen == 0)
344cee86682Scalum 			return (set_errno(EINVAL));
345cee86682Scalum 		nfs4_dss_bufp = kmem_alloc(nfs4_dss_buflen, KM_SLEEP);
346cee86682Scalum 		if (nfs4_dss_bufp == NULL)
347cee86682Scalum 			return (set_errno(ENOMEM));
348cee86682Scalum 
349cee86682Scalum 		if (copyin(arg, nfs4_dss_bufp, nfs4_dss_buflen)) {
350cee86682Scalum 			kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
351cee86682Scalum 			return (set_errno(EFAULT));
352cee86682Scalum 		}
353cee86682Scalum 
354cee86682Scalum 		/* unpack the buffer and extract the pathnames */
355cee86682Scalum 		error = nfs_srv_dss_func(nfs4_dss_bufp, nfs4_dss_buflen);
356cee86682Scalum 		kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
357cee86682Scalum 
358cee86682Scalum 		break;
359cee86682Scalum 	}
360cee86682Scalum 
361b9238976Sth199096 	case NFS4_EPHEMERAL_MOUNT_TO: {
362b9238976Sth199096 		uint_t	mount_to;
363b9238976Sth199096 
364b9238976Sth199096 		/*
365b9238976Sth199096 		 * Not a very complicated call.
366b9238976Sth199096 		 */
367b9238976Sth199096 		if (copyin(arg, &mount_to, sizeof (mount_to)))
368b9238976Sth199096 			return (set_errno(EFAULT));
369b9238976Sth199096 		nfs4_ephemeral_set_mount_to(mount_to);
370b9238976Sth199096 		error = 0;
371b9238976Sth199096 		break;
372b9238976Sth199096 	}
373b9238976Sth199096 
3741cc55349Srmesta 	case MOUNTD_ARGS: {
3751cc55349Srmesta 		uint_t	did;
3761cc55349Srmesta 
3771cc55349Srmesta 		/*
3781cc55349Srmesta 		 * For now, only passing down the door fd; if we
3791cc55349Srmesta 		 * ever need to pass down more info, we can use
3801cc55349Srmesta 		 * a (properly aligned) struct.
3811cc55349Srmesta 		 */
3821cc55349Srmesta 		if (copyin(arg, &did, sizeof (did)))
3831cc55349Srmesta 			return (set_errno(EFAULT));
3841cc55349Srmesta 		mountd_args(did);
3851cc55349Srmesta 		error = 0;
3861cc55349Srmesta 		break;
3871cc55349Srmesta 	}
3881cc55349Srmesta 
389*b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case NFSCMD_ARGS: {
390*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		uint_t	did;
391*b89a8333Snatalie li - Sun Microsystems - Irvine United States 
392*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/*
393*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * For now, only passing down the door fd; if we
394*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * ever need to pass down more info, we can use
395*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * a (properly aligned) struct.
396*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 */
397*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (copyin(arg, &did, sizeof (did)))
398*b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (set_errno(EFAULT));
399*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		nfscmd_args(did);
400*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		error = 0;
401*b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
402*b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
403*b89a8333Snatalie li - Sun Microsystems - Irvine United States 
4047c478bd9Sstevel@tonic-gate 	default:
4057c478bd9Sstevel@tonic-gate 		error = EINVAL;
4067c478bd9Sstevel@tonic-gate 		break;
4077c478bd9Sstevel@tonic-gate 	}
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 	return ((error != 0) ? set_errno(error) : 0);
4107c478bd9Sstevel@tonic-gate }
411