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