xref: /freebsd/sys/fs/nfsclient/nfs_clvfsops.c (revision 410556f1f10fd35b350102725fd8504c3cb0afc8)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1989, 1993, 1995
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Rick Macklem at The University of Guelph.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	from nfs_vfsops.c	8.12 (Berkeley) 5/20/95
35  */
36 
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39 
40 #include "opt_bootp.h"
41 #include "opt_nfsroot.h"
42 #include "opt_kern_tls.h"
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/bio.h>
48 #include <sys/buf.h>
49 #include <sys/clock.h>
50 #include <sys/jail.h>
51 #include <sys/limits.h>
52 #include <sys/lock.h>
53 #include <sys/malloc.h>
54 #include <sys/mbuf.h>
55 #include <sys/module.h>
56 #include <sys/mount.h>
57 #include <sys/proc.h>
58 #include <sys/socket.h>
59 #include <sys/socketvar.h>
60 #include <sys/sockio.h>
61 #include <sys/sysctl.h>
62 #include <sys/vnode.h>
63 #include <sys/signalvar.h>
64 
65 #include <vm/vm.h>
66 #include <vm/vm_extern.h>
67 #include <vm/uma.h>
68 
69 #include <net/if.h>
70 #include <net/route.h>
71 #include <net/route/route_ctl.h>
72 #include <netinet/in.h>
73 
74 #include <fs/nfs/nfsport.h>
75 #include <fs/nfsclient/nfsnode.h>
76 #include <fs/nfsclient/nfsmount.h>
77 #include <fs/nfsclient/nfs.h>
78 #include <nfs/nfsdiskless.h>
79 
80 #include <rpc/rpcsec_tls.h>
81 
82 FEATURE(nfscl, "NFSv4 client");
83 
84 extern int nfscl_ticks;
85 extern struct timeval nfsboottime;
86 extern int nfsrv_useacl;
87 extern int nfscl_debuglevel;
88 extern enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON];
89 extern struct nfsmount *ncl_iodmount[NFS_MAXASYNCDAEMON];
90 extern struct mtx ncl_iod_mutex;
91 NFSCLSTATEMUTEX;
92 extern struct mtx nfsrv_dslock_mtx;
93 
94 MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "NFS request header");
95 MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "NFS mount struct");
96 
97 SYSCTL_DECL(_vfs_nfs);
98 static int nfs_ip_paranoia = 1;
99 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
100     &nfs_ip_paranoia, 0, "");
101 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
102 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
103         downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
104 /* how long between console messages "nfs server foo not responding" */
105 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
106 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
107         downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
108 #ifdef NFS_DEBUG
109 int nfs_debug;
110 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
111     "Toggle debug flag");
112 #endif
113 
114 static int	nfs_mountroot(struct mount *);
115 static void	nfs_sec_name(char *, int *);
116 static void	nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
117 		    struct nfs_args *argp, const char *, struct ucred *,
118 		    struct thread *);
119 static int	mountnfs(struct nfs_args *, struct mount *,
120 		    struct sockaddr *, char *, u_char *, int, u_char *, int,
121 		    u_char *, int, struct vnode **, struct ucred *,
122 		    struct thread *, int, int, int, uint32_t, char *);
123 static void	nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
124 		    struct sockaddr_storage *, int *, off_t *,
125 		    struct timeval *);
126 static vfs_mount_t nfs_mount;
127 static vfs_cmount_t nfs_cmount;
128 static vfs_unmount_t nfs_unmount;
129 static vfs_root_t nfs_root;
130 static vfs_statfs_t nfs_statfs;
131 static vfs_sync_t nfs_sync;
132 static vfs_sysctl_t nfs_sysctl;
133 static vfs_purge_t nfs_purge;
134 
135 /*
136  * nfs vfs operations.
137  */
138 static struct vfsops nfs_vfsops = {
139 	.vfs_init =		ncl_init,
140 	.vfs_mount =		nfs_mount,
141 	.vfs_cmount =		nfs_cmount,
142 	.vfs_root =		vfs_cache_root,
143 	.vfs_cachedroot =	nfs_root,
144 	.vfs_statfs =		nfs_statfs,
145 	.vfs_sync =		nfs_sync,
146 	.vfs_uninit =		ncl_uninit,
147 	.vfs_unmount =		nfs_unmount,
148 	.vfs_sysctl =		nfs_sysctl,
149 	.vfs_purge =		nfs_purge,
150 };
151 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY);
152 
153 /* So that loader and kldload(2) can find us, wherever we are.. */
154 MODULE_VERSION(nfs, 1);
155 MODULE_DEPEND(nfs, nfscommon, 1, 1, 1);
156 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
157 MODULE_DEPEND(nfs, nfssvc, 1, 1, 1);
158 
159 /*
160  * This structure is now defined in sys/nfs/nfs_diskless.c so that it
161  * can be shared by both NFS clients. It is declared here so that it
162  * will be defined for kernels built without NFS_ROOT, although it
163  * isn't used in that case.
164  */
165 #if !defined(NFS_ROOT)
166 struct nfs_diskless	nfs_diskless = { { { 0 } } };
167 struct nfsv3_diskless	nfsv3_diskless = { { { 0 } } };
168 int			nfs_diskless_valid = 0;
169 #endif
170 
171 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
172     &nfs_diskless_valid, 0,
173     "Has the diskless struct been filled correctly");
174 
175 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
176     nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
177 
178 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
179     &nfsv3_diskless.root_saddr, sizeof(nfsv3_diskless.root_saddr),
180     "%Ssockaddr_in", "Diskless root nfs address");
181 
182 void		newnfsargs_ntoh(struct nfs_args *);
183 static int	nfs_mountdiskless(char *,
184 		    struct sockaddr_in *, struct nfs_args *,
185 		    struct thread *, struct vnode **, struct mount *);
186 static void	nfs_convert_diskless(void);
187 static void	nfs_convert_oargs(struct nfs_args *args,
188 		    struct onfs_args *oargs);
189 
190 int
191 newnfs_iosize(struct nfsmount *nmp)
192 {
193 	int iosize, maxio;
194 
195 	/* First, set the upper limit for iosize */
196 	if (nmp->nm_flag & NFSMNT_NFSV4) {
197 		maxio = NFS_MAXBSIZE;
198 	} else if (nmp->nm_flag & NFSMNT_NFSV3) {
199 		if (nmp->nm_sotype == SOCK_DGRAM)
200 			maxio = NFS_MAXDGRAMDATA;
201 		else
202 			maxio = NFS_MAXBSIZE;
203 	} else {
204 		maxio = NFS_V2MAXDATA;
205 	}
206 	if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
207 		nmp->nm_rsize = maxio;
208 	if (nmp->nm_rsize > NFS_MAXBSIZE)
209 		nmp->nm_rsize = NFS_MAXBSIZE;
210 	if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
211 		nmp->nm_readdirsize = maxio;
212 	if (nmp->nm_readdirsize > nmp->nm_rsize)
213 		nmp->nm_readdirsize = nmp->nm_rsize;
214 	if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
215 		nmp->nm_wsize = maxio;
216 	if (nmp->nm_wsize > NFS_MAXBSIZE)
217 		nmp->nm_wsize = NFS_MAXBSIZE;
218 
219 	/*
220 	 * Calculate the size used for io buffers.  Use the larger
221 	 * of the two sizes to minimise nfs requests but make sure
222 	 * that it is at least one VM page to avoid wasting buffer
223 	 * space.  It must also be at least NFS_DIRBLKSIZ, since
224 	 * that is the buffer size used for directories.
225 	 */
226 	iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
227 	iosize = imax(iosize, PAGE_SIZE);
228 	iosize = imax(iosize, NFS_DIRBLKSIZ);
229 	nmp->nm_mountp->mnt_stat.f_iosize = iosize;
230 	return (iosize);
231 }
232 
233 static void
234 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
235 {
236 
237 	args->version = NFS_ARGSVERSION;
238 	args->addr = oargs->addr;
239 	args->addrlen = oargs->addrlen;
240 	args->sotype = oargs->sotype;
241 	args->proto = oargs->proto;
242 	args->fh = oargs->fh;
243 	args->fhsize = oargs->fhsize;
244 	args->flags = oargs->flags;
245 	args->wsize = oargs->wsize;
246 	args->rsize = oargs->rsize;
247 	args->readdirsize = oargs->readdirsize;
248 	args->timeo = oargs->timeo;
249 	args->retrans = oargs->retrans;
250 	args->readahead = oargs->readahead;
251 	args->hostname = oargs->hostname;
252 }
253 
254 static void
255 nfs_convert_diskless(void)
256 {
257 
258 	bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
259 		sizeof(struct ifaliasreq));
260 	bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
261 		sizeof(struct sockaddr_in));
262 	nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
263 	if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
264 		nfsv3_diskless.root_fhsize = NFSX_MYFH;
265 		bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_MYFH);
266 	} else {
267 		nfsv3_diskless.root_fhsize = NFSX_V2FH;
268 		bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
269 	}
270 	bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
271 		sizeof(struct sockaddr_in));
272 	bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
273 	nfsv3_diskless.root_time = nfs_diskless.root_time;
274 	bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
275 		MAXHOSTNAMELEN);
276 	nfs_diskless_valid = 3;
277 }
278 
279 /*
280  * nfs statfs call
281  */
282 static int
283 nfs_statfs(struct mount *mp, struct statfs *sbp)
284 {
285 	struct vnode *vp;
286 	struct thread *td;
287 	struct nfsmount *nmp = VFSTONFS(mp);
288 	struct nfsvattr nfsva;
289 	struct nfsfsinfo fs;
290 	struct nfsstatfs sb;
291 	int error = 0, attrflag, gotfsinfo = 0, ret;
292 	struct nfsnode *np;
293 
294 	td = curthread;
295 
296 	error = vfs_busy(mp, MBF_NOWAIT);
297 	if (error)
298 		return (error);
299 	error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
300 	if (error) {
301 		vfs_unbusy(mp);
302 		return (error);
303 	}
304 	vp = NFSTOV(np);
305 	mtx_lock(&nmp->nm_mtx);
306 	if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
307 		mtx_unlock(&nmp->nm_mtx);
308 		error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
309 		    &attrflag, NULL);
310 		if (!error)
311 			gotfsinfo = 1;
312 	} else
313 		mtx_unlock(&nmp->nm_mtx);
314 	if (!error)
315 		error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
316 		    &attrflag, NULL);
317 	if (error != 0)
318 		NFSCL_DEBUG(2, "statfs=%d\n", error);
319 	if (attrflag == 0) {
320 		ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
321 		    td->td_ucred, td, &nfsva, NULL, NULL);
322 		if (ret) {
323 			/*
324 			 * Just set default values to get things going.
325 			 */
326 			NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
327 			nfsva.na_vattr.va_type = VDIR;
328 			nfsva.na_vattr.va_mode = 0777;
329 			nfsva.na_vattr.va_nlink = 100;
330 			nfsva.na_vattr.va_uid = (uid_t)0;
331 			nfsva.na_vattr.va_gid = (gid_t)0;
332 			nfsva.na_vattr.va_fileid = 2;
333 			nfsva.na_vattr.va_gen = 1;
334 			nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
335 			nfsva.na_vattr.va_size = 512 * 1024;
336 		}
337 	}
338 	(void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
339 	if (!error) {
340 	    mtx_lock(&nmp->nm_mtx);
341 	    if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
342 		nfscl_loadfsinfo(nmp, &fs);
343 	    nfscl_loadsbinfo(nmp, &sb, sbp);
344 	    sbp->f_iosize = newnfs_iosize(nmp);
345 	    mtx_unlock(&nmp->nm_mtx);
346 	    if (sbp != &mp->mnt_stat) {
347 		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
348 		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
349 	    }
350 	    strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
351 	} else if (NFS_ISV4(vp)) {
352 		error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
353 	}
354 	vput(vp);
355 	vfs_unbusy(mp);
356 	return (error);
357 }
358 
359 /*
360  * nfs version 3 fsinfo rpc call
361  */
362 int
363 ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
364     struct thread *td)
365 {
366 	struct nfsfsinfo fs;
367 	struct nfsvattr nfsva;
368 	int error, attrflag;
369 
370 	error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
371 	if (!error) {
372 		if (attrflag)
373 			(void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
374 			    1);
375 		mtx_lock(&nmp->nm_mtx);
376 		nfscl_loadfsinfo(nmp, &fs);
377 		mtx_unlock(&nmp->nm_mtx);
378 	}
379 	return (error);
380 }
381 
382 /*
383  * Mount a remote root fs via. nfs. This depends on the info in the
384  * nfs_diskless structure that has been filled in properly by some primary
385  * bootstrap.
386  * It goes something like this:
387  * - do enough of "ifconfig" by calling ifioctl() so that the system
388  *   can talk to the server
389  * - If nfs_diskless.mygateway is filled in, use that address as
390  *   a default gateway.
391  * - build the rootfs mount point and call mountnfs() to do the rest.
392  *
393  * It is assumed to be safe to read, modify, and write the nfsv3_diskless
394  * structure, as well as other global NFS client variables here, as
395  * nfs_mountroot() will be called once in the boot before any other NFS
396  * client activity occurs.
397  */
398 static int
399 nfs_mountroot(struct mount *mp)
400 {
401 	struct thread *td = curthread;
402 	struct nfsv3_diskless *nd = &nfsv3_diskless;
403 	struct socket *so;
404 	struct vnode *vp;
405 	struct ifreq ir;
406 	int error;
407 	u_long l;
408 	char buf[128];
409 	char *cp;
410 
411 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
412 	bootpc_init();		/* use bootp to get nfs_diskless filled in */
413 #elif defined(NFS_ROOT)
414 	nfs_setup_diskless();
415 #endif
416 
417 	if (nfs_diskless_valid == 0)
418 		return (-1);
419 	if (nfs_diskless_valid == 1)
420 		nfs_convert_diskless();
421 
422 	/*
423 	 * Do enough of ifconfig(8) so that the critical net interface can
424 	 * talk to the server.
425 	 */
426 	error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
427 	    td->td_ucred, td);
428 	if (error)
429 		panic("nfs_mountroot: socreate(%04x): %d",
430 			nd->myif.ifra_addr.sa_family, error);
431 
432 #if 0 /* XXX Bad idea */
433 	/*
434 	 * We might not have been told the right interface, so we pass
435 	 * over the first ten interfaces of the same kind, until we get
436 	 * one of them configured.
437 	 */
438 
439 	for (i = strlen(nd->myif.ifra_name) - 1;
440 		nd->myif.ifra_name[i] >= '0' &&
441 		nd->myif.ifra_name[i] <= '9';
442 		nd->myif.ifra_name[i] ++) {
443 		error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
444 		if(!error)
445 			break;
446 	}
447 #endif
448 	error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
449 	if (error)
450 		panic("nfs_mountroot: SIOCAIFADDR: %d", error);
451 	if ((cp = kern_getenv("boot.netif.mtu")) != NULL) {
452 		ir.ifr_mtu = strtol(cp, NULL, 10);
453 		bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
454 		freeenv(cp);
455 		error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
456 		if (error)
457 			printf("nfs_mountroot: SIOCSIFMTU: %d", error);
458 	}
459 	soclose(so);
460 
461 	/*
462 	 * If the gateway field is filled in, set it as the default route.
463 	 * Note that pxeboot will set a default route of 0 if the route
464 	 * is not set by the DHCP server.  Check also for a value of 0
465 	 * to avoid panicking inappropriately in that situation.
466 	 */
467 	if (nd->mygateway.sin_len != 0 &&
468 	    nd->mygateway.sin_addr.s_addr != 0) {
469 		struct sockaddr_in mask, sin;
470 		struct epoch_tracker et;
471 		struct rt_addrinfo info;
472 		struct rib_cmd_info rc;
473 
474 		bzero((caddr_t)&mask, sizeof(mask));
475 		sin = mask;
476 		sin.sin_family = AF_INET;
477 		sin.sin_len = sizeof(sin);
478                 /* XXX MRT use table 0 for this sort of thing */
479 		NET_EPOCH_ENTER(et);
480 		CURVNET_SET(TD_TO_VNET(td));
481 
482 		bzero((caddr_t)&info, sizeof(info));
483 		info.rti_flags = RTF_UP | RTF_GATEWAY;
484 		info.rti_info[RTAX_DST] = (struct sockaddr *)&sin;
485 		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&nd->mygateway;
486 		info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask;
487 
488 		error = rib_action(RT_DEFAULT_FIB, RTM_ADD, &info, &rc);
489 		CURVNET_RESTORE();
490 		NET_EPOCH_EXIT(et);
491 		if (error)
492 			panic("nfs_mountroot: RTM_ADD: %d", error);
493 	}
494 
495 	/*
496 	 * Create the rootfs mount point.
497 	 */
498 	nd->root_args.fh = nd->root_fh;
499 	nd->root_args.fhsize = nd->root_fhsize;
500 	l = ntohl(nd->root_saddr.sin_addr.s_addr);
501 	snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
502 		(l >> 24) & 0xff, (l >> 16) & 0xff,
503 		(l >>  8) & 0xff, (l >>  0) & 0xff, nd->root_hostnam);
504 	printf("NFS ROOT: %s\n", buf);
505 	nd->root_args.hostname = buf;
506 	if ((error = nfs_mountdiskless(buf,
507 	    &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
508 		return (error);
509 	}
510 
511 	/*
512 	 * This is not really an nfs issue, but it is much easier to
513 	 * set hostname here and then let the "/etc/rc.xxx" files
514 	 * mount the right /var based upon its preset value.
515 	 */
516 	mtx_lock(&prison0.pr_mtx);
517 	strlcpy(prison0.pr_hostname, nd->my_hostnam,
518 	    sizeof(prison0.pr_hostname));
519 	mtx_unlock(&prison0.pr_mtx);
520 	inittodr(ntohl(nd->root_time));
521 	return (0);
522 }
523 
524 /*
525  * Internal version of mount system call for diskless setup.
526  */
527 static int
528 nfs_mountdiskless(char *path,
529     struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
530     struct vnode **vpp, struct mount *mp)
531 {
532 	struct sockaddr *nam;
533 	int dirlen, error;
534 	char *dirpath;
535 
536 	/*
537 	 * Find the directory path in "path", which also has the server's
538 	 * name/ip address in it.
539 	 */
540 	dirpath = strchr(path, ':');
541 	if (dirpath != NULL)
542 		dirlen = strlen(++dirpath);
543 	else
544 		dirlen = 0;
545 	nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
546 	if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
547 	    NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
548 	    NFS_DEFAULT_NEGNAMETIMEO, 0, 0, NULL)) != 0) {
549 		printf("nfs_mountroot: mount %s on /: %d\n", path, error);
550 		return (error);
551 	}
552 	return (0);
553 }
554 
555 static void
556 nfs_sec_name(char *sec, int *flagsp)
557 {
558 	if (!strcmp(sec, "krb5"))
559 		*flagsp |= NFSMNT_KERB;
560 	else if (!strcmp(sec, "krb5i"))
561 		*flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
562 	else if (!strcmp(sec, "krb5p"))
563 		*flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
564 }
565 
566 static void
567 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
568     const char *hostname, struct ucred *cred, struct thread *td)
569 {
570 	int adjsock;
571 	char *p;
572 
573 	/*
574 	 * Set read-only flag if requested; otherwise, clear it if this is
575 	 * an update.  If this is not an update, then either the read-only
576 	 * flag is already clear, or this is a root mount and it was set
577 	 * intentionally at some previous point.
578 	 */
579 	if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
580 		MNT_ILOCK(mp);
581 		mp->mnt_flag |= MNT_RDONLY;
582 		MNT_IUNLOCK(mp);
583 	} else if (mp->mnt_flag & MNT_UPDATE) {
584 		MNT_ILOCK(mp);
585 		mp->mnt_flag &= ~MNT_RDONLY;
586 		MNT_IUNLOCK(mp);
587 	}
588 
589 	/*
590 	 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
591 	 * no sense in that context.  Also, set up appropriate retransmit
592 	 * and soft timeout behavior.
593 	 */
594 	if (argp->sotype == SOCK_STREAM) {
595 		nmp->nm_flag &= ~NFSMNT_NOCONN;
596 		nmp->nm_timeo = NFS_MAXTIMEO;
597 		if ((argp->flags & NFSMNT_NFSV4) != 0)
598 			nmp->nm_retry = INT_MAX;
599 		else
600 			nmp->nm_retry = NFS_RETRANS_TCP;
601 	}
602 
603 	/* Also clear RDIRPLUS if NFSv2, it crashes some servers */
604 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
605 		argp->flags &= ~NFSMNT_RDIRPLUS;
606 		nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
607 	}
608 
609 	/* Clear ONEOPENOWN for NFSv2, 3 and 4.0. */
610 	if (nmp->nm_minorvers == 0) {
611 		argp->flags &= ~NFSMNT_ONEOPENOWN;
612 		nmp->nm_flag &= ~NFSMNT_ONEOPENOWN;
613 	}
614 
615 	/* Re-bind if rsrvd port requested and wasn't on one */
616 	adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
617 		  && (argp->flags & NFSMNT_RESVPORT);
618 	/* Also re-bind if we're switching to/from a connected UDP socket */
619 	adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
620 		    (argp->flags & NFSMNT_NOCONN));
621 
622 	/* Update flags atomically.  Don't change the lock bits. */
623 	nmp->nm_flag = argp->flags | nmp->nm_flag;
624 
625 	if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
626 		nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
627 		if (nmp->nm_timeo < NFS_MINTIMEO)
628 			nmp->nm_timeo = NFS_MINTIMEO;
629 		else if (nmp->nm_timeo > NFS_MAXTIMEO)
630 			nmp->nm_timeo = NFS_MAXTIMEO;
631 	}
632 
633 	if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
634 		nmp->nm_retry = argp->retrans;
635 		if (nmp->nm_retry > NFS_MAXREXMIT)
636 			nmp->nm_retry = NFS_MAXREXMIT;
637 	}
638 
639 	if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
640 		nmp->nm_wsize = argp->wsize;
641 		/*
642 		 * Clip at the power of 2 below the size. There is an
643 		 * issue (not isolated) that causes intermittent page
644 		 * faults if this is not done.
645 		 */
646 		if (nmp->nm_wsize > NFS_FABLKSIZE)
647 			nmp->nm_wsize = 1 << (fls(nmp->nm_wsize) - 1);
648 		else
649 			nmp->nm_wsize = NFS_FABLKSIZE;
650 	}
651 
652 	if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
653 		nmp->nm_rsize = argp->rsize;
654 		/*
655 		 * Clip at the power of 2 below the size. There is an
656 		 * issue (not isolated) that causes intermittent page
657 		 * faults if this is not done.
658 		 */
659 		if (nmp->nm_rsize > NFS_FABLKSIZE)
660 			nmp->nm_rsize = 1 << (fls(nmp->nm_rsize) - 1);
661 		else
662 			nmp->nm_rsize = NFS_FABLKSIZE;
663 	}
664 
665 	if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
666 		nmp->nm_readdirsize = argp->readdirsize;
667 	}
668 
669 	if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
670 		nmp->nm_acregmin = argp->acregmin;
671 	else
672 		nmp->nm_acregmin = NFS_MINATTRTIMO;
673 	if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
674 		nmp->nm_acregmax = argp->acregmax;
675 	else
676 		nmp->nm_acregmax = NFS_MAXATTRTIMO;
677 	if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
678 		nmp->nm_acdirmin = argp->acdirmin;
679 	else
680 		nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
681 	if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
682 		nmp->nm_acdirmax = argp->acdirmax;
683 	else
684 		nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
685 	if (nmp->nm_acdirmin > nmp->nm_acdirmax)
686 		nmp->nm_acdirmin = nmp->nm_acdirmax;
687 	if (nmp->nm_acregmin > nmp->nm_acregmax)
688 		nmp->nm_acregmin = nmp->nm_acregmax;
689 
690 	if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
691 		if (argp->readahead <= NFS_MAXRAHEAD)
692 			nmp->nm_readahead = argp->readahead;
693 		else
694 			nmp->nm_readahead = NFS_MAXRAHEAD;
695 	}
696 	if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
697 		if (argp->wcommitsize < nmp->nm_wsize)
698 			nmp->nm_wcommitsize = nmp->nm_wsize;
699 		else
700 			nmp->nm_wcommitsize = argp->wcommitsize;
701 	}
702 
703 	adjsock |= ((nmp->nm_sotype != argp->sotype) ||
704 		    (nmp->nm_soproto != argp->proto));
705 
706 	if (nmp->nm_client != NULL && adjsock) {
707 		int haslock = 0, error = 0;
708 
709 		if (nmp->nm_sotype == SOCK_STREAM) {
710 			error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
711 			if (!error)
712 				haslock = 1;
713 		}
714 		if (!error) {
715 		    newnfs_disconnect(&nmp->nm_sockreq);
716 		    if (haslock)
717 			newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
718 		    nmp->nm_sotype = argp->sotype;
719 		    nmp->nm_soproto = argp->proto;
720 		    if (nmp->nm_sotype == SOCK_DGRAM)
721 			while (newnfs_connect(nmp, &nmp->nm_sockreq,
722 			    cred, td, 0, false)) {
723 				printf("newnfs_args: retrying connect\n");
724 				(void) nfs_catnap(PSOCK, 0, "nfscon");
725 			}
726 		}
727 	} else {
728 		nmp->nm_sotype = argp->sotype;
729 		nmp->nm_soproto = argp->proto;
730 	}
731 
732 	if (hostname != NULL) {
733 		strlcpy(nmp->nm_hostname, hostname,
734 		    sizeof(nmp->nm_hostname));
735 		p = strchr(nmp->nm_hostname, ':');
736 		if (p != NULL)
737 			*p = '\0';
738 	}
739 }
740 
741 static const char *nfs_opts[] = { "from", "nfs_args",
742     "noac", "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
743     "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
744     "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
745     "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
746     "retrans", "actimeo", "acregmin", "acregmax", "acdirmin", "acdirmax",
747     "resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh",
748     "nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath",
749     "minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr",
750     "pnfs", "wcommitsize", "oneopenown", "tls", "tlscertname",
751     NULL };
752 
753 /*
754  * Parse the "from" mountarg, passed by the generic mount(8) program
755  * or the mountroot code.  This is used when rerooting into NFS.
756  *
757  * Note that the "hostname" is actually a "hostname:/share/path" string.
758  */
759 static int
760 nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep,
761     struct sockaddr_in **sinp, char *dirpath, size_t dirpathsize, int *dirlenp)
762 {
763 	char *nam, *delimp, *hostp, *spec;
764 	int error, have_bracket = 0, offset, rv, speclen;
765 	struct sockaddr_in *sin;
766 	size_t len;
767 
768 	error = vfs_getopt(opts, "from", (void **)&spec, &speclen);
769 	if (error != 0)
770 		return (error);
771 	nam = malloc(MNAMELEN + 1, M_TEMP, M_WAITOK);
772 
773 	/*
774 	 * This part comes from sbin/mount_nfs/mount_nfs.c:getnfsargs().
775 	 */
776 	if (*spec == '[' && (delimp = strchr(spec + 1, ']')) != NULL &&
777 	    *(delimp + 1) == ':') {
778 		hostp = spec + 1;
779 		spec = delimp + 2;
780 		have_bracket = 1;
781 	} else if ((delimp = strrchr(spec, ':')) != NULL) {
782 		hostp = spec;
783 		spec = delimp + 1;
784 	} else if ((delimp = strrchr(spec, '@')) != NULL) {
785 		printf("%s: path@server syntax is deprecated, "
786 		    "use server:path\n", __func__);
787 		hostp = delimp + 1;
788 	} else {
789 		printf("%s: no <host>:<dirpath> nfs-name\n", __func__);
790 		free(nam, M_TEMP);
791 		return (EINVAL);
792 	}
793 	*delimp = '\0';
794 
795 	/*
796 	 * If there has been a trailing slash at mounttime it seems
797 	 * that some mountd implementations fail to remove the mount
798 	 * entries from their mountlist while unmounting.
799 	 */
800 	for (speclen = strlen(spec);
801 	    speclen > 1 && spec[speclen - 1] == '/';
802 	    speclen--)
803 		spec[speclen - 1] = '\0';
804 	if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) {
805 		printf("%s: %s:%s: name too long", __func__, hostp, spec);
806 		free(nam, M_TEMP);
807 		return (EINVAL);
808 	}
809 	/* Make both '@' and ':' notations equal */
810 	if (*hostp != '\0') {
811 		len = strlen(hostp);
812 		offset = 0;
813 		if (have_bracket)
814 			nam[offset++] = '[';
815 		memmove(nam + offset, hostp, len);
816 		if (have_bracket)
817 			nam[len + offset++] = ']';
818 		nam[len + offset++] = ':';
819 		memmove(nam + len + offset, spec, speclen);
820 		nam[len + speclen + offset] = '\0';
821 	} else
822 		nam[0] = '\0';
823 
824 	/*
825 	 * XXX: IPv6
826 	 */
827 	sin = malloc(sizeof(*sin), M_SONAME, M_WAITOK);
828 	rv = inet_pton(AF_INET, hostp, &sin->sin_addr);
829 	if (rv != 1) {
830 		printf("%s: cannot parse '%s', inet_pton() returned %d\n",
831 		    __func__, hostp, rv);
832 		free(nam, M_TEMP);
833 		free(sin, M_SONAME);
834 		return (EINVAL);
835 	}
836 
837 	sin->sin_len = sizeof(*sin);
838 	sin->sin_family = AF_INET;
839 	/*
840 	 * XXX: hardcoded port number.
841 	 */
842 	sin->sin_port = htons(2049);
843 
844 	*hostnamep = strdup(nam, M_NEWNFSMNT);
845 	*sinp = sin;
846 	strlcpy(dirpath, spec, dirpathsize);
847 	*dirlenp = strlen(dirpath);
848 
849 	free(nam, M_TEMP);
850 	return (0);
851 }
852 
853 /*
854  * VFS Operations.
855  *
856  * mount system call
857  * It seems a bit dumb to copyinstr() the host and path here and then
858  * bcopy() them in mountnfs(), but I wanted to detect errors before
859  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
860  * an error after that means that I have to release the mbuf.
861  */
862 /* ARGSUSED */
863 static int
864 nfs_mount(struct mount *mp)
865 {
866 	struct nfs_args args = {
867 	    .version = NFS_ARGSVERSION,
868 	    .addr = NULL,
869 	    .addrlen = sizeof (struct sockaddr_in),
870 	    .sotype = SOCK_STREAM,
871 	    .proto = 0,
872 	    .fh = NULL,
873 	    .fhsize = 0,
874 	    .flags = NFSMNT_RESVPORT,
875 	    .wsize = NFS_WSIZE,
876 	    .rsize = NFS_RSIZE,
877 	    .readdirsize = NFS_READDIRSIZE,
878 	    .timeo = 10,
879 	    .retrans = NFS_RETRANS,
880 	    .readahead = NFS_DEFRAHEAD,
881 	    .wcommitsize = 0,			/* was: NQ_DEFLEASE */
882 	    .hostname = NULL,
883 	    .acregmin = NFS_MINATTRTIMO,
884 	    .acregmax = NFS_MAXATTRTIMO,
885 	    .acdirmin = NFS_MINDIRATTRTIMO,
886 	    .acdirmax = NFS_MAXDIRATTRTIMO,
887 	};
888 	int error = 0, ret, len;
889 	struct sockaddr *nam = NULL;
890 	struct vnode *vp;
891 	struct thread *td;
892 	char *hst;
893 	u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
894 	char *cp, *opt, *name, *secname, *tlscertname;
895 	int nametimeo = NFS_DEFAULT_NAMETIMEO;
896 	int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
897 	int minvers = 0;
898 	int dirlen, has_nfs_args_opt, has_nfs_from_opt,
899 	    krbnamelen, srvkrbnamelen;
900 	size_t hstlen;
901 	uint32_t newflag;
902 
903 	has_nfs_args_opt = 0;
904 	has_nfs_from_opt = 0;
905 	newflag = 0;
906 	tlscertname = NULL;
907 	hst = malloc(MNAMELEN, M_TEMP, M_WAITOK);
908 	if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
909 		error = EINVAL;
910 		goto out;
911 	}
912 
913 	td = curthread;
914 	if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS &&
915 	    nfs_diskless_valid != 0) {
916 		error = nfs_mountroot(mp);
917 		goto out;
918 	}
919 
920 	nfscl_init();
921 
922 	/*
923 	 * The old mount_nfs program passed the struct nfs_args
924 	 * from userspace to kernel.  The new mount_nfs program
925 	 * passes string options via nmount() from userspace to kernel
926 	 * and we populate the struct nfs_args in the kernel.
927 	 */
928 	if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
929 		error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
930 		    sizeof(args));
931 		if (error != 0)
932 			goto out;
933 
934 		if (args.version != NFS_ARGSVERSION) {
935 			error = EPROGMISMATCH;
936 			goto out;
937 		}
938 		has_nfs_args_opt = 1;
939 	}
940 
941 	/* Handle the new style options. */
942 	if (vfs_getopt(mp->mnt_optnew, "noac", NULL, NULL) == 0) {
943 		args.acdirmin = args.acdirmax =
944 		    args.acregmin = args.acregmax = 0;
945 		args.flags |= NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX |
946 		    NFSMNT_ACREGMIN | NFSMNT_ACREGMAX;
947 	}
948 	if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
949 		args.flags |= NFSMNT_NOCONN;
950 	if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
951 		args.flags &= ~NFSMNT_NOCONN;
952 	if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
953 		args.flags |= NFSMNT_NOLOCKD;
954 	if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
955 		args.flags &= ~NFSMNT_NOLOCKD;
956 	if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
957 		args.flags |= NFSMNT_INT;
958 	if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
959 		args.flags |= NFSMNT_RDIRPLUS;
960 	if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
961 		args.flags |= NFSMNT_RESVPORT;
962 	if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
963 		args.flags &= ~NFSMNT_RESVPORT;
964 	if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
965 		args.flags |= NFSMNT_SOFT;
966 	if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
967 		args.flags &= ~NFSMNT_SOFT;
968 	if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
969 		args.sotype = SOCK_DGRAM;
970 	if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
971 		args.sotype = SOCK_DGRAM;
972 	if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
973 		args.sotype = SOCK_STREAM;
974 	if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
975 		args.flags |= NFSMNT_NFSV3;
976 	if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
977 		args.flags |= NFSMNT_NFSV4;
978 		args.sotype = SOCK_STREAM;
979 	}
980 	if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
981 		args.flags |= NFSMNT_ALLGSSNAME;
982 	if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
983 		args.flags |= NFSMNT_NOCTO;
984 	if (vfs_getopt(mp->mnt_optnew, "noncontigwr", NULL, NULL) == 0)
985 		args.flags |= NFSMNT_NONCONTIGWR;
986 	if (vfs_getopt(mp->mnt_optnew, "pnfs", NULL, NULL) == 0)
987 		args.flags |= NFSMNT_PNFS;
988 	if (vfs_getopt(mp->mnt_optnew, "oneopenown", NULL, NULL) == 0)
989 		args.flags |= NFSMNT_ONEOPENOWN;
990 	if (vfs_getopt(mp->mnt_optnew, "tls", NULL, NULL) == 0)
991 		newflag |= NFSMNT_TLS;
992 	if (vfs_getopt(mp->mnt_optnew, "tlscertname", (void **)&opt, &len) ==
993 	    0) {
994 		/*
995 		 * tlscertname with "key.pem" appended to it forms a file
996 		 * name.  As such, the maximum allowable strlen(tlscertname) is
997 		 * NAME_MAX - 7. However, "len" includes the nul termination
998 		 * byte so it can be up to NAME_MAX - 6.
999 		 */
1000 		if (opt == NULL || len <= 1 || len > NAME_MAX - 6) {
1001 			vfs_mount_error(mp, "invalid tlscertname");
1002 			error = EINVAL;
1003 			goto out;
1004 		}
1005 		tlscertname = malloc(len, M_NEWNFSMNT, M_WAITOK);
1006 		strlcpy(tlscertname, opt, len);
1007 	}
1008 	if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
1009 		if (opt == NULL) {
1010 			vfs_mount_error(mp, "illegal readdirsize");
1011 			error = EINVAL;
1012 			goto out;
1013 		}
1014 		ret = sscanf(opt, "%d", &args.readdirsize);
1015 		if (ret != 1 || args.readdirsize <= 0) {
1016 			vfs_mount_error(mp, "illegal readdirsize: %s",
1017 			    opt);
1018 			error = EINVAL;
1019 			goto out;
1020 		}
1021 		args.flags |= NFSMNT_READDIRSIZE;
1022 	}
1023 	if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
1024 		if (opt == NULL) {
1025 			vfs_mount_error(mp, "illegal readahead");
1026 			error = EINVAL;
1027 			goto out;
1028 		}
1029 		ret = sscanf(opt, "%d", &args.readahead);
1030 		if (ret != 1 || args.readahead <= 0) {
1031 			vfs_mount_error(mp, "illegal readahead: %s",
1032 			    opt);
1033 			error = EINVAL;
1034 			goto out;
1035 		}
1036 		args.flags |= NFSMNT_READAHEAD;
1037 	}
1038 	if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
1039 		if (opt == NULL) {
1040 			vfs_mount_error(mp, "illegal wsize");
1041 			error = EINVAL;
1042 			goto out;
1043 		}
1044 		ret = sscanf(opt, "%d", &args.wsize);
1045 		if (ret != 1 || args.wsize <= 0) {
1046 			vfs_mount_error(mp, "illegal wsize: %s",
1047 			    opt);
1048 			error = EINVAL;
1049 			goto out;
1050 		}
1051 		args.flags |= NFSMNT_WSIZE;
1052 	}
1053 	if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
1054 		if (opt == NULL) {
1055 			vfs_mount_error(mp, "illegal rsize");
1056 			error = EINVAL;
1057 			goto out;
1058 		}
1059 		ret = sscanf(opt, "%d", &args.rsize);
1060 		if (ret != 1 || args.rsize <= 0) {
1061 			vfs_mount_error(mp, "illegal wsize: %s",
1062 			    opt);
1063 			error = EINVAL;
1064 			goto out;
1065 		}
1066 		args.flags |= NFSMNT_RSIZE;
1067 	}
1068 	if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
1069 		if (opt == NULL) {
1070 			vfs_mount_error(mp, "illegal retrans");
1071 			error = EINVAL;
1072 			goto out;
1073 		}
1074 		ret = sscanf(opt, "%d", &args.retrans);
1075 		if (ret != 1 || args.retrans <= 0) {
1076 			vfs_mount_error(mp, "illegal retrans: %s",
1077 			    opt);
1078 			error = EINVAL;
1079 			goto out;
1080 		}
1081 		args.flags |= NFSMNT_RETRANS;
1082 	}
1083 	if (vfs_getopt(mp->mnt_optnew, "actimeo", (void **)&opt, NULL) == 0) {
1084 		ret = sscanf(opt, "%d", &args.acregmin);
1085 		if (ret != 1 || args.acregmin < 0) {
1086 			vfs_mount_error(mp, "illegal actimeo: %s",
1087 			    opt);
1088 			error = EINVAL;
1089 			goto out;
1090 		}
1091 		args.acdirmin = args.acdirmax = args.acregmax = args.acregmin;
1092 		args.flags |= NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX |
1093 		    NFSMNT_ACREGMIN | NFSMNT_ACREGMAX;
1094 	}
1095 	if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
1096 		ret = sscanf(opt, "%d", &args.acregmin);
1097 		if (ret != 1 || args.acregmin < 0) {
1098 			vfs_mount_error(mp, "illegal acregmin: %s",
1099 			    opt);
1100 			error = EINVAL;
1101 			goto out;
1102 		}
1103 		args.flags |= NFSMNT_ACREGMIN;
1104 	}
1105 	if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
1106 		ret = sscanf(opt, "%d", &args.acregmax);
1107 		if (ret != 1 || args.acregmax < 0) {
1108 			vfs_mount_error(mp, "illegal acregmax: %s",
1109 			    opt);
1110 			error = EINVAL;
1111 			goto out;
1112 		}
1113 		args.flags |= NFSMNT_ACREGMAX;
1114 	}
1115 	if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
1116 		ret = sscanf(opt, "%d", &args.acdirmin);
1117 		if (ret != 1 || args.acdirmin < 0) {
1118 			vfs_mount_error(mp, "illegal acdirmin: %s",
1119 			    opt);
1120 			error = EINVAL;
1121 			goto out;
1122 		}
1123 		args.flags |= NFSMNT_ACDIRMIN;
1124 	}
1125 	if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1126 		ret = sscanf(opt, "%d", &args.acdirmax);
1127 		if (ret != 1 || args.acdirmax < 0) {
1128 			vfs_mount_error(mp, "illegal acdirmax: %s",
1129 			    opt);
1130 			error = EINVAL;
1131 			goto out;
1132 		}
1133 		args.flags |= NFSMNT_ACDIRMAX;
1134 	}
1135 	if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
1136 		ret = sscanf(opt, "%d", &args.wcommitsize);
1137 		if (ret != 1 || args.wcommitsize < 0) {
1138 			vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
1139 			error = EINVAL;
1140 			goto out;
1141 		}
1142 		args.flags |= NFSMNT_WCOMMITSIZE;
1143 	}
1144 	if (vfs_getopt(mp->mnt_optnew, "timeo", (void **)&opt, NULL) == 0) {
1145 		ret = sscanf(opt, "%d", &args.timeo);
1146 		if (ret != 1 || args.timeo <= 0) {
1147 			vfs_mount_error(mp, "illegal timeo: %s",
1148 			    opt);
1149 			error = EINVAL;
1150 			goto out;
1151 		}
1152 		args.flags |= NFSMNT_TIMEO;
1153 	}
1154 	if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1155 		ret = sscanf(opt, "%d", &args.timeo);
1156 		if (ret != 1 || args.timeo <= 0) {
1157 			vfs_mount_error(mp, "illegal timeout: %s",
1158 			    opt);
1159 			error = EINVAL;
1160 			goto out;
1161 		}
1162 		args.flags |= NFSMNT_TIMEO;
1163 	}
1164 	if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
1165 		ret = sscanf(opt, "%d", &nametimeo);
1166 		if (ret != 1 || nametimeo < 0) {
1167 			vfs_mount_error(mp, "illegal nametimeo: %s", opt);
1168 			error = EINVAL;
1169 			goto out;
1170 		}
1171 	}
1172 	if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1173 	    == 0) {
1174 		ret = sscanf(opt, "%d", &negnametimeo);
1175 		if (ret != 1 || negnametimeo < 0) {
1176 			vfs_mount_error(mp, "illegal negnametimeo: %s",
1177 			    opt);
1178 			error = EINVAL;
1179 			goto out;
1180 		}
1181 	}
1182 	if (vfs_getopt(mp->mnt_optnew, "minorversion", (void **)&opt, NULL) ==
1183 	    0) {
1184 		ret = sscanf(opt, "%d", &minvers);
1185 		if (ret != 1 || minvers < 0 || minvers > 2 ||
1186 		    (args.flags & NFSMNT_NFSV4) == 0) {
1187 			vfs_mount_error(mp, "illegal minorversion: %s", opt);
1188 			error = EINVAL;
1189 			goto out;
1190 		}
1191 	}
1192 	if (vfs_getopt(mp->mnt_optnew, "sec",
1193 		(void **) &secname, NULL) == 0)
1194 		nfs_sec_name(secname, &args.flags);
1195 
1196 	if (mp->mnt_flag & MNT_UPDATE) {
1197 		struct nfsmount *nmp = VFSTONFS(mp);
1198 
1199 		if (nmp == NULL) {
1200 			error = EIO;
1201 			goto out;
1202 		}
1203 
1204 		/*
1205 		 * If a change from TCP->UDP is done and there are thread(s)
1206 		 * that have I/O RPC(s) in progress with a transfer size
1207 		 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1208 		 * hung, retrying the RPC(s) forever. Usually these threads
1209 		 * will be seen doing an uninterruptible sleep on wait channel
1210 		 * "nfsreq".
1211 		 */
1212 		if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1213 			tprintf(td->td_proc, LOG_WARNING,
1214 	"Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1215 
1216 		/*
1217 		 * When doing an update, we can't change version,
1218 		 * security, switch lockd strategies, change cookie
1219 		 * translation or switch oneopenown.
1220 		 */
1221 		args.flags = (args.flags &
1222 		    ~(NFSMNT_NFSV3 |
1223 		      NFSMNT_NFSV4 |
1224 		      NFSMNT_KERB |
1225 		      NFSMNT_INTEGRITY |
1226 		      NFSMNT_PRIVACY |
1227 		      NFSMNT_ONEOPENOWN |
1228 		      NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1229 		    (nmp->nm_flag &
1230 			(NFSMNT_NFSV3 |
1231 			 NFSMNT_NFSV4 |
1232 			 NFSMNT_KERB |
1233 			 NFSMNT_INTEGRITY |
1234 			 NFSMNT_PRIVACY |
1235 			 NFSMNT_ONEOPENOWN |
1236 			 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1237 		nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1238 		goto out;
1239 	}
1240 
1241 	/*
1242 	 * Make the nfs_ip_paranoia sysctl serve as the default connection
1243 	 * or no-connection mode for those protocols that support
1244 	 * no-connection mode (the flag will be cleared later for protocols
1245 	 * that do not support no-connection mode).  This will allow a client
1246 	 * to receive replies from a different IP then the request was
1247 	 * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
1248 	 * not 0.
1249 	 */
1250 	if (nfs_ip_paranoia == 0)
1251 		args.flags |= NFSMNT_NOCONN;
1252 
1253 	if (has_nfs_args_opt != 0) {
1254 		/*
1255 		 * In the 'nfs_args' case, the pointers in the args
1256 		 * structure are in userland - we copy them in here.
1257 		 */
1258 		if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1259 			vfs_mount_error(mp, "Bad file handle");
1260 			error = EINVAL;
1261 			goto out;
1262 		}
1263 		error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1264 		    args.fhsize);
1265 		if (error != 0)
1266 			goto out;
1267 		error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1268 		if (error != 0)
1269 			goto out;
1270 		bzero(&hst[hstlen], MNAMELEN - hstlen);
1271 		args.hostname = hst;
1272 		/* getsockaddr() call must be after above copyin() calls */
1273 		error = getsockaddr(&nam, args.addr, args.addrlen);
1274 		if (error != 0)
1275 			goto out;
1276 	} else if (nfs_mount_parse_from(mp->mnt_optnew,
1277 	    &args.hostname, (struct sockaddr_in **)&nam, dirpath,
1278 	    sizeof(dirpath), &dirlen) == 0) {
1279 		has_nfs_from_opt = 1;
1280 		bcopy(args.hostname, hst, MNAMELEN);
1281 		hst[MNAMELEN - 1] = '\0';
1282 
1283 		/*
1284 		 * This only works with NFSv4 for now.
1285 		 */
1286 		args.fhsize = 0;
1287 		args.flags |= NFSMNT_NFSV4;
1288 		args.sotype = SOCK_STREAM;
1289 	} else {
1290 		if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1291 		    &args.fhsize) == 0) {
1292 			if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1293 				vfs_mount_error(mp, "Bad file handle");
1294 				error = EINVAL;
1295 				goto out;
1296 			}
1297 			bcopy(args.fh, nfh, args.fhsize);
1298 		} else {
1299 			args.fhsize = 0;
1300 		}
1301 		(void) vfs_getopt(mp->mnt_optnew, "hostname",
1302 		    (void **)&args.hostname, &len);
1303 		if (args.hostname == NULL) {
1304 			vfs_mount_error(mp, "Invalid hostname");
1305 			error = EINVAL;
1306 			goto out;
1307 		}
1308 		if (len >= MNAMELEN) {
1309 			vfs_mount_error(mp, "Hostname too long");
1310 			error = EINVAL;
1311 			goto out;
1312 		}
1313 		bcopy(args.hostname, hst, len);
1314 		hst[len] = '\0';
1315 	}
1316 
1317 	if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1318 		strlcpy(srvkrbname, name, sizeof (srvkrbname));
1319 	else {
1320 		snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1321 		cp = strchr(srvkrbname, ':');
1322 		if (cp != NULL)
1323 			*cp = '\0';
1324 	}
1325 	srvkrbnamelen = strlen(srvkrbname);
1326 
1327 	if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1328 		strlcpy(krbname, name, sizeof (krbname));
1329 	else
1330 		krbname[0] = '\0';
1331 	krbnamelen = strlen(krbname);
1332 
1333 	if (has_nfs_from_opt == 0) {
1334 		if (vfs_getopt(mp->mnt_optnew,
1335 		    "dirpath", (void **)&name, NULL) == 0)
1336 			strlcpy(dirpath, name, sizeof (dirpath));
1337 		else
1338 			dirpath[0] = '\0';
1339 		dirlen = strlen(dirpath);
1340 	}
1341 
1342 	if (has_nfs_args_opt == 0 && has_nfs_from_opt == 0) {
1343 		if (vfs_getopt(mp->mnt_optnew, "addr",
1344 		    (void **)&args.addr, &args.addrlen) == 0) {
1345 			if (args.addrlen > SOCK_MAXADDRLEN) {
1346 				error = ENAMETOOLONG;
1347 				goto out;
1348 			}
1349 			nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1350 			bcopy(args.addr, nam, args.addrlen);
1351 			nam->sa_len = args.addrlen;
1352 		} else {
1353 			vfs_mount_error(mp, "No server address");
1354 			error = EINVAL;
1355 			goto out;
1356 		}
1357 	}
1358 
1359 	args.fh = nfh;
1360 	error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1361 	    dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1362 	    nametimeo, negnametimeo, minvers, newflag, tlscertname);
1363 out:
1364 	if (!error) {
1365 		MNT_ILOCK(mp);
1366 		mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF |
1367 		    MNTK_USES_BCACHE;
1368 		if ((VFSTONFS(mp)->nm_flag & NFSMNT_NFSV4) != 0)
1369 			mp->mnt_kern_flag |= MNTK_NULL_NOCACHE;
1370 		MNT_IUNLOCK(mp);
1371 	}
1372 	free(hst, M_TEMP);
1373 	return (error);
1374 }
1375 
1376 /*
1377  * VFS Operations.
1378  *
1379  * mount system call
1380  * It seems a bit dumb to copyinstr() the host and path here and then
1381  * bcopy() them in mountnfs(), but I wanted to detect errors before
1382  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
1383  * an error after that means that I have to release the mbuf.
1384  */
1385 /* ARGSUSED */
1386 static int
1387 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1388 {
1389 	int error;
1390 	struct nfs_args args;
1391 
1392 	error = copyin(data, &args, sizeof (struct nfs_args));
1393 	if (error)
1394 		return error;
1395 
1396 	ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1397 
1398 	error = kernel_mount(ma, flags);
1399 	return (error);
1400 }
1401 
1402 /*
1403  * Common code for mount and mountroot
1404  */
1405 static int
1406 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1407     char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1408     u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1409     struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
1410     int minvers, uint32_t newflag, char *tlscertname)
1411 {
1412 	struct nfsmount *nmp;
1413 	struct nfsnode *np;
1414 	int error, trycnt, ret;
1415 	struct nfsvattr nfsva;
1416 	struct nfsclclient *clp;
1417 	struct nfsclds *dsp, *tdsp;
1418 	uint32_t lease;
1419 	static u_int64_t clval = 0;
1420 #ifdef KERN_TLS
1421 	u_int maxlen;
1422 #endif
1423 
1424 	NFSCL_DEBUG(3, "in mnt\n");
1425 	clp = NULL;
1426 	if (mp->mnt_flag & MNT_UPDATE) {
1427 		nmp = VFSTONFS(mp);
1428 		printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1429 		free(nam, M_SONAME);
1430 		free(tlscertname, M_NEWNFSMNT);
1431 		return (0);
1432 	} else {
1433 		/* NFS-over-TLS requires that rpctls be functioning. */
1434 		if ((newflag & NFSMNT_TLS) != 0) {
1435 			error = EINVAL;
1436 #ifdef KERN_TLS
1437 			/* KERN_TLS is only supported for TCP. */
1438 			if (argp->sotype == SOCK_STREAM &&
1439 			    rpctls_getinfo(&maxlen, true, false))
1440 				error = 0;
1441 #endif
1442 			if (error != 0) {
1443 				free(nam, M_SONAME);
1444 				free(tlscertname, M_NEWNFSMNT);
1445 				return (error);
1446 			}
1447 		}
1448 		nmp = malloc(sizeof (struct nfsmount) +
1449 		    krbnamelen + dirlen + srvkrbnamelen + 2,
1450 		    M_NEWNFSMNT, M_WAITOK | M_ZERO);
1451 		nmp->nm_tlscertname = tlscertname;
1452 		nmp->nm_newflag = newflag;
1453 		TAILQ_INIT(&nmp->nm_bufq);
1454 		TAILQ_INIT(&nmp->nm_sess);
1455 		if (clval == 0)
1456 			clval = (u_int64_t)nfsboottime.tv_sec;
1457 		nmp->nm_clval = clval++;
1458 		nmp->nm_krbnamelen = krbnamelen;
1459 		nmp->nm_dirpathlen = dirlen;
1460 		nmp->nm_srvkrbnamelen = srvkrbnamelen;
1461 		if (td->td_ucred->cr_uid != (uid_t)0) {
1462 			/*
1463 			 * nm_uid is used to get KerberosV credentials for
1464 			 * the nfsv4 state handling operations if there is
1465 			 * no host based principal set. Use the uid of
1466 			 * this user if not root, since they are doing the
1467 			 * mount. I don't think setting this for root will
1468 			 * work, since root normally does not have user
1469 			 * credentials in a credentials cache.
1470 			 */
1471 			nmp->nm_uid = td->td_ucred->cr_uid;
1472 		} else {
1473 			/*
1474 			 * Just set to -1, so it won't be used.
1475 			 */
1476 			nmp->nm_uid = (uid_t)-1;
1477 		}
1478 
1479 		/* Copy and null terminate all the names */
1480 		if (nmp->nm_krbnamelen > 0) {
1481 			bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1482 			nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1483 		}
1484 		if (nmp->nm_dirpathlen > 0) {
1485 			bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1486 			    nmp->nm_dirpathlen);
1487 			nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1488 			    + 1] = '\0';
1489 		}
1490 		if (nmp->nm_srvkrbnamelen > 0) {
1491 			bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1492 			    nmp->nm_srvkrbnamelen);
1493 			nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1494 			    + nmp->nm_srvkrbnamelen + 2] = '\0';
1495 		}
1496 		nmp->nm_sockreq.nr_cred = crhold(cred);
1497 		mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1498 		mp->mnt_data = nmp;
1499 		nmp->nm_getinfo = nfs_getnlminfo;
1500 		nmp->nm_vinvalbuf = ncl_vinvalbuf;
1501 	}
1502 	vfs_getnewfsid(mp);
1503 	nmp->nm_mountp = mp;
1504 	mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1505 
1506 	/*
1507 	 * Since nfs_decode_args() might optionally set them, these
1508 	 * need to be set to defaults before the call, so that the
1509 	 * optional settings aren't overwritten.
1510 	 */
1511 	nmp->nm_nametimeo = nametimeo;
1512 	nmp->nm_negnametimeo = negnametimeo;
1513 	nmp->nm_timeo = NFS_TIMEO;
1514 	nmp->nm_retry = NFS_RETRANS;
1515 	nmp->nm_readahead = NFS_DEFRAHEAD;
1516 
1517 	/* This is empirical approximation of sqrt(hibufspace) * 256. */
1518 	nmp->nm_wcommitsize = NFS_MAXBSIZE / 256;
1519 	while ((long)nmp->nm_wcommitsize * nmp->nm_wcommitsize < hibufspace)
1520 		nmp->nm_wcommitsize *= 2;
1521 	nmp->nm_wcommitsize *= 256;
1522 
1523 	if ((argp->flags & NFSMNT_NFSV4) != 0)
1524 		nmp->nm_minorvers = minvers;
1525 	else
1526 		nmp->nm_minorvers = 0;
1527 
1528 	nfs_decode_args(mp, nmp, argp, hst, cred, td);
1529 
1530 	/*
1531 	 * V2 can only handle 32 bit filesizes.  A 4GB-1 limit may be too
1532 	 * high, depending on whether we end up with negative offsets in
1533 	 * the client or server somewhere.  2GB-1 may be safer.
1534 	 *
1535 	 * For V3, ncl_fsinfo will adjust this as necessary.  Assume maximum
1536 	 * that we can handle until we find out otherwise.
1537 	 */
1538 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1539 		nmp->nm_maxfilesize = 0xffffffffLL;
1540 	else
1541 		nmp->nm_maxfilesize = OFF_MAX;
1542 
1543 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1544 		nmp->nm_wsize = NFS_WSIZE;
1545 		nmp->nm_rsize = NFS_RSIZE;
1546 		nmp->nm_readdirsize = NFS_READDIRSIZE;
1547 	}
1548 	nmp->nm_numgrps = NFS_MAXGRPS;
1549 	nmp->nm_tprintf_delay = nfs_tprintf_delay;
1550 	if (nmp->nm_tprintf_delay < 0)
1551 		nmp->nm_tprintf_delay = 0;
1552 	nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1553 	if (nmp->nm_tprintf_initial_delay < 0)
1554 		nmp->nm_tprintf_initial_delay = 0;
1555 	nmp->nm_fhsize = argp->fhsize;
1556 	if (nmp->nm_fhsize > 0)
1557 		bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1558 	bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1559 	nmp->nm_nam = nam;
1560 	/* Set up the sockets and per-host congestion */
1561 	nmp->nm_sotype = argp->sotype;
1562 	nmp->nm_soproto = argp->proto;
1563 	nmp->nm_sockreq.nr_prog = NFS_PROG;
1564 	if ((argp->flags & NFSMNT_NFSV4))
1565 		nmp->nm_sockreq.nr_vers = NFS_VER4;
1566 	else if ((argp->flags & NFSMNT_NFSV3))
1567 		nmp->nm_sockreq.nr_vers = NFS_VER3;
1568 	else
1569 		nmp->nm_sockreq.nr_vers = NFS_VER2;
1570 
1571 	if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false)))
1572 		goto bad;
1573 	/* For NFSv4.1, get the clientid now. */
1574 	if (nmp->nm_minorvers > 0) {
1575 		NFSCL_DEBUG(3, "at getcl\n");
1576 		error = nfscl_getcl(mp, cred, td, 0, &clp);
1577 		NFSCL_DEBUG(3, "aft getcl=%d\n", error);
1578 		if (error != 0)
1579 			goto bad;
1580 	}
1581 
1582 	if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1583 	    nmp->nm_dirpathlen > 0) {
1584 		NFSCL_DEBUG(3, "in dirp\n");
1585 		/*
1586 		 * If the fhsize on the mount point == 0 for V4, the mount
1587 		 * path needs to be looked up.
1588 		 */
1589 		trycnt = 3;
1590 		do {
1591 			error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1592 			    cred, td);
1593 			NFSCL_DEBUG(3, "aft dirp=%d\n", error);
1594 			if (error)
1595 				(void) nfs_catnap(PZERO, error, "nfsgetdirp");
1596 		} while (error && --trycnt > 0);
1597 		if (error)
1598 			goto bad;
1599 	}
1600 
1601 	/*
1602 	 * A reference count is needed on the nfsnode representing the
1603 	 * remote root.  If this object is not persistent, then backward
1604 	 * traversals of the mount point (i.e. "..") will not work if
1605 	 * the nfsnode gets flushed out of the cache. Ufs does not have
1606 	 * this problem, because one can identify root inodes by their
1607 	 * number == UFS_ROOTINO (2).
1608 	 */
1609 	if (nmp->nm_fhsize > 0) {
1610 		/*
1611 		 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1612 		 * non-zero for the root vnode. f_iosize will be set correctly
1613 		 * by nfs_statfs() before any I/O occurs.
1614 		 */
1615 		mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1616 		error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1617 		    LK_EXCLUSIVE);
1618 		if (error)
1619 			goto bad;
1620 		*vpp = NFSTOV(np);
1621 
1622 		/*
1623 		 * Get file attributes and transfer parameters for the
1624 		 * mountpoint.  This has the side effect of filling in
1625 		 * (*vpp)->v_type with the correct value.
1626 		 */
1627 		ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1628 		    cred, td, &nfsva, NULL, &lease);
1629 		if (ret) {
1630 			/*
1631 			 * Just set default values to get things going.
1632 			 */
1633 			NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1634 			nfsva.na_vattr.va_type = VDIR;
1635 			nfsva.na_vattr.va_mode = 0777;
1636 			nfsva.na_vattr.va_nlink = 100;
1637 			nfsva.na_vattr.va_uid = (uid_t)0;
1638 			nfsva.na_vattr.va_gid = (gid_t)0;
1639 			nfsva.na_vattr.va_fileid = 2;
1640 			nfsva.na_vattr.va_gen = 1;
1641 			nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1642 			nfsva.na_vattr.va_size = 512 * 1024;
1643 			lease = 60;
1644 		}
1645 		(void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1646 		if (nmp->nm_minorvers > 0) {
1647 			NFSCL_DEBUG(3, "lease=%d\n", (int)lease);
1648 			NFSLOCKCLSTATE();
1649 			clp->nfsc_renew = NFSCL_RENEW(lease);
1650 			clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
1651 			clp->nfsc_clientidrev++;
1652 			if (clp->nfsc_clientidrev == 0)
1653 				clp->nfsc_clientidrev++;
1654 			NFSUNLOCKCLSTATE();
1655 			/*
1656 			 * Mount will succeed, so the renew thread can be
1657 			 * started now.
1658 			 */
1659 			nfscl_start_renewthread(clp);
1660 			nfscl_clientrelease(clp);
1661 		}
1662 		if (argp->flags & NFSMNT_NFSV3)
1663 			ncl_fsinfo(nmp, *vpp, cred, td);
1664 
1665 		/* Mark if the mount point supports NFSv4 ACLs. */
1666 		if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1667 		    ret == 0 &&
1668 		    NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1669 			MNT_ILOCK(mp);
1670 			mp->mnt_flag |= MNT_NFS4ACLS;
1671 			MNT_IUNLOCK(mp);
1672 		}
1673 
1674 		/*
1675 		 * Lose the lock but keep the ref.
1676 		 */
1677 		NFSVOPUNLOCK(*vpp);
1678 		vfs_cache_root_set(mp, *vpp);
1679 		return (0);
1680 	}
1681 	error = EIO;
1682 
1683 bad:
1684 	if (clp != NULL)
1685 		nfscl_clientrelease(clp);
1686 	newnfs_disconnect(&nmp->nm_sockreq);
1687 	crfree(nmp->nm_sockreq.nr_cred);
1688 	if (nmp->nm_sockreq.nr_auth != NULL)
1689 		AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1690 	mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1691 	mtx_destroy(&nmp->nm_mtx);
1692 	if (nmp->nm_clp != NULL) {
1693 		NFSLOCKCLSTATE();
1694 		LIST_REMOVE(nmp->nm_clp, nfsc_list);
1695 		NFSUNLOCKCLSTATE();
1696 		free(nmp->nm_clp, M_NFSCLCLIENT);
1697 	}
1698 	TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1699 		if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1700 		    dsp->nfsclds_sockp != NULL)
1701 			newnfs_disconnect(dsp->nfsclds_sockp);
1702 		nfscl_freenfsclds(dsp);
1703 	}
1704 	free(nmp->nm_tlscertname, M_NEWNFSMNT);
1705 	free(nmp, M_NEWNFSMNT);
1706 	free(nam, M_SONAME);
1707 	return (error);
1708 }
1709 
1710 /*
1711  * unmount system call
1712  */
1713 static int
1714 nfs_unmount(struct mount *mp, int mntflags)
1715 {
1716 	struct thread *td;
1717 	struct nfsmount *nmp;
1718 	int error, flags = 0, i, trycnt = 0;
1719 	struct nfsclds *dsp, *tdsp;
1720 
1721 	td = curthread;
1722 
1723 	if (mntflags & MNT_FORCE)
1724 		flags |= FORCECLOSE;
1725 	nmp = VFSTONFS(mp);
1726 	error = 0;
1727 	/*
1728 	 * Goes something like this..
1729 	 * - Call vflush() to clear out vnodes for this filesystem
1730 	 * - Close the socket
1731 	 * - Free up the data structures
1732 	 */
1733 	/* In the forced case, cancel any outstanding requests. */
1734 	if (mntflags & MNT_FORCE) {
1735 		NFSDDSLOCK();
1736 		if (nfsv4_findmirror(nmp) != NULL)
1737 			error = ENXIO;
1738 		NFSDDSUNLOCK();
1739 		if (error)
1740 			goto out;
1741 		error = newnfs_nmcancelreqs(nmp);
1742 		if (error)
1743 			goto out;
1744 		/* For a forced close, get rid of the renew thread now */
1745 		nfscl_umount(nmp, td);
1746 	}
1747 	/* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1748 	do {
1749 		error = vflush(mp, 1, flags, td);
1750 		if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1751 			(void) nfs_catnap(PSOCK, error, "newndm");
1752 	} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1753 	if (error)
1754 		goto out;
1755 
1756 	/*
1757 	 * We are now committed to the unmount.
1758 	 */
1759 	if ((mntflags & MNT_FORCE) == 0)
1760 		nfscl_umount(nmp, td);
1761 	else {
1762 		mtx_lock(&nmp->nm_mtx);
1763 		nmp->nm_privflag |= NFSMNTP_FORCEDISM;
1764 		mtx_unlock(&nmp->nm_mtx);
1765 	}
1766 	/* Make sure no nfsiods are assigned to this mount. */
1767 	NFSLOCKIOD();
1768 	for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1769 		if (ncl_iodmount[i] == nmp) {
1770 			ncl_iodwant[i] = NFSIOD_AVAILABLE;
1771 			ncl_iodmount[i] = NULL;
1772 		}
1773 	NFSUNLOCKIOD();
1774 
1775 	/*
1776 	 * We can now set mnt_data to NULL and wait for
1777 	 * nfssvc(NFSSVC_FORCEDISM) to complete.
1778 	 */
1779 	mtx_lock(&mountlist_mtx);
1780 	mtx_lock(&nmp->nm_mtx);
1781 	mp->mnt_data = NULL;
1782 	mtx_unlock(&mountlist_mtx);
1783 	while ((nmp->nm_privflag & NFSMNTP_CANCELRPCS) != 0)
1784 		msleep(nmp, &nmp->nm_mtx, PVFS, "nfsfdism", 0);
1785 	mtx_unlock(&nmp->nm_mtx);
1786 
1787 	newnfs_disconnect(&nmp->nm_sockreq);
1788 	crfree(nmp->nm_sockreq.nr_cred);
1789 	free(nmp->nm_nam, M_SONAME);
1790 	if (nmp->nm_sockreq.nr_auth != NULL)
1791 		AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1792 	mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1793 	mtx_destroy(&nmp->nm_mtx);
1794 	TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1795 		if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1796 		    dsp->nfsclds_sockp != NULL)
1797 			newnfs_disconnect(dsp->nfsclds_sockp);
1798 		nfscl_freenfsclds(dsp);
1799 	}
1800 	free(nmp->nm_tlscertname, M_NEWNFSMNT);
1801 	free(nmp, M_NEWNFSMNT);
1802 out:
1803 	return (error);
1804 }
1805 
1806 /*
1807  * Return root of a filesystem
1808  */
1809 static int
1810 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1811 {
1812 	struct vnode *vp;
1813 	struct nfsmount *nmp;
1814 	struct nfsnode *np;
1815 	int error;
1816 
1817 	nmp = VFSTONFS(mp);
1818 	error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1819 	if (error)
1820 		return error;
1821 	vp = NFSTOV(np);
1822 	/*
1823 	 * Get transfer parameters and attributes for root vnode once.
1824 	 */
1825 	mtx_lock(&nmp->nm_mtx);
1826 	if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1827 		mtx_unlock(&nmp->nm_mtx);
1828 		ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1829 	} else
1830 		mtx_unlock(&nmp->nm_mtx);
1831 	if (vp->v_type == VNON)
1832 	    vp->v_type = VDIR;
1833 	vp->v_vflag |= VV_ROOT;
1834 	*vpp = vp;
1835 	return (0);
1836 }
1837 
1838 /*
1839  * Flush out the buffer cache
1840  */
1841 /* ARGSUSED */
1842 static int
1843 nfs_sync(struct mount *mp, int waitfor)
1844 {
1845 	struct vnode *vp, *mvp;
1846 	struct thread *td;
1847 	int error, allerror = 0;
1848 
1849 	td = curthread;
1850 
1851 	MNT_ILOCK(mp);
1852 	/*
1853 	 * If a forced dismount is in progress, return from here so that
1854 	 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1855 	 * calling VFS_UNMOUNT().
1856 	 */
1857 	if (NFSCL_FORCEDISM(mp)) {
1858 		MNT_IUNLOCK(mp);
1859 		return (EBADF);
1860 	}
1861 	MNT_IUNLOCK(mp);
1862 
1863 	/*
1864 	 * Force stale buffer cache information to be flushed.
1865 	 */
1866 loop:
1867 	MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1868 		/* XXX Racy bv_cnt check. */
1869 		if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1870 		    waitfor == MNT_LAZY) {
1871 			VI_UNLOCK(vp);
1872 			continue;
1873 		}
1874 		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
1875 			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1876 			goto loop;
1877 		}
1878 		error = VOP_FSYNC(vp, waitfor, td);
1879 		if (error)
1880 			allerror = error;
1881 		NFSVOPUNLOCK(vp);
1882 		vrele(vp);
1883 	}
1884 	return (allerror);
1885 }
1886 
1887 static int
1888 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1889 {
1890 	struct nfsmount *nmp = VFSTONFS(mp);
1891 	struct vfsquery vq;
1892 	int error;
1893 
1894 	bzero(&vq, sizeof(vq));
1895 	switch (op) {
1896 #if 0
1897 	case VFS_CTL_NOLOCKS:
1898 		val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1899  		if (req->oldptr != NULL) {
1900  			error = SYSCTL_OUT(req, &val, sizeof(val));
1901  			if (error)
1902  				return (error);
1903  		}
1904  		if (req->newptr != NULL) {
1905  			error = SYSCTL_IN(req, &val, sizeof(val));
1906  			if (error)
1907  				return (error);
1908 			if (val)
1909 				nmp->nm_flag |= NFSMNT_NOLOCKS;
1910 			else
1911 				nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1912  		}
1913 		break;
1914 #endif
1915 	case VFS_CTL_QUERY:
1916 		mtx_lock(&nmp->nm_mtx);
1917 		if (nmp->nm_state & NFSSTA_TIMEO)
1918 			vq.vq_flags |= VQ_NOTRESP;
1919 		mtx_unlock(&nmp->nm_mtx);
1920 #if 0
1921 		if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1922 		    (nmp->nm_state & NFSSTA_LOCKTIMEO))
1923 			vq.vq_flags |= VQ_NOTRESPLOCK;
1924 #endif
1925 		error = SYSCTL_OUT(req, &vq, sizeof(vq));
1926 		break;
1927  	case VFS_CTL_TIMEO:
1928  		if (req->oldptr != NULL) {
1929  			error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1930  			    sizeof(nmp->nm_tprintf_initial_delay));
1931  			if (error)
1932  				return (error);
1933  		}
1934  		if (req->newptr != NULL) {
1935 			error = vfs_suser(mp, req->td);
1936 			if (error)
1937 				return (error);
1938  			error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1939  			    sizeof(nmp->nm_tprintf_initial_delay));
1940  			if (error)
1941  				return (error);
1942  			if (nmp->nm_tprintf_initial_delay < 0)
1943  				nmp->nm_tprintf_initial_delay = 0;
1944  		}
1945 		break;
1946 	default:
1947 		return (ENOTSUP);
1948 	}
1949 	return (0);
1950 }
1951 
1952 /*
1953  * Purge any RPCs in progress, so that they will all return errors.
1954  * This allows dounmount() to continue as far as VFS_UNMOUNT() for a
1955  * forced dismount.
1956  */
1957 static void
1958 nfs_purge(struct mount *mp)
1959 {
1960 	struct nfsmount *nmp = VFSTONFS(mp);
1961 
1962 	newnfs_nmcancelreqs(nmp);
1963 }
1964 
1965 /*
1966  * Extract the information needed by the nlm from the nfs vnode.
1967  */
1968 static void
1969 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1970     struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1971     struct timeval *timeop)
1972 {
1973 	struct nfsmount *nmp;
1974 	struct nfsnode *np = VTONFS(vp);
1975 
1976 	nmp = VFSTONFS(vp->v_mount);
1977 	if (fhlenp != NULL)
1978 		*fhlenp = (size_t)np->n_fhp->nfh_len;
1979 	if (fhp != NULL)
1980 		bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1981 	if (sp != NULL)
1982 		bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1983 	if (is_v3p != NULL)
1984 		*is_v3p = NFS_ISV3(vp);
1985 	if (sizep != NULL)
1986 		*sizep = np->n_size;
1987 	if (timeop != NULL) {
1988 		timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1989 		timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1990 	}
1991 }
1992 
1993 /*
1994  * This function prints out an option name, based on the conditional
1995  * argument.
1996  */
1997 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
1998     char *opt, char **buf, size_t *blen)
1999 {
2000 	int len;
2001 
2002 	if (testval != 0 && *blen > strlen(opt)) {
2003 		len = snprintf(*buf, *blen, "%s", opt);
2004 		if (len != strlen(opt))
2005 			printf("EEK!!\n");
2006 		*buf += len;
2007 		*blen -= len;
2008 	}
2009 }
2010 
2011 /*
2012  * This function printf out an options integer value.
2013  */
2014 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
2015     char *opt, char **buf, size_t *blen)
2016 {
2017 	int len;
2018 
2019 	if (*blen > strlen(opt) + 1) {
2020 		/* Could result in truncated output string. */
2021 		len = snprintf(*buf, *blen, "%s=%d", opt, optval);
2022 		if (len < *blen) {
2023 			*buf += len;
2024 			*blen -= len;
2025 		}
2026 	}
2027 }
2028 
2029 /*
2030  * Load the option flags and values into the buffer.
2031  */
2032 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
2033 {
2034 	char *buf;
2035 	size_t blen;
2036 
2037 	buf = buffer;
2038 	blen = buflen;
2039 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
2040 	    &blen);
2041 	if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) {
2042 		nfscl_printoptval(nmp, nmp->nm_minorvers, ",minorversion", &buf,
2043 		    &blen);
2044 		nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
2045 		    &buf, &blen);
2046 		nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_ONEOPENOWN) != 0 &&
2047 		    nmp->nm_minorvers > 0, ",oneopenown", &buf, &blen);
2048 	}
2049 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
2050 	    &blen);
2051 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
2052 	    "nfsv2", &buf, &blen);
2053 	nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
2054 	nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
2055 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
2056 	    &buf, &blen);
2057 	nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf,
2058 	    &blen);
2059 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
2060 	    &buf, &blen);
2061 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
2062 	    &blen);
2063 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
2064 	    &blen);
2065 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
2066 	    &blen);
2067 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
2068 	    &blen);
2069 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
2070 	    &blen);
2071 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NONCONTIGWR) != 0,
2072 	    ",noncontigwr", &buf, &blen);
2073 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2074 	    0, ",lockd", &buf, &blen);
2075 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2076 	    NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
2077 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
2078 	    &buf, &blen);
2079 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
2080 	    &buf, &blen);
2081 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2082 	    NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
2083 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2084 	    NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
2085 	    &buf, &blen);
2086 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2087 	    NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
2088 	    &buf, &blen);
2089 	nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
2090 	nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
2091 	nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
2092 	nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
2093 	nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
2094 	nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
2095 	    &blen);
2096 	nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
2097 	nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
2098 	nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
2099 	    &blen);
2100 	nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
2101 	nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
2102 	    &blen);
2103 	nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
2104 	nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
2105 }
2106