xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs_sys.c (revision 967a528a)
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  */
210dfe541eSEvan Layton 
227c478bd9Sstevel@tonic-gate /*
23b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
250dfe541eSEvan Layton  */
260dfe541eSEvan Layton 
270dfe541eSEvan Layton /*
287c478bd9Sstevel@tonic-gate  * Copyright (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
297c478bd9Sstevel@tonic-gate  * All rights reserved.
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
320dfe541eSEvan Layton /*
330dfe541eSEvan Layton  * Copyright 2018 Nexenta Systems, Inc.
34*967a528aSDan McDonald  * Copyright 2023 MNX Cloud, Inc.
350dfe541eSEvan Layton  */
360dfe541eSEvan Layton 
377c478bd9Sstevel@tonic-gate #include <sys/types.h>
387c478bd9Sstevel@tonic-gate #include <rpc/types.h>
397c478bd9Sstevel@tonic-gate #include <sys/systm.h>
407c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
417c478bd9Sstevel@tonic-gate #include <sys/errno.h>
427c478bd9Sstevel@tonic-gate #include <sys/cred.h>
437c478bd9Sstevel@tonic-gate #include <sys/policy.h>
447c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
457c478bd9Sstevel@tonic-gate #include <sys/proc.h>		/* for exit() declaration */
46cee86682Scalum #include <sys/kmem.h>
477c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
487c478bd9Sstevel@tonic-gate #include <nfs/nfssys.h>
497c478bd9Sstevel@tonic-gate #include <sys/thread.h>
507c478bd9Sstevel@tonic-gate #include <rpc/auth.h>
517c478bd9Sstevel@tonic-gate #include <rpc/rpcsys.h>
527c478bd9Sstevel@tonic-gate #include <rpc/svc.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /* This filled in by nfssrv:_init() */
557c478bd9Sstevel@tonic-gate void (*nfs_srv_quiesce_func)(void) = NULL;
567c478bd9Sstevel@tonic-gate 
57b89a8333Snatalie li - Sun Microsystems - Irvine United States extern void nfscmd_args(uint_t);
58b89a8333Snatalie li - Sun Microsystems - Irvine United States 
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate  * These will be reset by klmmod:lm_svc(), when lockd starts NLM service,
617c478bd9Sstevel@tonic-gate  * based on values read by lockd from /etc/default/nfs. Since nfssrv depends on
627c478bd9Sstevel@tonic-gate  * klmmod, the declarations need to be here (in nfs, on which both depend) so
637c478bd9Sstevel@tonic-gate  * that nfssrv can see the klmmod changes.
647c478bd9Sstevel@tonic-gate  * When the dependency of NFSv4 on NLM/lockd is removed, this will need to
657c478bd9Sstevel@tonic-gate  * be adjusted.
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate #define	RFS4_LEASETIME 90			/* seconds */
687c478bd9Sstevel@tonic-gate time_t rfs4_lease_time = RFS4_LEASETIME;
697c478bd9Sstevel@tonic-gate time_t rfs4_grace_period = RFS4_LEASETIME;
707c478bd9Sstevel@tonic-gate 
71cee86682Scalum /* DSS: distributed stable storage */
72cee86682Scalum size_t nfs4_dss_buflen = 0;
73cee86682Scalum /* This filled in by nfssrv:_init() */
74cee86682Scalum int (*nfs_srv_dss_func)(char *, size_t) = NULL;
75cee86682Scalum 
76ecd6cf80Smarks int
nfs_export(void * arg)77ecd6cf80Smarks nfs_export(void *arg)
78ecd6cf80Smarks {
79ecd6cf80Smarks 	STRUCT_DECL(exportfs_args, ea);
80ecd6cf80Smarks 
81ecd6cf80Smarks 	STRUCT_INIT(ea, get_udatamodel());
82ecd6cf80Smarks 	if (copyin(arg, STRUCT_BUF(ea), STRUCT_SIZE(ea)))
83ecd6cf80Smarks 		return (set_errno(EFAULT));
84ecd6cf80Smarks 
85ecd6cf80Smarks 	return (exportfs(STRUCT_BUF(ea), get_udatamodel(), CRED()));
86ecd6cf80Smarks }
87cee86682Scalum 
887c478bd9Sstevel@tonic-gate int
nfssys(enum nfssys_op opcode,void * arg)897c478bd9Sstevel@tonic-gate nfssys(enum nfssys_op opcode, void *arg)
907c478bd9Sstevel@tonic-gate {
917c478bd9Sstevel@tonic-gate 	int error = 0;
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	if (!(opcode == NFS_REVAUTH || opcode == NFS4_SVC) &&
947c478bd9Sstevel@tonic-gate 	    secpolicy_nfs(CRED()) != 0)
957c478bd9Sstevel@tonic-gate 		return (set_errno(EPERM));
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	switch (opcode) {
987c478bd9Sstevel@tonic-gate 	case NFS4_CLR_STATE: { /* Clear NFS4 client state */
997c478bd9Sstevel@tonic-gate 		struct nfs4clrst_args clr;
1007c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs4clrst_args, u_clr);
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 		STRUCT_INIT(u_clr, get_udatamodel());
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(u_clr), STRUCT_SIZE(u_clr)))
1057c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 		clr.vers = STRUCT_FGET(u_clr, vers);
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 		if (clr.vers != NFS4_CLRST_VERSION)
1107c478bd9Sstevel@tonic-gate 			return (set_errno(EINVAL));
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 		clr.addr_type = STRUCT_FGET(u_clr, addr_type);
1137c478bd9Sstevel@tonic-gate 		clr.ap = STRUCT_FGETP(u_clr, ap);
114*967a528aSDan McDonald 		error = rfs4_clear_client_state(&clr);
1157c478bd9Sstevel@tonic-gate 		break;
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	case SVCPOOL_CREATE: { /* setup an RPC server thread pool */
1197c478bd9Sstevel@tonic-gate 		struct svcpool_args p;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 		if (copyin(arg, &p, sizeof (p)))
1227c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 		error = svc_pool_create(&p);
1257c478bd9Sstevel@tonic-gate 		break;
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	case SVCPOOL_WAIT: { /* wait in kernel for threads to be needed */
1297c478bd9Sstevel@tonic-gate 		int id;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 		if (copyin(arg, &id, sizeof (id)))
1327c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 		error = svc_wait(id);
1357c478bd9Sstevel@tonic-gate 		break;
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	case SVCPOOL_RUN: { /* give work to a runnable thread */
1397c478bd9Sstevel@tonic-gate 		int id;
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 		if (copyin(arg, &id, sizeof (id)))
1427c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 		error = svc_do_run(id);
1457c478bd9Sstevel@tonic-gate 		break;
1467c478bd9Sstevel@tonic-gate 	}
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	case RDMA_SVC_INIT: {
1497c478bd9Sstevel@tonic-gate 		struct rdma_svc_args rsa;
1507c478bd9Sstevel@tonic-gate 		char netstore[20] = "tcp";
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 		if (get_udatamodel() != DATAMODEL_NATIVE) {
1537c478bd9Sstevel@tonic-gate 			STRUCT_DECL(rdma_svc_args, ursa);
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 			STRUCT_INIT(ursa, get_udatamodel());
1567c478bd9Sstevel@tonic-gate 			if (copyin(arg, STRUCT_BUF(ursa), STRUCT_SIZE(ursa)))
1577c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 			rsa.poolid = STRUCT_FGET(ursa, poolid);
1607c478bd9Sstevel@tonic-gate 			rsa.nfs_versmin = STRUCT_FGET(ursa, nfs_versmin);
1617c478bd9Sstevel@tonic-gate 			rsa.nfs_versmax = STRUCT_FGET(ursa, nfs_versmax);
1627c478bd9Sstevel@tonic-gate 			rsa.delegation = STRUCT_FGET(ursa, delegation);
1637c478bd9Sstevel@tonic-gate 		} else {
1647c478bd9Sstevel@tonic-gate 			if (copyin(arg, &rsa, sizeof (rsa)))
1657c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 		rsa.netid = netstore;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 		error = rdma_start(&rsa);
1707c478bd9Sstevel@tonic-gate 		break;
1717c478bd9Sstevel@tonic-gate 	}
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	case NFS_SVC: { /* NFS server daemon */
1747c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs_svc_args, nsa);
1757c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nsa, get_udatamodel());
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
1787c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 		error = nfs_svc(STRUCT_BUF(nsa), get_udatamodel());
1817c478bd9Sstevel@tonic-gate 		break;
1827c478bd9Sstevel@tonic-gate 	}
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	case EXPORTFS: { /* export a file system */
185ecd6cf80Smarks 		error = nfs_export(arg);
1867c478bd9Sstevel@tonic-gate 		break;
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	case NFS_GETFH: { /* get a file handle */
1907c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs_getfh_args, nga);
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nga, get_udatamodel());
1937c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nga), STRUCT_SIZE(nga)))
1947c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 		error = nfs_getfh(STRUCT_BUF(nga), get_udatamodel(), CRED());
1977c478bd9Sstevel@tonic-gate 		break;
1987c478bd9Sstevel@tonic-gate 	}
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	case NFS_REVAUTH: { /* revoke the cached credentials for the uid */
2017c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs_revauth_args, nra);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nra, get_udatamodel());
2047c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nra), STRUCT_SIZE(nra)))
2057c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 		/* This call performs its own privilege checking */
2087c478bd9Sstevel@tonic-gate 		error = sec_clnt_revoke(STRUCT_FGET(nra, authtype),
2097c478bd9Sstevel@tonic-gate 		    STRUCT_FGET(nra, uid), CRED(), NULL, get_udatamodel());
2107c478bd9Sstevel@tonic-gate 		break;
2117c478bd9Sstevel@tonic-gate 	}
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	case LM_SVC: { /* LM server daemon */
2147c478bd9Sstevel@tonic-gate 		struct lm_svc_args lsa;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 		if (get_udatamodel() != DATAMODEL_NATIVE) {
2177c478bd9Sstevel@tonic-gate 			STRUCT_DECL(lm_svc_args, ulsa);
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 			STRUCT_INIT(ulsa, get_udatamodel());
2207c478bd9Sstevel@tonic-gate 			if (copyin(arg, STRUCT_BUF(ulsa), STRUCT_SIZE(ulsa)))
2217c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 			lsa.version = STRUCT_FGET(ulsa, version);
2247c478bd9Sstevel@tonic-gate 			lsa.fd = STRUCT_FGET(ulsa, fd);
2257c478bd9Sstevel@tonic-gate 			lsa.n_fmly = STRUCT_FGET(ulsa, n_fmly);
2267c478bd9Sstevel@tonic-gate 			lsa.n_proto = STRUCT_FGET(ulsa, n_proto);
2277c478bd9Sstevel@tonic-gate 			lsa.n_rdev = expldev(STRUCT_FGET(ulsa, n_rdev));
2287c478bd9Sstevel@tonic-gate 			lsa.debug = STRUCT_FGET(ulsa, debug);
2297c478bd9Sstevel@tonic-gate 			lsa.timout = STRUCT_FGET(ulsa, timout);
2307c478bd9Sstevel@tonic-gate 			lsa.grace = STRUCT_FGET(ulsa, grace);
2317c478bd9Sstevel@tonic-gate 			lsa.retransmittimeout = STRUCT_FGET(ulsa,
2327c478bd9Sstevel@tonic-gate 			    retransmittimeout);
2337c478bd9Sstevel@tonic-gate 		} else {
2347c478bd9Sstevel@tonic-gate 			if (copyin(arg, &lsa, sizeof (lsa)))
2357c478bd9Sstevel@tonic-gate 				return (set_errno(EFAULT));
2367c478bd9Sstevel@tonic-gate 		}
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate 		error = lm_svc(&lsa);
2397c478bd9Sstevel@tonic-gate 		break;
2407c478bd9Sstevel@tonic-gate 	}
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	case KILL_LOCKMGR: {
2437c478bd9Sstevel@tonic-gate 		error = lm_shutdown();
2447c478bd9Sstevel@tonic-gate 		break;
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	case LOG_FLUSH:	{	/* Flush log buffer and possibly rename */
2487c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfsl_flush_args, nfa);
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nfa, get_udatamodel());
2517c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nfa), STRUCT_SIZE(nfa)))
2527c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 		error = nfsl_flush(STRUCT_BUF(nfa), get_udatamodel());
2557c478bd9Sstevel@tonic-gate 		break;
2567c478bd9Sstevel@tonic-gate 	}
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	case NFS4_SVC: { /* NFS client callback daemon */
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		STRUCT_DECL(nfs4_svc_args, nsa);
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 		STRUCT_INIT(nsa, get_udatamodel());
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 		if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
2657c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 		error = nfs4_svc(STRUCT_BUF(nsa), get_udatamodel());
2687c478bd9Sstevel@tonic-gate 		break;
2697c478bd9Sstevel@tonic-gate 	}
2707c478bd9Sstevel@tonic-gate 
271cee86682Scalum 	/* Request that NFSv4 server quiesce on next shutdown */
272cee86682Scalum 	case NFS4_SVC_REQUEST_QUIESCE: {
273cee86682Scalum 		int id;
274cee86682Scalum 
275cee86682Scalum 		/* check that nfssrv module is loaded */
276cee86682Scalum 		if (nfs_srv_quiesce_func == NULL)
277cee86682Scalum 			return (set_errno(ENOTSUP));
278cee86682Scalum 
279cee86682Scalum 		if (copyin(arg, &id, sizeof (id)))
280cee86682Scalum 			return (set_errno(EFAULT));
281cee86682Scalum 
282cee86682Scalum 		error = svc_pool_control(id, SVCPSET_SHUTDOWN_PROC,
283cee86682Scalum 		    (void *)nfs_srv_quiesce_func);
284cee86682Scalum 		break;
285cee86682Scalum 	}
286cee86682Scalum 
2877c478bd9Sstevel@tonic-gate 	case NFS_IDMAP: {
2887c478bd9Sstevel@tonic-gate 		struct nfsidmap_args idm;
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 		if (copyin(arg, &idm, sizeof (idm)))
2917c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 		nfs_idmap_args(&idm);
2947c478bd9Sstevel@tonic-gate 		error = 0;
2957c478bd9Sstevel@tonic-gate 		break;
2967c478bd9Sstevel@tonic-gate 	}
2977c478bd9Sstevel@tonic-gate 
298cee86682Scalum 	case NFS4_DSS_SETPATHS_SIZE: {
299cee86682Scalum 		/* crosses ILP32/LP64 boundary */
300cee86682Scalum 		uint32_t nfs4_dss_bufsize = 0;
301cee86682Scalum 
302cee86682Scalum 		if (copyin(arg, &nfs4_dss_bufsize, sizeof (nfs4_dss_bufsize)))
303cee86682Scalum 			return (set_errno(EFAULT));
304cee86682Scalum 		nfs4_dss_buflen = (long)nfs4_dss_bufsize;
305cee86682Scalum 		error = 0;
306cee86682Scalum 		break;
307cee86682Scalum 	}
308cee86682Scalum 
309cee86682Scalum 	case NFS4_DSS_SETPATHS: {
310cee86682Scalum 		char *nfs4_dss_bufp;
311cee86682Scalum 
312cee86682Scalum 		/* check that nfssrv module is loaded */
313cee86682Scalum 		if (nfs_srv_dss_func == NULL)
314cee86682Scalum 			return (set_errno(ENOTSUP));
315cee86682Scalum 
316cee86682Scalum 		/*
317cee86682Scalum 		 * NFS4_DSS_SETPATHS_SIZE must be called before
318cee86682Scalum 		 * NFS4_DSS_SETPATHS, to tell us how big a buffer we need
319cee86682Scalum 		 * to allocate.
320cee86682Scalum 		 */
321cee86682Scalum 		if (nfs4_dss_buflen == 0)
322cee86682Scalum 			return (set_errno(EINVAL));
323cee86682Scalum 		nfs4_dss_bufp = kmem_alloc(nfs4_dss_buflen, KM_SLEEP);
324cee86682Scalum 		if (nfs4_dss_bufp == NULL)
325cee86682Scalum 			return (set_errno(ENOMEM));
326cee86682Scalum 
327cee86682Scalum 		if (copyin(arg, nfs4_dss_bufp, nfs4_dss_buflen)) {
328cee86682Scalum 			kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
329cee86682Scalum 			return (set_errno(EFAULT));
330cee86682Scalum 		}
331cee86682Scalum 
332cee86682Scalum 		/* unpack the buffer and extract the pathnames */
333cee86682Scalum 		error = nfs_srv_dss_func(nfs4_dss_bufp, nfs4_dss_buflen);
334cee86682Scalum 		kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
335cee86682Scalum 
336cee86682Scalum 		break;
337cee86682Scalum 	}
338cee86682Scalum 
339b9238976Sth 	case NFS4_EPHEMERAL_MOUNT_TO: {
340b9238976Sth 		uint_t	mount_to;
341b9238976Sth 
342b9238976Sth 		/*
343b9238976Sth 		 * Not a very complicated call.
344b9238976Sth 		 */
345b9238976Sth 		if (copyin(arg, &mount_to, sizeof (mount_to)))
346b9238976Sth 			return (set_errno(EFAULT));
347b9238976Sth 		nfs4_ephemeral_set_mount_to(mount_to);
348b9238976Sth 		error = 0;
349b9238976Sth 		break;
350b9238976Sth 	}
351b9238976Sth 
3521cc55349Srmesta 	case MOUNTD_ARGS: {
3531cc55349Srmesta 		uint_t	did;
3541cc55349Srmesta 
3551cc55349Srmesta 		/*
3561cc55349Srmesta 		 * For now, only passing down the door fd; if we
3571cc55349Srmesta 		 * ever need to pass down more info, we can use
3581cc55349Srmesta 		 * a (properly aligned) struct.
3591cc55349Srmesta 		 */
3601cc55349Srmesta 		if (copyin(arg, &did, sizeof (did)))
3611cc55349Srmesta 			return (set_errno(EFAULT));
3621cc55349Srmesta 		mountd_args(did);
3631cc55349Srmesta 		error = 0;
3641cc55349Srmesta 		break;
3651cc55349Srmesta 	}
3661cc55349Srmesta 
367b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case NFSCMD_ARGS: {
368b89a8333Snatalie li - Sun Microsystems - Irvine United States 		uint_t	did;
369b89a8333Snatalie li - Sun Microsystems - Irvine United States 
370b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/*
371b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * For now, only passing down the door fd; if we
372b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * ever need to pass down more info, we can use
373b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * a (properly aligned) struct.
374b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 */
375b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (copyin(arg, &did, sizeof (did)))
376b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (set_errno(EFAULT));
377b89a8333Snatalie li - Sun Microsystems - Irvine United States 		nfscmd_args(did);
378b89a8333Snatalie li - Sun Microsystems - Irvine United States 		error = 0;
379b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
380b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
381b89a8333Snatalie li - Sun Microsystems - Irvine United States 
3827c478bd9Sstevel@tonic-gate 	default:
3837c478bd9Sstevel@tonic-gate 		error = EINVAL;
3847c478bd9Sstevel@tonic-gate 		break;
3857c478bd9Sstevel@tonic-gate 	}
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	return ((error != 0) ? set_errno(error) : 0);
3887c478bd9Sstevel@tonic-gate }
389