xref: /freebsd/sys/fs/nfsclient/nfs_clvfsops.c (revision cc68614da8232d8baaca0ae0d0dd8f890f06623e)
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 *, int);
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)) != 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, &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, &nmp->nm_sockreq.nr_client)) {
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", "nconnect",
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 = -1;
901 	int dirlen, has_nfs_args_opt, has_nfs_from_opt,
902 	    krbnamelen, srvkrbnamelen;
903 	size_t hstlen;
904 	uint32_t newflag;
905 	int aconn = 0;
906 
907 	has_nfs_args_opt = 0;
908 	has_nfs_from_opt = 0;
909 	newflag = 0;
910 	tlscertname = NULL;
911 	hst = malloc(MNAMELEN, M_TEMP, M_WAITOK);
912 	if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
913 		error = EINVAL;
914 		goto out;
915 	}
916 
917 	td = curthread;
918 	if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS &&
919 	    nfs_diskless_valid != 0) {
920 		error = nfs_mountroot(mp);
921 		goto out;
922 	}
923 
924 	nfscl_init();
925 
926 	/*
927 	 * The old mount_nfs program passed the struct nfs_args
928 	 * from userspace to kernel.  The new mount_nfs program
929 	 * passes string options via nmount() from userspace to kernel
930 	 * and we populate the struct nfs_args in the kernel.
931 	 */
932 	if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
933 		error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
934 		    sizeof(args));
935 		if (error != 0)
936 			goto out;
937 
938 		if (args.version != NFS_ARGSVERSION) {
939 			error = EPROGMISMATCH;
940 			goto out;
941 		}
942 		has_nfs_args_opt = 1;
943 	}
944 
945 	/* Handle the new style options. */
946 	if (vfs_getopt(mp->mnt_optnew, "noac", NULL, NULL) == 0) {
947 		args.acdirmin = args.acdirmax =
948 		    args.acregmin = args.acregmax = 0;
949 		args.flags |= NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX |
950 		    NFSMNT_ACREGMIN | NFSMNT_ACREGMAX;
951 	}
952 	if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
953 		args.flags |= NFSMNT_NOCONN;
954 	if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
955 		args.flags &= ~NFSMNT_NOCONN;
956 	if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
957 		args.flags |= NFSMNT_NOLOCKD;
958 	if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
959 		args.flags &= ~NFSMNT_NOLOCKD;
960 	if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
961 		args.flags |= NFSMNT_INT;
962 	if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
963 		args.flags |= NFSMNT_RDIRPLUS;
964 	if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
965 		args.flags |= NFSMNT_RESVPORT;
966 	if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
967 		args.flags &= ~NFSMNT_RESVPORT;
968 	if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
969 		args.flags |= NFSMNT_SOFT;
970 	if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
971 		args.flags &= ~NFSMNT_SOFT;
972 	if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
973 		args.sotype = SOCK_DGRAM;
974 	if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
975 		args.sotype = SOCK_DGRAM;
976 	if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
977 		args.sotype = SOCK_STREAM;
978 	if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
979 		args.flags |= NFSMNT_NFSV3;
980 	if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
981 		args.flags |= NFSMNT_NFSV4;
982 		args.sotype = SOCK_STREAM;
983 	}
984 	if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
985 		args.flags |= NFSMNT_ALLGSSNAME;
986 	if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
987 		args.flags |= NFSMNT_NOCTO;
988 	if (vfs_getopt(mp->mnt_optnew, "noncontigwr", NULL, NULL) == 0)
989 		args.flags |= NFSMNT_NONCONTIGWR;
990 	if (vfs_getopt(mp->mnt_optnew, "pnfs", NULL, NULL) == 0)
991 		args.flags |= NFSMNT_PNFS;
992 	if (vfs_getopt(mp->mnt_optnew, "oneopenown", NULL, NULL) == 0)
993 		args.flags |= NFSMNT_ONEOPENOWN;
994 	if (vfs_getopt(mp->mnt_optnew, "tls", NULL, NULL) == 0)
995 		newflag |= NFSMNT_TLS;
996 	if (vfs_getopt(mp->mnt_optnew, "tlscertname", (void **)&opt, &len) ==
997 	    0) {
998 		/*
999 		 * tlscertname with "key.pem" appended to it forms a file
1000 		 * name.  As such, the maximum allowable strlen(tlscertname) is
1001 		 * NAME_MAX - 7. However, "len" includes the nul termination
1002 		 * byte so it can be up to NAME_MAX - 6.
1003 		 */
1004 		if (opt == NULL || len <= 1 || len > NAME_MAX - 6) {
1005 			vfs_mount_error(mp, "invalid tlscertname");
1006 			error = EINVAL;
1007 			goto out;
1008 		}
1009 		tlscertname = malloc(len, M_NEWNFSMNT, M_WAITOK);
1010 		strlcpy(tlscertname, opt, len);
1011 	}
1012 	if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
1013 		if (opt == NULL) {
1014 			vfs_mount_error(mp, "illegal readdirsize");
1015 			error = EINVAL;
1016 			goto out;
1017 		}
1018 		ret = sscanf(opt, "%d", &args.readdirsize);
1019 		if (ret != 1 || args.readdirsize <= 0) {
1020 			vfs_mount_error(mp, "illegal readdirsize: %s",
1021 			    opt);
1022 			error = EINVAL;
1023 			goto out;
1024 		}
1025 		args.flags |= NFSMNT_READDIRSIZE;
1026 	}
1027 	if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
1028 		if (opt == NULL) {
1029 			vfs_mount_error(mp, "illegal readahead");
1030 			error = EINVAL;
1031 			goto out;
1032 		}
1033 		ret = sscanf(opt, "%d", &args.readahead);
1034 		if (ret != 1 || args.readahead <= 0) {
1035 			vfs_mount_error(mp, "illegal readahead: %s",
1036 			    opt);
1037 			error = EINVAL;
1038 			goto out;
1039 		}
1040 		args.flags |= NFSMNT_READAHEAD;
1041 	}
1042 	if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
1043 		if (opt == NULL) {
1044 			vfs_mount_error(mp, "illegal wsize");
1045 			error = EINVAL;
1046 			goto out;
1047 		}
1048 		ret = sscanf(opt, "%d", &args.wsize);
1049 		if (ret != 1 || args.wsize <= 0) {
1050 			vfs_mount_error(mp, "illegal wsize: %s",
1051 			    opt);
1052 			error = EINVAL;
1053 			goto out;
1054 		}
1055 		args.flags |= NFSMNT_WSIZE;
1056 	}
1057 	if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
1058 		if (opt == NULL) {
1059 			vfs_mount_error(mp, "illegal rsize");
1060 			error = EINVAL;
1061 			goto out;
1062 		}
1063 		ret = sscanf(opt, "%d", &args.rsize);
1064 		if (ret != 1 || args.rsize <= 0) {
1065 			vfs_mount_error(mp, "illegal wsize: %s",
1066 			    opt);
1067 			error = EINVAL;
1068 			goto out;
1069 		}
1070 		args.flags |= NFSMNT_RSIZE;
1071 	}
1072 	if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
1073 		if (opt == NULL) {
1074 			vfs_mount_error(mp, "illegal retrans");
1075 			error = EINVAL;
1076 			goto out;
1077 		}
1078 		ret = sscanf(opt, "%d", &args.retrans);
1079 		if (ret != 1 || args.retrans <= 0) {
1080 			vfs_mount_error(mp, "illegal retrans: %s",
1081 			    opt);
1082 			error = EINVAL;
1083 			goto out;
1084 		}
1085 		args.flags |= NFSMNT_RETRANS;
1086 	}
1087 	if (vfs_getopt(mp->mnt_optnew, "actimeo", (void **)&opt, NULL) == 0) {
1088 		ret = sscanf(opt, "%d", &args.acregmin);
1089 		if (ret != 1 || args.acregmin < 0) {
1090 			vfs_mount_error(mp, "illegal actimeo: %s",
1091 			    opt);
1092 			error = EINVAL;
1093 			goto out;
1094 		}
1095 		args.acdirmin = args.acdirmax = args.acregmax = args.acregmin;
1096 		args.flags |= NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX |
1097 		    NFSMNT_ACREGMIN | NFSMNT_ACREGMAX;
1098 	}
1099 	if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
1100 		ret = sscanf(opt, "%d", &args.acregmin);
1101 		if (ret != 1 || args.acregmin < 0) {
1102 			vfs_mount_error(mp, "illegal acregmin: %s",
1103 			    opt);
1104 			error = EINVAL;
1105 			goto out;
1106 		}
1107 		args.flags |= NFSMNT_ACREGMIN;
1108 	}
1109 	if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
1110 		ret = sscanf(opt, "%d", &args.acregmax);
1111 		if (ret != 1 || args.acregmax < 0) {
1112 			vfs_mount_error(mp, "illegal acregmax: %s",
1113 			    opt);
1114 			error = EINVAL;
1115 			goto out;
1116 		}
1117 		args.flags |= NFSMNT_ACREGMAX;
1118 	}
1119 	if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
1120 		ret = sscanf(opt, "%d", &args.acdirmin);
1121 		if (ret != 1 || args.acdirmin < 0) {
1122 			vfs_mount_error(mp, "illegal acdirmin: %s",
1123 			    opt);
1124 			error = EINVAL;
1125 			goto out;
1126 		}
1127 		args.flags |= NFSMNT_ACDIRMIN;
1128 	}
1129 	if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1130 		ret = sscanf(opt, "%d", &args.acdirmax);
1131 		if (ret != 1 || args.acdirmax < 0) {
1132 			vfs_mount_error(mp, "illegal acdirmax: %s",
1133 			    opt);
1134 			error = EINVAL;
1135 			goto out;
1136 		}
1137 		args.flags |= NFSMNT_ACDIRMAX;
1138 	}
1139 	if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
1140 		ret = sscanf(opt, "%d", &args.wcommitsize);
1141 		if (ret != 1 || args.wcommitsize < 0) {
1142 			vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
1143 			error = EINVAL;
1144 			goto out;
1145 		}
1146 		args.flags |= NFSMNT_WCOMMITSIZE;
1147 	}
1148 	if (vfs_getopt(mp->mnt_optnew, "timeo", (void **)&opt, NULL) == 0) {
1149 		ret = sscanf(opt, "%d", &args.timeo);
1150 		if (ret != 1 || args.timeo <= 0) {
1151 			vfs_mount_error(mp, "illegal timeo: %s",
1152 			    opt);
1153 			error = EINVAL;
1154 			goto out;
1155 		}
1156 		args.flags |= NFSMNT_TIMEO;
1157 	}
1158 	if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1159 		ret = sscanf(opt, "%d", &args.timeo);
1160 		if (ret != 1 || args.timeo <= 0) {
1161 			vfs_mount_error(mp, "illegal timeout: %s",
1162 			    opt);
1163 			error = EINVAL;
1164 			goto out;
1165 		}
1166 		args.flags |= NFSMNT_TIMEO;
1167 	}
1168 	if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
1169 		ret = sscanf(opt, "%d", &nametimeo);
1170 		if (ret != 1 || nametimeo < 0) {
1171 			vfs_mount_error(mp, "illegal nametimeo: %s", opt);
1172 			error = EINVAL;
1173 			goto out;
1174 		}
1175 	}
1176 	if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1177 	    == 0) {
1178 		ret = sscanf(opt, "%d", &negnametimeo);
1179 		if (ret != 1 || negnametimeo < 0) {
1180 			vfs_mount_error(mp, "illegal negnametimeo: %s",
1181 			    opt);
1182 			error = EINVAL;
1183 			goto out;
1184 		}
1185 	}
1186 	if (vfs_getopt(mp->mnt_optnew, "minorversion", (void **)&opt, NULL) ==
1187 	    0) {
1188 		ret = sscanf(opt, "%d", &minvers);
1189 		if (ret != 1 || minvers < 0 || minvers > 2 ||
1190 		    (args.flags & NFSMNT_NFSV4) == 0) {
1191 			vfs_mount_error(mp, "illegal minorversion: %s", opt);
1192 			error = EINVAL;
1193 			goto out;
1194 		}
1195 	}
1196 	if (vfs_getopt(mp->mnt_optnew, "nconnect", (void **)&opt, NULL) ==
1197 	    0) {
1198 		ret = sscanf(opt, "%d", &aconn);
1199 		if (ret != 1 || aconn < 1 || aconn > NFS_MAXNCONN) {
1200 			vfs_mount_error(mp, "illegal nconnect: %s", opt);
1201 			error = EINVAL;
1202 			goto out;
1203 		}
1204 		/*
1205 		 * Setting nconnect=1 is a no-op, allowed so that
1206 		 * the option can be used in a Linux compatible way.
1207 		 */
1208 		aconn--;
1209 	}
1210 	if (vfs_getopt(mp->mnt_optnew, "sec",
1211 		(void **) &secname, NULL) == 0)
1212 		nfs_sec_name(secname, &args.flags);
1213 
1214 	if (mp->mnt_flag & MNT_UPDATE) {
1215 		struct nfsmount *nmp = VFSTONFS(mp);
1216 
1217 		if (nmp == NULL) {
1218 			error = EIO;
1219 			goto out;
1220 		}
1221 
1222 		/*
1223 		 * If a change from TCP->UDP is done and there are thread(s)
1224 		 * that have I/O RPC(s) in progress with a transfer size
1225 		 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1226 		 * hung, retrying the RPC(s) forever. Usually these threads
1227 		 * will be seen doing an uninterruptible sleep on wait channel
1228 		 * "nfsreq".
1229 		 */
1230 		if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1231 			tprintf(td->td_proc, LOG_WARNING,
1232 	"Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1233 
1234 		/*
1235 		 * When doing an update, we can't change version,
1236 		 * security, switch lockd strategies, change cookie
1237 		 * translation or switch oneopenown.
1238 		 */
1239 		args.flags = (args.flags &
1240 		    ~(NFSMNT_NFSV3 |
1241 		      NFSMNT_NFSV4 |
1242 		      NFSMNT_KERB |
1243 		      NFSMNT_INTEGRITY |
1244 		      NFSMNT_PRIVACY |
1245 		      NFSMNT_ONEOPENOWN |
1246 		      NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1247 		    (nmp->nm_flag &
1248 			(NFSMNT_NFSV3 |
1249 			 NFSMNT_NFSV4 |
1250 			 NFSMNT_KERB |
1251 			 NFSMNT_INTEGRITY |
1252 			 NFSMNT_PRIVACY |
1253 			 NFSMNT_ONEOPENOWN |
1254 			 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1255 		nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1256 		goto out;
1257 	}
1258 
1259 	/*
1260 	 * Make the nfs_ip_paranoia sysctl serve as the default connection
1261 	 * or no-connection mode for those protocols that support
1262 	 * no-connection mode (the flag will be cleared later for protocols
1263 	 * that do not support no-connection mode).  This will allow a client
1264 	 * to receive replies from a different IP then the request was
1265 	 * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
1266 	 * not 0.
1267 	 */
1268 	if (nfs_ip_paranoia == 0)
1269 		args.flags |= NFSMNT_NOCONN;
1270 
1271 	if (has_nfs_args_opt != 0) {
1272 		/*
1273 		 * In the 'nfs_args' case, the pointers in the args
1274 		 * structure are in userland - we copy them in here.
1275 		 */
1276 		if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1277 			vfs_mount_error(mp, "Bad file handle");
1278 			error = EINVAL;
1279 			goto out;
1280 		}
1281 		error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1282 		    args.fhsize);
1283 		if (error != 0)
1284 			goto out;
1285 		error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1286 		if (error != 0)
1287 			goto out;
1288 		bzero(&hst[hstlen], MNAMELEN - hstlen);
1289 		args.hostname = hst;
1290 		/* getsockaddr() call must be after above copyin() calls */
1291 		error = getsockaddr(&nam, args.addr, args.addrlen);
1292 		if (error != 0)
1293 			goto out;
1294 	} else if (nfs_mount_parse_from(mp->mnt_optnew,
1295 	    &args.hostname, (struct sockaddr_in **)&nam, dirpath,
1296 	    sizeof(dirpath), &dirlen) == 0) {
1297 		has_nfs_from_opt = 1;
1298 		bcopy(args.hostname, hst, MNAMELEN);
1299 		hst[MNAMELEN - 1] = '\0';
1300 
1301 		/*
1302 		 * This only works with NFSv4 for now.
1303 		 */
1304 		args.fhsize = 0;
1305 		args.flags |= NFSMNT_NFSV4;
1306 		args.sotype = SOCK_STREAM;
1307 	} else {
1308 		if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1309 		    &args.fhsize) == 0) {
1310 			if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1311 				vfs_mount_error(mp, "Bad file handle");
1312 				error = EINVAL;
1313 				goto out;
1314 			}
1315 			bcopy(args.fh, nfh, args.fhsize);
1316 		} else {
1317 			args.fhsize = 0;
1318 		}
1319 		(void) vfs_getopt(mp->mnt_optnew, "hostname",
1320 		    (void **)&args.hostname, &len);
1321 		if (args.hostname == NULL) {
1322 			vfs_mount_error(mp, "Invalid hostname");
1323 			error = EINVAL;
1324 			goto out;
1325 		}
1326 		if (len >= MNAMELEN) {
1327 			vfs_mount_error(mp, "Hostname too long");
1328 			error = EINVAL;
1329 			goto out;
1330 		}
1331 		bcopy(args.hostname, hst, len);
1332 		hst[len] = '\0';
1333 	}
1334 
1335 	if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1336 		strlcpy(srvkrbname, name, sizeof (srvkrbname));
1337 	else {
1338 		snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1339 		cp = strchr(srvkrbname, ':');
1340 		if (cp != NULL)
1341 			*cp = '\0';
1342 	}
1343 	srvkrbnamelen = strlen(srvkrbname);
1344 
1345 	if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1346 		strlcpy(krbname, name, sizeof (krbname));
1347 	else
1348 		krbname[0] = '\0';
1349 	krbnamelen = strlen(krbname);
1350 
1351 	if (has_nfs_from_opt == 0) {
1352 		if (vfs_getopt(mp->mnt_optnew,
1353 		    "dirpath", (void **)&name, NULL) == 0)
1354 			strlcpy(dirpath, name, sizeof (dirpath));
1355 		else
1356 			dirpath[0] = '\0';
1357 		dirlen = strlen(dirpath);
1358 	}
1359 
1360 	if (has_nfs_args_opt == 0 && has_nfs_from_opt == 0) {
1361 		if (vfs_getopt(mp->mnt_optnew, "addr",
1362 		    (void **)&args.addr, &args.addrlen) == 0) {
1363 			if (args.addrlen > SOCK_MAXADDRLEN) {
1364 				error = ENAMETOOLONG;
1365 				goto out;
1366 			}
1367 			nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1368 			bcopy(args.addr, nam, args.addrlen);
1369 			nam->sa_len = args.addrlen;
1370 		} else {
1371 			vfs_mount_error(mp, "No server address");
1372 			error = EINVAL;
1373 			goto out;
1374 		}
1375 	}
1376 
1377 	if (aconn > 0 && (args.sotype != SOCK_STREAM ||
1378 	    (args.flags & NFSMNT_NFSV4) == 0 || minvers == 0)) {
1379 		/*
1380 		 * RFC 5661 requires that an NFSv4.1/4.2 server
1381 		 * send an RPC reply on the same TCP connection
1382 		 * as the one it received the request on.
1383 		 * This property in required for "nconnect" and
1384 		 * might not be the case for NFSv3 or NFSv4.0 servers.
1385 		 */
1386 		vfs_mount_error(mp, "nconnect should only be used "
1387 		    "for NFSv4.1/4.2 mounts");
1388 		error = EINVAL;
1389 		goto out;
1390 	}
1391 
1392 	args.fh = nfh;
1393 	error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1394 	    dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1395 	    nametimeo, negnametimeo, minvers, newflag, tlscertname, aconn);
1396 out:
1397 	if (!error) {
1398 		MNT_ILOCK(mp);
1399 		mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF |
1400 		    MNTK_USES_BCACHE;
1401 		if ((VFSTONFS(mp)->nm_flag & NFSMNT_NFSV4) != 0)
1402 			mp->mnt_kern_flag |= MNTK_NULL_NOCACHE;
1403 		MNT_IUNLOCK(mp);
1404 	}
1405 	free(hst, M_TEMP);
1406 	return (error);
1407 }
1408 
1409 /*
1410  * VFS Operations.
1411  *
1412  * mount system call
1413  * It seems a bit dumb to copyinstr() the host and path here and then
1414  * bcopy() them in mountnfs(), but I wanted to detect errors before
1415  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
1416  * an error after that means that I have to release the mbuf.
1417  */
1418 /* ARGSUSED */
1419 static int
1420 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1421 {
1422 	int error;
1423 	struct nfs_args args;
1424 
1425 	error = copyin(data, &args, sizeof (struct nfs_args));
1426 	if (error)
1427 		return error;
1428 
1429 	ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1430 
1431 	error = kernel_mount(ma, flags);
1432 	return (error);
1433 }
1434 
1435 /*
1436  * Common code for mount and mountroot
1437  */
1438 static int
1439 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1440     char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1441     u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1442     struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
1443     int minvers, uint32_t newflag, char *tlscertname, int aconn)
1444 {
1445 	struct nfsmount *nmp;
1446 	struct nfsnode *np;
1447 	int error, trycnt, ret;
1448 	struct nfsvattr nfsva;
1449 	struct nfsclclient *clp;
1450 	struct nfsclds *dsp, *tdsp;
1451 	uint32_t lease;
1452 	bool tryminvers;
1453 	static u_int64_t clval = 0;
1454 #ifdef KERN_TLS
1455 	u_int maxlen;
1456 #endif
1457 
1458 	NFSCL_DEBUG(3, "in mnt\n");
1459 	clp = NULL;
1460 	if (mp->mnt_flag & MNT_UPDATE) {
1461 		nmp = VFSTONFS(mp);
1462 		printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1463 		free(nam, M_SONAME);
1464 		free(tlscertname, M_NEWNFSMNT);
1465 		return (0);
1466 	} else {
1467 		/* NFS-over-TLS requires that rpctls be functioning. */
1468 		if ((newflag & NFSMNT_TLS) != 0) {
1469 			error = EINVAL;
1470 #ifdef KERN_TLS
1471 			/* KERN_TLS is only supported for TCP. */
1472 			if (argp->sotype == SOCK_STREAM &&
1473 			    rpctls_getinfo(&maxlen, true, false))
1474 				error = 0;
1475 #endif
1476 			if (error != 0) {
1477 				free(nam, M_SONAME);
1478 				free(tlscertname, M_NEWNFSMNT);
1479 				return (error);
1480 			}
1481 		}
1482 		nmp = malloc(sizeof (struct nfsmount) +
1483 		    krbnamelen + dirlen + srvkrbnamelen + 2,
1484 		    M_NEWNFSMNT, M_WAITOK | M_ZERO);
1485 		nmp->nm_tlscertname = tlscertname;
1486 		nmp->nm_newflag = newflag;
1487 		TAILQ_INIT(&nmp->nm_bufq);
1488 		TAILQ_INIT(&nmp->nm_sess);
1489 		if (clval == 0)
1490 			clval = (u_int64_t)nfsboottime.tv_sec;
1491 		nmp->nm_clval = clval++;
1492 		nmp->nm_krbnamelen = krbnamelen;
1493 		nmp->nm_dirpathlen = dirlen;
1494 		nmp->nm_srvkrbnamelen = srvkrbnamelen;
1495 		if (td->td_ucred->cr_uid != (uid_t)0) {
1496 			/*
1497 			 * nm_uid is used to get KerberosV credentials for
1498 			 * the nfsv4 state handling operations if there is
1499 			 * no host based principal set. Use the uid of
1500 			 * this user if not root, since they are doing the
1501 			 * mount. I don't think setting this for root will
1502 			 * work, since root normally does not have user
1503 			 * credentials in a credentials cache.
1504 			 */
1505 			nmp->nm_uid = td->td_ucred->cr_uid;
1506 		} else {
1507 			/*
1508 			 * Just set to -1, so it won't be used.
1509 			 */
1510 			nmp->nm_uid = (uid_t)-1;
1511 		}
1512 
1513 		/* Copy and null terminate all the names */
1514 		if (nmp->nm_krbnamelen > 0) {
1515 			bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1516 			nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1517 		}
1518 		if (nmp->nm_dirpathlen > 0) {
1519 			bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1520 			    nmp->nm_dirpathlen);
1521 			nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1522 			    + 1] = '\0';
1523 		}
1524 		if (nmp->nm_srvkrbnamelen > 0) {
1525 			bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1526 			    nmp->nm_srvkrbnamelen);
1527 			nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1528 			    + nmp->nm_srvkrbnamelen + 2] = '\0';
1529 		}
1530 		nmp->nm_sockreq.nr_cred = crhold(cred);
1531 		mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1532 		mp->mnt_data = nmp;
1533 		nmp->nm_getinfo = nfs_getnlminfo;
1534 		nmp->nm_vinvalbuf = ncl_vinvalbuf;
1535 	}
1536 	vfs_getnewfsid(mp);
1537 	nmp->nm_mountp = mp;
1538 	mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1539 
1540 	/*
1541 	 * Since nfs_decode_args() might optionally set them, these
1542 	 * need to be set to defaults before the call, so that the
1543 	 * optional settings aren't overwritten.
1544 	 */
1545 	nmp->nm_nametimeo = nametimeo;
1546 	nmp->nm_negnametimeo = negnametimeo;
1547 	nmp->nm_timeo = NFS_TIMEO;
1548 	nmp->nm_retry = NFS_RETRANS;
1549 	nmp->nm_readahead = NFS_DEFRAHEAD;
1550 
1551 	/* This is empirical approximation of sqrt(hibufspace) * 256. */
1552 	nmp->nm_wcommitsize = NFS_MAXBSIZE / 256;
1553 	while ((long)nmp->nm_wcommitsize * nmp->nm_wcommitsize < hibufspace)
1554 		nmp->nm_wcommitsize *= 2;
1555 	nmp->nm_wcommitsize *= 256;
1556 
1557 	tryminvers = false;
1558 	if ((argp->flags & NFSMNT_NFSV4) != 0) {
1559 		if (minvers < 0) {
1560 			tryminvers = true;
1561 			minvers = NFSV42_MINORVERSION;
1562 		}
1563 		nmp->nm_minorvers = minvers;
1564 	} else
1565 		nmp->nm_minorvers = 0;
1566 
1567 	nfs_decode_args(mp, nmp, argp, hst, cred, td);
1568 
1569 	/*
1570 	 * V2 can only handle 32 bit filesizes.  A 4GB-1 limit may be too
1571 	 * high, depending on whether we end up with negative offsets in
1572 	 * the client or server somewhere.  2GB-1 may be safer.
1573 	 *
1574 	 * For V3, ncl_fsinfo will adjust this as necessary.  Assume maximum
1575 	 * that we can handle until we find out otherwise.
1576 	 */
1577 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1578 		nmp->nm_maxfilesize = 0xffffffffLL;
1579 	else
1580 		nmp->nm_maxfilesize = OFF_MAX;
1581 
1582 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1583 		nmp->nm_wsize = NFS_WSIZE;
1584 		nmp->nm_rsize = NFS_RSIZE;
1585 		nmp->nm_readdirsize = NFS_READDIRSIZE;
1586 	}
1587 	nmp->nm_numgrps = NFS_MAXGRPS;
1588 	nmp->nm_tprintf_delay = nfs_tprintf_delay;
1589 	if (nmp->nm_tprintf_delay < 0)
1590 		nmp->nm_tprintf_delay = 0;
1591 	nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1592 	if (nmp->nm_tprintf_initial_delay < 0)
1593 		nmp->nm_tprintf_initial_delay = 0;
1594 	nmp->nm_fhsize = argp->fhsize;
1595 	if (nmp->nm_fhsize > 0)
1596 		bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1597 	strlcpy(mp->mnt_stat.f_mntfromname, hst, MNAMELEN);
1598 	nmp->nm_nam = nam;
1599 	/* Set up the sockets and per-host congestion */
1600 	nmp->nm_sotype = argp->sotype;
1601 	nmp->nm_soproto = argp->proto;
1602 	nmp->nm_sockreq.nr_prog = NFS_PROG;
1603 	if ((argp->flags & NFSMNT_NFSV4))
1604 		nmp->nm_sockreq.nr_vers = NFS_VER4;
1605 	else if ((argp->flags & NFSMNT_NFSV3))
1606 		nmp->nm_sockreq.nr_vers = NFS_VER3;
1607 	else
1608 		nmp->nm_sockreq.nr_vers = NFS_VER2;
1609 
1610 	if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false,
1611 	    &nmp->nm_sockreq.nr_client)))
1612 		goto bad;
1613 	/* For NFSv4, get the clientid now. */
1614 	if ((argp->flags & NFSMNT_NFSV4) != 0) {
1615 		NFSCL_DEBUG(3, "at getcl\n");
1616 		error = nfscl_getcl(mp, cred, td, tryminvers, true, &clp);
1617 		NFSCL_DEBUG(3, "aft getcl=%d\n", error);
1618 		if (error != 0)
1619 			goto bad;
1620 		if (aconn > 0 && nmp->nm_minorvers == 0) {
1621 			vfs_mount_error(mp, "nconnect should only be used "
1622 			    "for NFSv4.1/4.2 mounts");
1623 			error = EINVAL;
1624 			goto bad;
1625 		}
1626 	}
1627 
1628 	if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1629 	    nmp->nm_dirpathlen > 0) {
1630 		NFSCL_DEBUG(3, "in dirp\n");
1631 		/*
1632 		 * If the fhsize on the mount point == 0 for V4, the mount
1633 		 * path needs to be looked up.
1634 		 */
1635 		trycnt = 3;
1636 		do {
1637 			error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1638 			    cred, td);
1639 			NFSCL_DEBUG(3, "aft dirp=%d\n", error);
1640 			if (error)
1641 				(void) nfs_catnap(PZERO, error, "nfsgetdirp");
1642 		} while (error && --trycnt > 0);
1643 		if (error)
1644 			goto bad;
1645 	}
1646 
1647 	/*
1648 	 * A reference count is needed on the nfsnode representing the
1649 	 * remote root.  If this object is not persistent, then backward
1650 	 * traversals of the mount point (i.e. "..") will not work if
1651 	 * the nfsnode gets flushed out of the cache. Ufs does not have
1652 	 * this problem, because one can identify root inodes by their
1653 	 * number == UFS_ROOTINO (2).
1654 	 */
1655 	if (nmp->nm_fhsize > 0) {
1656 		/*
1657 		 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1658 		 * non-zero for the root vnode. f_iosize will be set correctly
1659 		 * by nfs_statfs() before any I/O occurs.
1660 		 */
1661 		mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1662 		error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1663 		    LK_EXCLUSIVE);
1664 		if (error)
1665 			goto bad;
1666 		*vpp = NFSTOV(np);
1667 
1668 		/*
1669 		 * Get file attributes and transfer parameters for the
1670 		 * mountpoint.  This has the side effect of filling in
1671 		 * (*vpp)->v_type with the correct value.
1672 		 */
1673 		ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1674 		    cred, td, &nfsva, NULL, &lease);
1675 		if (ret) {
1676 			/*
1677 			 * Just set default values to get things going.
1678 			 */
1679 			NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1680 			nfsva.na_vattr.va_type = VDIR;
1681 			nfsva.na_vattr.va_mode = 0777;
1682 			nfsva.na_vattr.va_nlink = 100;
1683 			nfsva.na_vattr.va_uid = (uid_t)0;
1684 			nfsva.na_vattr.va_gid = (gid_t)0;
1685 			nfsva.na_vattr.va_fileid = 2;
1686 			nfsva.na_vattr.va_gen = 1;
1687 			nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1688 			nfsva.na_vattr.va_size = 512 * 1024;
1689 			lease = 60;
1690 		}
1691 		(void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1692 		if ((argp->flags & NFSMNT_NFSV4) != 0) {
1693 			NFSCL_DEBUG(3, "lease=%d\n", (int)lease);
1694 			NFSLOCKCLSTATE();
1695 			clp->nfsc_renew = NFSCL_RENEW(lease);
1696 			clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
1697 			clp->nfsc_clientidrev++;
1698 			if (clp->nfsc_clientidrev == 0)
1699 				clp->nfsc_clientidrev++;
1700 			NFSUNLOCKCLSTATE();
1701 			/*
1702 			 * Mount will succeed, so the renew thread can be
1703 			 * started now.
1704 			 */
1705 			nfscl_start_renewthread(clp);
1706 			nfscl_clientrelease(clp);
1707 		}
1708 		if (argp->flags & NFSMNT_NFSV3)
1709 			ncl_fsinfo(nmp, *vpp, cred, td);
1710 
1711 		/* Mark if the mount point supports NFSv4 ACLs. */
1712 		if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1713 		    ret == 0 &&
1714 		    NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1715 			MNT_ILOCK(mp);
1716 			mp->mnt_flag |= MNT_NFS4ACLS;
1717 			MNT_IUNLOCK(mp);
1718 		}
1719 
1720 		/* Can now allow additional connections. */
1721 		if (aconn > 0)
1722 			nmp->nm_aconnect = aconn;
1723 
1724 		/*
1725 		 * Lose the lock but keep the ref.
1726 		 */
1727 		NFSVOPUNLOCK(*vpp);
1728 		vfs_cache_root_set(mp, *vpp);
1729 		return (0);
1730 	}
1731 	error = EIO;
1732 
1733 bad:
1734 	if (clp != NULL)
1735 		nfscl_clientrelease(clp);
1736 	newnfs_disconnect(NULL, &nmp->nm_sockreq);
1737 	crfree(nmp->nm_sockreq.nr_cred);
1738 	if (nmp->nm_sockreq.nr_auth != NULL)
1739 		AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1740 	mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1741 	mtx_destroy(&nmp->nm_mtx);
1742 	if (nmp->nm_clp != NULL) {
1743 		NFSLOCKCLSTATE();
1744 		LIST_REMOVE(nmp->nm_clp, nfsc_list);
1745 		NFSUNLOCKCLSTATE();
1746 		free(nmp->nm_clp, M_NFSCLCLIENT);
1747 	}
1748 	TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1749 		if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1750 		    dsp->nfsclds_sockp != NULL)
1751 			newnfs_disconnect(NULL, dsp->nfsclds_sockp);
1752 		nfscl_freenfsclds(dsp);
1753 	}
1754 	free(nmp->nm_tlscertname, M_NEWNFSMNT);
1755 	free(nmp, M_NEWNFSMNT);
1756 	free(nam, M_SONAME);
1757 	return (error);
1758 }
1759 
1760 /*
1761  * unmount system call
1762  */
1763 static int
1764 nfs_unmount(struct mount *mp, int mntflags)
1765 {
1766 	struct thread *td;
1767 	struct nfsmount *nmp;
1768 	int error, flags = 0, i, trycnt = 0;
1769 	struct nfsclds *dsp, *tdsp;
1770 	struct nfscldeleg *dp, *ndp;
1771 	struct nfscldeleghead dh;
1772 
1773 	td = curthread;
1774 	TAILQ_INIT(&dh);
1775 
1776 	if (mntflags & MNT_FORCE)
1777 		flags |= FORCECLOSE;
1778 	nmp = VFSTONFS(mp);
1779 	error = 0;
1780 	/*
1781 	 * Goes something like this..
1782 	 * - Call vflush() to clear out vnodes for this filesystem
1783 	 * - Close the socket
1784 	 * - Free up the data structures
1785 	 */
1786 	/* In the forced case, cancel any outstanding requests. */
1787 	if (mntflags & MNT_FORCE) {
1788 		NFSDDSLOCK();
1789 		if (nfsv4_findmirror(nmp) != NULL)
1790 			error = ENXIO;
1791 		NFSDDSUNLOCK();
1792 		if (error)
1793 			goto out;
1794 		error = newnfs_nmcancelreqs(nmp);
1795 		if (error)
1796 			goto out;
1797 		/* For a forced close, get rid of the renew thread now */
1798 		nfscl_umount(nmp, td, &dh);
1799 	}
1800 	/* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1801 	do {
1802 		error = vflush(mp, 1, flags, td);
1803 		if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1804 			(void) nfs_catnap(PSOCK, error, "newndm");
1805 	} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1806 	if (error)
1807 		goto out;
1808 
1809 	/*
1810 	 * We are now committed to the unmount.
1811 	 */
1812 	if ((mntflags & MNT_FORCE) == 0)
1813 		nfscl_umount(nmp, td, NULL);
1814 	else {
1815 		mtx_lock(&nmp->nm_mtx);
1816 		nmp->nm_privflag |= NFSMNTP_FORCEDISM;
1817 		mtx_unlock(&nmp->nm_mtx);
1818 	}
1819 	/* Make sure no nfsiods are assigned to this mount. */
1820 	NFSLOCKIOD();
1821 	for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1822 		if (ncl_iodmount[i] == nmp) {
1823 			ncl_iodwant[i] = NFSIOD_AVAILABLE;
1824 			ncl_iodmount[i] = NULL;
1825 		}
1826 	NFSUNLOCKIOD();
1827 
1828 	/*
1829 	 * We can now set mnt_data to NULL and wait for
1830 	 * nfssvc(NFSSVC_FORCEDISM) to complete.
1831 	 */
1832 	mtx_lock(&mountlist_mtx);
1833 	mtx_lock(&nmp->nm_mtx);
1834 	mp->mnt_data = NULL;
1835 	mtx_unlock(&mountlist_mtx);
1836 	while ((nmp->nm_privflag & NFSMNTP_CANCELRPCS) != 0)
1837 		msleep(nmp, &nmp->nm_mtx, PVFS, "nfsfdism", 0);
1838 	mtx_unlock(&nmp->nm_mtx);
1839 
1840 	newnfs_disconnect(nmp, &nmp->nm_sockreq);
1841 	crfree(nmp->nm_sockreq.nr_cred);
1842 	free(nmp->nm_nam, M_SONAME);
1843 	if (nmp->nm_sockreq.nr_auth != NULL)
1844 		AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1845 	mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1846 	mtx_destroy(&nmp->nm_mtx);
1847 	TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1848 		if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1849 		    dsp->nfsclds_sockp != NULL)
1850 			newnfs_disconnect(NULL, dsp->nfsclds_sockp);
1851 		nfscl_freenfsclds(dsp);
1852 	}
1853 	free(nmp->nm_tlscertname, M_NEWNFSMNT);
1854 	free(nmp, M_NEWNFSMNT);
1855 
1856 	/* Free up the delegation structures for forced dismounts. */
1857 	TAILQ_FOREACH_SAFE(dp, &dh, nfsdl_list, ndp) {
1858 		TAILQ_REMOVE(&dh, dp, nfsdl_list);
1859 		free(dp, M_NFSCLDELEG);
1860 	}
1861 out:
1862 	return (error);
1863 }
1864 
1865 /*
1866  * Return root of a filesystem
1867  */
1868 static int
1869 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1870 {
1871 	struct vnode *vp;
1872 	struct nfsmount *nmp;
1873 	struct nfsnode *np;
1874 	int error;
1875 
1876 	nmp = VFSTONFS(mp);
1877 	error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1878 	if (error)
1879 		return error;
1880 	vp = NFSTOV(np);
1881 	/*
1882 	 * Get transfer parameters and attributes for root vnode once.
1883 	 */
1884 	mtx_lock(&nmp->nm_mtx);
1885 	if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1886 		mtx_unlock(&nmp->nm_mtx);
1887 		ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1888 	} else
1889 		mtx_unlock(&nmp->nm_mtx);
1890 	if (vp->v_type == VNON)
1891 	    vp->v_type = VDIR;
1892 	vp->v_vflag |= VV_ROOT;
1893 	*vpp = vp;
1894 	return (0);
1895 }
1896 
1897 /*
1898  * Flush out the buffer cache
1899  */
1900 /* ARGSUSED */
1901 static int
1902 nfs_sync(struct mount *mp, int waitfor)
1903 {
1904 	struct vnode *vp, *mvp;
1905 	struct thread *td;
1906 	int error, allerror = 0;
1907 
1908 	td = curthread;
1909 
1910 	MNT_ILOCK(mp);
1911 	/*
1912 	 * If a forced dismount is in progress, return from here so that
1913 	 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1914 	 * calling VFS_UNMOUNT().
1915 	 */
1916 	if (NFSCL_FORCEDISM(mp)) {
1917 		MNT_IUNLOCK(mp);
1918 		return (EBADF);
1919 	}
1920 	MNT_IUNLOCK(mp);
1921 
1922 	/*
1923 	 * Force stale buffer cache information to be flushed.
1924 	 */
1925 loop:
1926 	MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1927 		/* XXX Racy bv_cnt check. */
1928 		if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1929 		    waitfor == MNT_LAZY) {
1930 			VI_UNLOCK(vp);
1931 			continue;
1932 		}
1933 		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
1934 			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1935 			goto loop;
1936 		}
1937 		error = VOP_FSYNC(vp, waitfor, td);
1938 		if (error)
1939 			allerror = error;
1940 		NFSVOPUNLOCK(vp);
1941 		vrele(vp);
1942 	}
1943 	return (allerror);
1944 }
1945 
1946 static int
1947 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1948 {
1949 	struct nfsmount *nmp = VFSTONFS(mp);
1950 	struct vfsquery vq;
1951 	int error;
1952 
1953 	bzero(&vq, sizeof(vq));
1954 	switch (op) {
1955 #if 0
1956 	case VFS_CTL_NOLOCKS:
1957 		val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1958  		if (req->oldptr != NULL) {
1959  			error = SYSCTL_OUT(req, &val, sizeof(val));
1960  			if (error)
1961  				return (error);
1962  		}
1963  		if (req->newptr != NULL) {
1964  			error = SYSCTL_IN(req, &val, sizeof(val));
1965  			if (error)
1966  				return (error);
1967 			if (val)
1968 				nmp->nm_flag |= NFSMNT_NOLOCKS;
1969 			else
1970 				nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1971  		}
1972 		break;
1973 #endif
1974 	case VFS_CTL_QUERY:
1975 		mtx_lock(&nmp->nm_mtx);
1976 		if (nmp->nm_state & NFSSTA_TIMEO)
1977 			vq.vq_flags |= VQ_NOTRESP;
1978 		mtx_unlock(&nmp->nm_mtx);
1979 #if 0
1980 		if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1981 		    (nmp->nm_state & NFSSTA_LOCKTIMEO))
1982 			vq.vq_flags |= VQ_NOTRESPLOCK;
1983 #endif
1984 		error = SYSCTL_OUT(req, &vq, sizeof(vq));
1985 		break;
1986  	case VFS_CTL_TIMEO:
1987  		if (req->oldptr != NULL) {
1988  			error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1989  			    sizeof(nmp->nm_tprintf_initial_delay));
1990  			if (error)
1991  				return (error);
1992  		}
1993  		if (req->newptr != NULL) {
1994 			error = vfs_suser(mp, req->td);
1995 			if (error)
1996 				return (error);
1997  			error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1998  			    sizeof(nmp->nm_tprintf_initial_delay));
1999  			if (error)
2000  				return (error);
2001  			if (nmp->nm_tprintf_initial_delay < 0)
2002  				nmp->nm_tprintf_initial_delay = 0;
2003  		}
2004 		break;
2005 	default:
2006 		return (ENOTSUP);
2007 	}
2008 	return (0);
2009 }
2010 
2011 /*
2012  * Purge any RPCs in progress, so that they will all return errors.
2013  * This allows dounmount() to continue as far as VFS_UNMOUNT() for a
2014  * forced dismount.
2015  */
2016 static void
2017 nfs_purge(struct mount *mp)
2018 {
2019 	struct nfsmount *nmp = VFSTONFS(mp);
2020 
2021 	newnfs_nmcancelreqs(nmp);
2022 }
2023 
2024 /*
2025  * Extract the information needed by the nlm from the nfs vnode.
2026  */
2027 static void
2028 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
2029     struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
2030     struct timeval *timeop)
2031 {
2032 	struct nfsmount *nmp;
2033 	struct nfsnode *np = VTONFS(vp);
2034 
2035 	nmp = VFSTONFS(vp->v_mount);
2036 	if (fhlenp != NULL)
2037 		*fhlenp = (size_t)np->n_fhp->nfh_len;
2038 	if (fhp != NULL)
2039 		bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
2040 	if (sp != NULL)
2041 		bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
2042 	if (is_v3p != NULL)
2043 		*is_v3p = NFS_ISV3(vp);
2044 	if (sizep != NULL)
2045 		*sizep = np->n_size;
2046 	if (timeop != NULL) {
2047 		timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
2048 		timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
2049 	}
2050 }
2051 
2052 /*
2053  * This function prints out an option name, based on the conditional
2054  * argument.
2055  */
2056 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
2057     char *opt, char **buf, size_t *blen)
2058 {
2059 	int len;
2060 
2061 	if (testval != 0 && *blen > strlen(opt)) {
2062 		len = snprintf(*buf, *blen, "%s", opt);
2063 		if (len != strlen(opt))
2064 			printf("EEK!!\n");
2065 		*buf += len;
2066 		*blen -= len;
2067 	}
2068 }
2069 
2070 /*
2071  * This function printf out an options integer value.
2072  */
2073 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
2074     char *opt, char **buf, size_t *blen)
2075 {
2076 	int len;
2077 
2078 	if (*blen > strlen(opt) + 1) {
2079 		/* Could result in truncated output string. */
2080 		len = snprintf(*buf, *blen, "%s=%d", opt, optval);
2081 		if (len < *blen) {
2082 			*buf += len;
2083 			*blen -= len;
2084 		}
2085 	}
2086 }
2087 
2088 /*
2089  * Load the option flags and values into the buffer.
2090  */
2091 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
2092 {
2093 	char *buf;
2094 	size_t blen;
2095 
2096 	buf = buffer;
2097 	blen = buflen;
2098 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
2099 	    &blen);
2100 	if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) {
2101 		nfscl_printoptval(nmp, nmp->nm_minorvers, ",minorversion", &buf,
2102 		    &blen);
2103 		nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
2104 		    &buf, &blen);
2105 		nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_ONEOPENOWN) != 0 &&
2106 		    nmp->nm_minorvers > 0, ",oneopenown", &buf, &blen);
2107 	}
2108 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
2109 	    &blen);
2110 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
2111 	    "nfsv2", &buf, &blen);
2112 	nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
2113 	nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
2114 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
2115 	    &buf, &blen);
2116 	nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf,
2117 	    &blen);
2118 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
2119 	    &buf, &blen);
2120 	nfscl_printoptval(nmp, nmp->nm_aconnect + 1, ",nconnect", &buf, &blen);
2121 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
2122 	    &blen);
2123 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
2124 	    &blen);
2125 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
2126 	    &blen);
2127 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
2128 	    &blen);
2129 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
2130 	    &blen);
2131 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NONCONTIGWR) != 0,
2132 	    ",noncontigwr", &buf, &blen);
2133 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2134 	    0, ",lockd", &buf, &blen);
2135 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2136 	    NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
2137 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
2138 	    &buf, &blen);
2139 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
2140 	    &buf, &blen);
2141 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2142 	    NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
2143 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2144 	    NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
2145 	    &buf, &blen);
2146 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2147 	    NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
2148 	    &buf, &blen);
2149 	nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
2150 	nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
2151 	nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
2152 	nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
2153 	nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
2154 	nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
2155 	    &blen);
2156 	nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
2157 	nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
2158 	nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
2159 	    &blen);
2160 	nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
2161 	nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
2162 	    &blen);
2163 	nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
2164 	nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
2165 }
2166