xref: /freebsd/sys/fs/nfsclient/nfs_clvfsops.c (revision 1f1e2261)
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);
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);
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, 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);
374 	if (!error) {
375 		if (attrflag)
376 			(void) nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
377 		mtx_lock(&nmp->nm_mtx);
378 		nfscl_loadfsinfo(nmp, &fs);
379 		mtx_unlock(&nmp->nm_mtx);
380 	}
381 	return (error);
382 }
383 
384 /*
385  * Mount a remote root fs via. nfs. This depends on the info in the
386  * nfs_diskless structure that has been filled in properly by some primary
387  * bootstrap.
388  * It goes something like this:
389  * - do enough of "ifconfig" by calling ifioctl() so that the system
390  *   can talk to the server
391  * - If nfs_diskless.mygateway is filled in, use that address as
392  *   a default gateway.
393  * - build the rootfs mount point and call mountnfs() to do the rest.
394  *
395  * It is assumed to be safe to read, modify, and write the nfsv3_diskless
396  * structure, as well as other global NFS client variables here, as
397  * nfs_mountroot() will be called once in the boot before any other NFS
398  * client activity occurs.
399  */
400 static int
401 nfs_mountroot(struct mount *mp)
402 {
403 	struct thread *td = curthread;
404 	struct nfsv3_diskless *nd = &nfsv3_diskless;
405 	struct socket *so;
406 	struct vnode *vp;
407 	struct ifreq ir;
408 	int error;
409 	u_long l;
410 	char buf[128];
411 	char *cp;
412 
413 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
414 	bootpc_init();		/* use bootp to get nfs_diskless filled in */
415 #elif defined(NFS_ROOT)
416 	nfs_setup_diskless();
417 #endif
418 
419 	if (nfs_diskless_valid == 0)
420 		return (-1);
421 	if (nfs_diskless_valid == 1)
422 		nfs_convert_diskless();
423 
424 	/*
425 	 * Do enough of ifconfig(8) so that the critical net interface can
426 	 * talk to the server.
427 	 */
428 	error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
429 	    td->td_ucred, td);
430 	if (error)
431 		panic("nfs_mountroot: socreate(%04x): %d",
432 			nd->myif.ifra_addr.sa_family, error);
433 
434 #if 0 /* XXX Bad idea */
435 	/*
436 	 * We might not have been told the right interface, so we pass
437 	 * over the first ten interfaces of the same kind, until we get
438 	 * one of them configured.
439 	 */
440 
441 	for (i = strlen(nd->myif.ifra_name) - 1;
442 		nd->myif.ifra_name[i] >= '0' &&
443 		nd->myif.ifra_name[i] <= '9';
444 		nd->myif.ifra_name[i] ++) {
445 		error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
446 		if(!error)
447 			break;
448 	}
449 #endif
450 	error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
451 	if (error)
452 		panic("nfs_mountroot: SIOCAIFADDR: %d", error);
453 	if ((cp = kern_getenv("boot.netif.mtu")) != NULL) {
454 		ir.ifr_mtu = strtol(cp, NULL, 10);
455 		bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
456 		freeenv(cp);
457 		error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
458 		if (error)
459 			printf("nfs_mountroot: SIOCSIFMTU: %d", error);
460 	}
461 	soclose(so);
462 
463 	/*
464 	 * If the gateway field is filled in, set it as the default route.
465 	 * Note that pxeboot will set a default route of 0 if the route
466 	 * is not set by the DHCP server.  Check also for a value of 0
467 	 * to avoid panicking inappropriately in that situation.
468 	 */
469 	if (nd->mygateway.sin_len != 0 &&
470 	    nd->mygateway.sin_addr.s_addr != 0) {
471 		struct sockaddr_in mask, sin;
472 		struct epoch_tracker et;
473 		struct rt_addrinfo info;
474 		struct rib_cmd_info rc;
475 
476 		bzero((caddr_t)&mask, sizeof(mask));
477 		sin = mask;
478 		sin.sin_family = AF_INET;
479 		sin.sin_len = sizeof(sin);
480                 /* XXX MRT use table 0 for this sort of thing */
481 		NET_EPOCH_ENTER(et);
482 		CURVNET_SET(TD_TO_VNET(td));
483 
484 		bzero((caddr_t)&info, sizeof(info));
485 		info.rti_flags = RTF_UP | RTF_GATEWAY;
486 		info.rti_info[RTAX_DST] = (struct sockaddr *)&sin;
487 		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&nd->mygateway;
488 		info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask;
489 
490 		error = rib_action(RT_DEFAULT_FIB, RTM_ADD, &info, &rc);
491 		CURVNET_RESTORE();
492 		NET_EPOCH_EXIT(et);
493 		if (error)
494 			panic("nfs_mountroot: RTM_ADD: %d", error);
495 	}
496 
497 	/*
498 	 * Create the rootfs mount point.
499 	 */
500 	nd->root_args.fh = nd->root_fh;
501 	nd->root_args.fhsize = nd->root_fhsize;
502 	l = ntohl(nd->root_saddr.sin_addr.s_addr);
503 	snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
504 		(l >> 24) & 0xff, (l >> 16) & 0xff,
505 		(l >>  8) & 0xff, (l >>  0) & 0xff, nd->root_hostnam);
506 	printf("NFS ROOT: %s\n", buf);
507 	nd->root_args.hostname = buf;
508 	if ((error = nfs_mountdiskless(buf,
509 	    &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
510 		return (error);
511 	}
512 
513 	/*
514 	 * This is not really an nfs issue, but it is much easier to
515 	 * set hostname here and then let the "/etc/rc.xxx" files
516 	 * mount the right /var based upon its preset value.
517 	 */
518 	mtx_lock(&prison0.pr_mtx);
519 	strlcpy(prison0.pr_hostname, nd->my_hostnam,
520 	    sizeof(prison0.pr_hostname));
521 	mtx_unlock(&prison0.pr_mtx);
522 	inittodr(ntohl(nd->root_time));
523 	return (0);
524 }
525 
526 /*
527  * Internal version of mount system call for diskless setup.
528  */
529 static int
530 nfs_mountdiskless(char *path,
531     struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
532     struct vnode **vpp, struct mount *mp)
533 {
534 	struct sockaddr *nam;
535 	int dirlen, error;
536 	char *dirpath;
537 
538 	/*
539 	 * Find the directory path in "path", which also has the server's
540 	 * name/ip address in it.
541 	 */
542 	dirpath = strchr(path, ':');
543 	if (dirpath != NULL)
544 		dirlen = strlen(++dirpath);
545 	else
546 		dirlen = 0;
547 	nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
548 	if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
549 	    NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
550 	    NFS_DEFAULT_NEGNAMETIMEO, 0, 0, NULL, 0)) != 0) {
551 		printf("nfs_mountroot: mount %s on /: %d\n", path, error);
552 		return (error);
553 	}
554 	return (0);
555 }
556 
557 static void
558 nfs_sec_name(char *sec, int *flagsp)
559 {
560 	if (!strcmp(sec, "krb5"))
561 		*flagsp |= NFSMNT_KERB;
562 	else if (!strcmp(sec, "krb5i"))
563 		*flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
564 	else if (!strcmp(sec, "krb5p"))
565 		*flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
566 }
567 
568 static void
569 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
570     const char *hostname, struct ucred *cred, struct thread *td)
571 {
572 	int adjsock;
573 	char *p;
574 
575 	/*
576 	 * Set read-only flag if requested; otherwise, clear it if this is
577 	 * an update.  If this is not an update, then either the read-only
578 	 * flag is already clear, or this is a root mount and it was set
579 	 * intentionally at some previous point.
580 	 */
581 	if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
582 		MNT_ILOCK(mp);
583 		mp->mnt_flag |= MNT_RDONLY;
584 		MNT_IUNLOCK(mp);
585 	} else if (mp->mnt_flag & MNT_UPDATE) {
586 		MNT_ILOCK(mp);
587 		mp->mnt_flag &= ~MNT_RDONLY;
588 		MNT_IUNLOCK(mp);
589 	}
590 
591 	/*
592 	 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
593 	 * no sense in that context.  Also, set up appropriate retransmit
594 	 * and soft timeout behavior.
595 	 */
596 	if (argp->sotype == SOCK_STREAM) {
597 		nmp->nm_flag &= ~NFSMNT_NOCONN;
598 		nmp->nm_timeo = NFS_MAXTIMEO;
599 		if ((argp->flags & NFSMNT_NFSV4) != 0)
600 			nmp->nm_retry = INT_MAX;
601 		else
602 			nmp->nm_retry = NFS_RETRANS_TCP;
603 	}
604 
605 	/* Also clear RDIRPLUS if NFSv2, it crashes some servers */
606 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
607 		argp->flags &= ~NFSMNT_RDIRPLUS;
608 		nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
609 	}
610 
611 	/* Clear ONEOPENOWN for NFSv2, 3 and 4.0. */
612 	if (nmp->nm_minorvers == 0) {
613 		argp->flags &= ~NFSMNT_ONEOPENOWN;
614 		nmp->nm_flag &= ~NFSMNT_ONEOPENOWN;
615 	}
616 
617 	/* Re-bind if rsrvd port requested and wasn't on one */
618 	adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
619 		  && (argp->flags & NFSMNT_RESVPORT);
620 	/* Also re-bind if we're switching to/from a connected UDP socket */
621 	adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
622 		    (argp->flags & NFSMNT_NOCONN));
623 
624 	/* Update flags atomically.  Don't change the lock bits. */
625 	nmp->nm_flag = argp->flags | nmp->nm_flag;
626 
627 	if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
628 		nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
629 		if (nmp->nm_timeo < NFS_MINTIMEO)
630 			nmp->nm_timeo = NFS_MINTIMEO;
631 		else if (nmp->nm_timeo > NFS_MAXTIMEO)
632 			nmp->nm_timeo = NFS_MAXTIMEO;
633 	}
634 
635 	if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
636 		nmp->nm_retry = argp->retrans;
637 		if (nmp->nm_retry > NFS_MAXREXMIT)
638 			nmp->nm_retry = NFS_MAXREXMIT;
639 	}
640 
641 	if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
642 		nmp->nm_wsize = argp->wsize;
643 		/*
644 		 * Clip at the power of 2 below the size. There is an
645 		 * issue (not isolated) that causes intermittent page
646 		 * faults if this is not done.
647 		 */
648 		if (nmp->nm_wsize > NFS_FABLKSIZE)
649 			nmp->nm_wsize = 1 << (fls(nmp->nm_wsize) - 1);
650 		else
651 			nmp->nm_wsize = NFS_FABLKSIZE;
652 	}
653 
654 	if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
655 		nmp->nm_rsize = argp->rsize;
656 		/*
657 		 * Clip at the power of 2 below the size. There is an
658 		 * issue (not isolated) that causes intermittent page
659 		 * faults if this is not done.
660 		 */
661 		if (nmp->nm_rsize > NFS_FABLKSIZE)
662 			nmp->nm_rsize = 1 << (fls(nmp->nm_rsize) - 1);
663 		else
664 			nmp->nm_rsize = NFS_FABLKSIZE;
665 	}
666 
667 	if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
668 		nmp->nm_readdirsize = argp->readdirsize;
669 	}
670 
671 	if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
672 		nmp->nm_acregmin = argp->acregmin;
673 	else
674 		nmp->nm_acregmin = NFS_MINATTRTIMO;
675 	if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
676 		nmp->nm_acregmax = argp->acregmax;
677 	else
678 		nmp->nm_acregmax = NFS_MAXATTRTIMO;
679 	if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
680 		nmp->nm_acdirmin = argp->acdirmin;
681 	else
682 		nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
683 	if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
684 		nmp->nm_acdirmax = argp->acdirmax;
685 	else
686 		nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
687 	if (nmp->nm_acdirmin > nmp->nm_acdirmax)
688 		nmp->nm_acdirmin = nmp->nm_acdirmax;
689 	if (nmp->nm_acregmin > nmp->nm_acregmax)
690 		nmp->nm_acregmin = nmp->nm_acregmax;
691 
692 	if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
693 		if (argp->readahead <= NFS_MAXRAHEAD)
694 			nmp->nm_readahead = argp->readahead;
695 		else
696 			nmp->nm_readahead = NFS_MAXRAHEAD;
697 	}
698 	if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
699 		if (argp->wcommitsize < nmp->nm_wsize)
700 			nmp->nm_wcommitsize = nmp->nm_wsize;
701 		else
702 			nmp->nm_wcommitsize = argp->wcommitsize;
703 	}
704 
705 	adjsock |= ((nmp->nm_sotype != argp->sotype) ||
706 		    (nmp->nm_soproto != argp->proto));
707 
708 	if (nmp->nm_client != NULL && adjsock) {
709 		int haslock = 0, error = 0;
710 
711 		if (nmp->nm_sotype == SOCK_STREAM) {
712 			error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
713 			if (!error)
714 				haslock = 1;
715 		}
716 		if (!error) {
717 		    newnfs_disconnect(nmp, &nmp->nm_sockreq);
718 		    if (haslock)
719 			newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
720 		    nmp->nm_sotype = argp->sotype;
721 		    nmp->nm_soproto = argp->proto;
722 		    if (nmp->nm_sotype == SOCK_DGRAM)
723 			while (newnfs_connect(nmp, &nmp->nm_sockreq,
724 			    cred, td, 0, false, &nmp->nm_sockreq.nr_client)) {
725 				printf("newnfs_args: retrying connect\n");
726 				(void) nfs_catnap(PSOCK, 0, "nfscon");
727 			}
728 		}
729 	} else {
730 		nmp->nm_sotype = argp->sotype;
731 		nmp->nm_soproto = argp->proto;
732 	}
733 
734 	if (hostname != NULL) {
735 		strlcpy(nmp->nm_hostname, hostname,
736 		    sizeof(nmp->nm_hostname));
737 		p = strchr(nmp->nm_hostname, ':');
738 		if (p != NULL)
739 			*p = '\0';
740 	}
741 }
742 
743 static const char *nfs_opts[] = { "from", "nfs_args",
744     "noac", "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
745     "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
746     "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
747     "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
748     "retrans", "actimeo", "acregmin", "acregmax", "acdirmin", "acdirmax",
749     "resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh",
750     "nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath",
751     "minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr",
752     "pnfs", "wcommitsize", "oneopenown", "tls", "tlscertname", "nconnect",
753     NULL };
754 
755 /*
756  * Parse the "from" mountarg, passed by the generic mount(8) program
757  * or the mountroot code.  This is used when rerooting into NFS.
758  *
759  * Note that the "hostname" is actually a "hostname:/share/path" string.
760  */
761 static int
762 nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep,
763     struct sockaddr_in **sinp, char *dirpath, size_t dirpathsize, int *dirlenp)
764 {
765 	char *nam, *delimp, *hostp, *spec;
766 	int error, have_bracket = 0, offset, rv, speclen;
767 	struct sockaddr_in *sin;
768 	size_t len;
769 
770 	error = vfs_getopt(opts, "from", (void **)&spec, &speclen);
771 	if (error != 0)
772 		return (error);
773 	nam = malloc(MNAMELEN + 1, M_TEMP, M_WAITOK);
774 
775 	/*
776 	 * This part comes from sbin/mount_nfs/mount_nfs.c:getnfsargs().
777 	 */
778 	if (*spec == '[' && (delimp = strchr(spec + 1, ']')) != NULL &&
779 	    *(delimp + 1) == ':') {
780 		hostp = spec + 1;
781 		spec = delimp + 2;
782 		have_bracket = 1;
783 	} else if ((delimp = strrchr(spec, ':')) != NULL) {
784 		hostp = spec;
785 		spec = delimp + 1;
786 	} else if ((delimp = strrchr(spec, '@')) != NULL) {
787 		printf("%s: path@server syntax is deprecated, "
788 		    "use server:path\n", __func__);
789 		hostp = delimp + 1;
790 	} else {
791 		printf("%s: no <host>:<dirpath> nfs-name\n", __func__);
792 		free(nam, M_TEMP);
793 		return (EINVAL);
794 	}
795 	*delimp = '\0';
796 
797 	/*
798 	 * If there has been a trailing slash at mounttime it seems
799 	 * that some mountd implementations fail to remove the mount
800 	 * entries from their mountlist while unmounting.
801 	 */
802 	for (speclen = strlen(spec);
803 	    speclen > 1 && spec[speclen - 1] == '/';
804 	    speclen--)
805 		spec[speclen - 1] = '\0';
806 	if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) {
807 		printf("%s: %s:%s: name too long", __func__, hostp, spec);
808 		free(nam, M_TEMP);
809 		return (EINVAL);
810 	}
811 	/* Make both '@' and ':' notations equal */
812 	if (*hostp != '\0') {
813 		len = strlen(hostp);
814 		offset = 0;
815 		if (have_bracket)
816 			nam[offset++] = '[';
817 		memmove(nam + offset, hostp, len);
818 		if (have_bracket)
819 			nam[len + offset++] = ']';
820 		nam[len + offset++] = ':';
821 		memmove(nam + len + offset, spec, speclen);
822 		nam[len + speclen + offset] = '\0';
823 	} else
824 		nam[0] = '\0';
825 
826 	/*
827 	 * XXX: IPv6
828 	 */
829 	sin = malloc(sizeof(*sin), M_SONAME, M_WAITOK);
830 	rv = inet_pton(AF_INET, hostp, &sin->sin_addr);
831 	if (rv != 1) {
832 		printf("%s: cannot parse '%s', inet_pton() returned %d\n",
833 		    __func__, hostp, rv);
834 		free(nam, M_TEMP);
835 		free(sin, M_SONAME);
836 		return (EINVAL);
837 	}
838 
839 	sin->sin_len = sizeof(*sin);
840 	sin->sin_family = AF_INET;
841 	/*
842 	 * XXX: hardcoded port number.
843 	 */
844 	sin->sin_port = htons(2049);
845 
846 	*hostnamep = strdup(nam, M_NEWNFSMNT);
847 	*sinp = sin;
848 	strlcpy(dirpath, spec, dirpathsize);
849 	*dirlenp = strlen(dirpath);
850 
851 	free(nam, M_TEMP);
852 	return (0);
853 }
854 
855 /*
856  * VFS Operations.
857  *
858  * mount system call
859  * It seems a bit dumb to copyinstr() the host and path here and then
860  * bcopy() them in mountnfs(), but I wanted to detect errors before
861  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
862  * an error after that means that I have to release the mbuf.
863  */
864 /* ARGSUSED */
865 static int
866 nfs_mount(struct mount *mp)
867 {
868 	struct nfs_args args = {
869 	    .version = NFS_ARGSVERSION,
870 	    .addr = NULL,
871 	    .addrlen = sizeof (struct sockaddr_in),
872 	    .sotype = SOCK_STREAM,
873 	    .proto = 0,
874 	    .fh = NULL,
875 	    .fhsize = 0,
876 	    .flags = NFSMNT_RESVPORT,
877 	    .wsize = NFS_WSIZE,
878 	    .rsize = NFS_RSIZE,
879 	    .readdirsize = NFS_READDIRSIZE,
880 	    .timeo = 10,
881 	    .retrans = NFS_RETRANS,
882 	    .readahead = NFS_DEFRAHEAD,
883 	    .wcommitsize = 0,			/* was: NQ_DEFLEASE */
884 	    .hostname = NULL,
885 	    .acregmin = NFS_MINATTRTIMO,
886 	    .acregmax = NFS_MAXATTRTIMO,
887 	    .acdirmin = NFS_MINDIRATTRTIMO,
888 	    .acdirmax = NFS_MAXDIRATTRTIMO,
889 	};
890 	int error = 0, ret, len;
891 	struct sockaddr *nam = NULL;
892 	struct vnode *vp;
893 	struct thread *td;
894 	char *hst;
895 	u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
896 	char *cp, *opt, *name, *secname, *tlscertname;
897 	int nametimeo = NFS_DEFAULT_NAMETIMEO;
898 	int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
899 	int minvers = -1;
900 	int dirlen, has_nfs_args_opt, has_nfs_from_opt,
901 	    krbnamelen, srvkrbnamelen;
902 	size_t hstlen;
903 	uint32_t newflag;
904 	int aconn = 0;
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, "nconnect", (void **)&opt, NULL) ==
1196 	    0) {
1197 		ret = sscanf(opt, "%d", &aconn);
1198 		if (ret != 1 || aconn < 1 || aconn > NFS_MAXNCONN) {
1199 			vfs_mount_error(mp, "illegal nconnect: %s", opt);
1200 			error = EINVAL;
1201 			goto out;
1202 		}
1203 		/*
1204 		 * Setting nconnect=1 is a no-op, allowed so that
1205 		 * the option can be used in a Linux compatible way.
1206 		 */
1207 		aconn--;
1208 	}
1209 	if (vfs_getopt(mp->mnt_optnew, "sec",
1210 		(void **) &secname, NULL) == 0)
1211 		nfs_sec_name(secname, &args.flags);
1212 
1213 	if (mp->mnt_flag & MNT_UPDATE) {
1214 		struct nfsmount *nmp = VFSTONFS(mp);
1215 
1216 		if (nmp == NULL) {
1217 			error = EIO;
1218 			goto out;
1219 		}
1220 
1221 		/*
1222 		 * If a change from TCP->UDP is done and there are thread(s)
1223 		 * that have I/O RPC(s) in progress with a transfer size
1224 		 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1225 		 * hung, retrying the RPC(s) forever. Usually these threads
1226 		 * will be seen doing an uninterruptible sleep on wait channel
1227 		 * "nfsreq".
1228 		 */
1229 		if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1230 			tprintf(td->td_proc, LOG_WARNING,
1231 	"Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1232 
1233 		/*
1234 		 * When doing an update, we can't change version,
1235 		 * security, switch lockd strategies, change cookie
1236 		 * translation or switch oneopenown.
1237 		 */
1238 		args.flags = (args.flags &
1239 		    ~(NFSMNT_NFSV3 |
1240 		      NFSMNT_NFSV4 |
1241 		      NFSMNT_KERB |
1242 		      NFSMNT_INTEGRITY |
1243 		      NFSMNT_PRIVACY |
1244 		      NFSMNT_ONEOPENOWN |
1245 		      NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1246 		    (nmp->nm_flag &
1247 			(NFSMNT_NFSV3 |
1248 			 NFSMNT_NFSV4 |
1249 			 NFSMNT_KERB |
1250 			 NFSMNT_INTEGRITY |
1251 			 NFSMNT_PRIVACY |
1252 			 NFSMNT_ONEOPENOWN |
1253 			 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1254 		nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1255 		goto out;
1256 	}
1257 
1258 	/*
1259 	 * Make the nfs_ip_paranoia sysctl serve as the default connection
1260 	 * or no-connection mode for those protocols that support
1261 	 * no-connection mode (the flag will be cleared later for protocols
1262 	 * that do not support no-connection mode).  This will allow a client
1263 	 * to receive replies from a different IP then the request was
1264 	 * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
1265 	 * not 0.
1266 	 */
1267 	if (nfs_ip_paranoia == 0)
1268 		args.flags |= NFSMNT_NOCONN;
1269 
1270 	if (has_nfs_args_opt != 0) {
1271 		/*
1272 		 * In the 'nfs_args' case, the pointers in the args
1273 		 * structure are in userland - we copy them in here.
1274 		 */
1275 		if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1276 			vfs_mount_error(mp, "Bad file handle");
1277 			error = EINVAL;
1278 			goto out;
1279 		}
1280 		error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1281 		    args.fhsize);
1282 		if (error != 0)
1283 			goto out;
1284 		error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1285 		if (error != 0)
1286 			goto out;
1287 		bzero(&hst[hstlen], MNAMELEN - hstlen);
1288 		args.hostname = hst;
1289 		/* getsockaddr() call must be after above copyin() calls */
1290 		error = getsockaddr(&nam, args.addr, args.addrlen);
1291 		if (error != 0)
1292 			goto out;
1293 	} else if (nfs_mount_parse_from(mp->mnt_optnew,
1294 	    &args.hostname, (struct sockaddr_in **)&nam, dirpath,
1295 	    sizeof(dirpath), &dirlen) == 0) {
1296 		has_nfs_from_opt = 1;
1297 		bcopy(args.hostname, hst, MNAMELEN);
1298 		hst[MNAMELEN - 1] = '\0';
1299 
1300 		/*
1301 		 * This only works with NFSv4 for now.
1302 		 */
1303 		args.fhsize = 0;
1304 		args.flags |= NFSMNT_NFSV4;
1305 		args.sotype = SOCK_STREAM;
1306 	} else {
1307 		if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1308 		    &args.fhsize) == 0) {
1309 			if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1310 				vfs_mount_error(mp, "Bad file handle");
1311 				error = EINVAL;
1312 				goto out;
1313 			}
1314 			bcopy(args.fh, nfh, args.fhsize);
1315 		} else {
1316 			args.fhsize = 0;
1317 		}
1318 		(void) vfs_getopt(mp->mnt_optnew, "hostname",
1319 		    (void **)&args.hostname, &len);
1320 		if (args.hostname == NULL) {
1321 			vfs_mount_error(mp, "Invalid hostname");
1322 			error = EINVAL;
1323 			goto out;
1324 		}
1325 		if (len >= MNAMELEN) {
1326 			vfs_mount_error(mp, "Hostname too long");
1327 			error = EINVAL;
1328 			goto out;
1329 		}
1330 		bcopy(args.hostname, hst, len);
1331 		hst[len] = '\0';
1332 	}
1333 
1334 	if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1335 		strlcpy(srvkrbname, name, sizeof (srvkrbname));
1336 	else {
1337 		snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1338 		cp = strchr(srvkrbname, ':');
1339 		if (cp != NULL)
1340 			*cp = '\0';
1341 	}
1342 	srvkrbnamelen = strlen(srvkrbname);
1343 
1344 	if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1345 		strlcpy(krbname, name, sizeof (krbname));
1346 	else
1347 		krbname[0] = '\0';
1348 	krbnamelen = strlen(krbname);
1349 
1350 	if (has_nfs_from_opt == 0) {
1351 		if (vfs_getopt(mp->mnt_optnew,
1352 		    "dirpath", (void **)&name, NULL) == 0)
1353 			strlcpy(dirpath, name, sizeof (dirpath));
1354 		else
1355 			dirpath[0] = '\0';
1356 		dirlen = strlen(dirpath);
1357 	}
1358 
1359 	if (has_nfs_args_opt == 0 && has_nfs_from_opt == 0) {
1360 		if (vfs_getopt(mp->mnt_optnew, "addr",
1361 		    (void **)&args.addr, &args.addrlen) == 0) {
1362 			if (args.addrlen > SOCK_MAXADDRLEN) {
1363 				error = ENAMETOOLONG;
1364 				goto out;
1365 			}
1366 			nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1367 			bcopy(args.addr, nam, args.addrlen);
1368 			nam->sa_len = args.addrlen;
1369 		} else {
1370 			vfs_mount_error(mp, "No server address");
1371 			error = EINVAL;
1372 			goto out;
1373 		}
1374 	}
1375 
1376 	if (aconn > 0 && (args.sotype != SOCK_STREAM ||
1377 	    (args.flags & NFSMNT_NFSV4) == 0 || minvers == 0)) {
1378 		/*
1379 		 * RFC 5661 requires that an NFSv4.1/4.2 server
1380 		 * send an RPC reply on the same TCP connection
1381 		 * as the one it received the request on.
1382 		 * This property in required for "nconnect" and
1383 		 * might not be the case for NFSv3 or NFSv4.0 servers.
1384 		 */
1385 		vfs_mount_error(mp, "nconnect should only be used "
1386 		    "for NFSv4.1/4.2 mounts");
1387 		error = EINVAL;
1388 		goto out;
1389 	}
1390 
1391 	args.fh = nfh;
1392 	error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1393 	    dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1394 	    nametimeo, negnametimeo, minvers, newflag, tlscertname, aconn);
1395 out:
1396 	if (!error) {
1397 		MNT_ILOCK(mp);
1398 		mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF |
1399 		    MNTK_USES_BCACHE;
1400 		if ((VFSTONFS(mp)->nm_flag & NFSMNT_NFSV4) != 0)
1401 			mp->mnt_kern_flag |= MNTK_NULL_NOCACHE;
1402 		MNT_IUNLOCK(mp);
1403 	}
1404 	free(hst, M_TEMP);
1405 	return (error);
1406 }
1407 
1408 /*
1409  * VFS Operations.
1410  *
1411  * mount system call
1412  * It seems a bit dumb to copyinstr() the host and path here and then
1413  * bcopy() them in mountnfs(), but I wanted to detect errors before
1414  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
1415  * an error after that means that I have to release the mbuf.
1416  */
1417 /* ARGSUSED */
1418 static int
1419 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1420 {
1421 	int error;
1422 	struct nfs_args args;
1423 
1424 	error = copyin(data, &args, sizeof (struct nfs_args));
1425 	if (error)
1426 		return error;
1427 
1428 	ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1429 
1430 	error = kernel_mount(ma, flags);
1431 	return (error);
1432 }
1433 
1434 /*
1435  * Common code for mount and mountroot
1436  */
1437 static int
1438 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1439     char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1440     u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1441     struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
1442     int minvers, uint32_t newflag, char *tlscertname, int aconn)
1443 {
1444 	struct nfsmount *nmp;
1445 	struct nfsnode *np;
1446 	int error, trycnt, ret;
1447 	struct nfsvattr nfsva;
1448 	struct nfsclclient *clp;
1449 	struct nfsclds *dsp, *tdsp;
1450 	uint32_t lease;
1451 	bool tryminvers;
1452 	static u_int64_t clval = 0;
1453 #ifdef KERN_TLS
1454 	u_int maxlen;
1455 #endif
1456 
1457 	NFSCL_DEBUG(3, "in mnt\n");
1458 	clp = NULL;
1459 	if (mp->mnt_flag & MNT_UPDATE) {
1460 		nmp = VFSTONFS(mp);
1461 		printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1462 		free(nam, M_SONAME);
1463 		free(tlscertname, M_NEWNFSMNT);
1464 		return (0);
1465 	} else {
1466 		/* NFS-over-TLS requires that rpctls be functioning. */
1467 		if ((newflag & NFSMNT_TLS) != 0) {
1468 			error = EINVAL;
1469 #ifdef KERN_TLS
1470 			/* KERN_TLS is only supported for TCP. */
1471 			if (argp->sotype == SOCK_STREAM &&
1472 			    rpctls_getinfo(&maxlen, true, false))
1473 				error = 0;
1474 #endif
1475 			if (error != 0) {
1476 				free(nam, M_SONAME);
1477 				free(tlscertname, M_NEWNFSMNT);
1478 				return (error);
1479 			}
1480 		}
1481 		nmp = malloc(sizeof (struct nfsmount) +
1482 		    krbnamelen + dirlen + srvkrbnamelen + 2,
1483 		    M_NEWNFSMNT, M_WAITOK | M_ZERO);
1484 		nmp->nm_tlscertname = tlscertname;
1485 		nmp->nm_newflag = newflag;
1486 		TAILQ_INIT(&nmp->nm_bufq);
1487 		TAILQ_INIT(&nmp->nm_sess);
1488 		if (clval == 0)
1489 			clval = (u_int64_t)nfsboottime.tv_sec;
1490 		nmp->nm_clval = clval++;
1491 		nmp->nm_krbnamelen = krbnamelen;
1492 		nmp->nm_dirpathlen = dirlen;
1493 		nmp->nm_srvkrbnamelen = srvkrbnamelen;
1494 		if (td->td_ucred->cr_uid != (uid_t)0) {
1495 			/*
1496 			 * nm_uid is used to get KerberosV credentials for
1497 			 * the nfsv4 state handling operations if there is
1498 			 * no host based principal set. Use the uid of
1499 			 * this user if not root, since they are doing the
1500 			 * mount. I don't think setting this for root will
1501 			 * work, since root normally does not have user
1502 			 * credentials in a credentials cache.
1503 			 */
1504 			nmp->nm_uid = td->td_ucred->cr_uid;
1505 		} else {
1506 			/*
1507 			 * Just set to -1, so it won't be used.
1508 			 */
1509 			nmp->nm_uid = (uid_t)-1;
1510 		}
1511 
1512 		/* Copy and null terminate all the names */
1513 		if (nmp->nm_krbnamelen > 0) {
1514 			bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1515 			nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1516 		}
1517 		if (nmp->nm_dirpathlen > 0) {
1518 			bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1519 			    nmp->nm_dirpathlen);
1520 			nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1521 			    + 1] = '\0';
1522 		}
1523 		if (nmp->nm_srvkrbnamelen > 0) {
1524 			bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1525 			    nmp->nm_srvkrbnamelen);
1526 			nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1527 			    + nmp->nm_srvkrbnamelen + 2] = '\0';
1528 		}
1529 		nmp->nm_sockreq.nr_cred = crhold(cred);
1530 		mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1531 		mp->mnt_data = nmp;
1532 		nmp->nm_getinfo = nfs_getnlminfo;
1533 		nmp->nm_vinvalbuf = ncl_vinvalbuf;
1534 	}
1535 	vfs_getnewfsid(mp);
1536 	nmp->nm_mountp = mp;
1537 	mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1538 
1539 	/*
1540 	 * Since nfs_decode_args() might optionally set them, these
1541 	 * need to be set to defaults before the call, so that the
1542 	 * optional settings aren't overwritten.
1543 	 */
1544 	nmp->nm_nametimeo = nametimeo;
1545 	nmp->nm_negnametimeo = negnametimeo;
1546 	nmp->nm_timeo = NFS_TIMEO;
1547 	nmp->nm_retry = NFS_RETRANS;
1548 	nmp->nm_readahead = NFS_DEFRAHEAD;
1549 
1550 	/* This is empirical approximation of sqrt(hibufspace) * 256. */
1551 	nmp->nm_wcommitsize = NFS_MAXBSIZE / 256;
1552 	while ((long)nmp->nm_wcommitsize * nmp->nm_wcommitsize < hibufspace)
1553 		nmp->nm_wcommitsize *= 2;
1554 	nmp->nm_wcommitsize *= 256;
1555 
1556 	tryminvers = false;
1557 	if ((argp->flags & NFSMNT_NFSV4) != 0) {
1558 		if (minvers < 0) {
1559 			tryminvers = true;
1560 			minvers = NFSV42_MINORVERSION;
1561 		}
1562 		nmp->nm_minorvers = minvers;
1563 	} else
1564 		nmp->nm_minorvers = 0;
1565 
1566 	nfs_decode_args(mp, nmp, argp, hst, cred, td);
1567 
1568 	/*
1569 	 * V2 can only handle 32 bit filesizes.  A 4GB-1 limit may be too
1570 	 * high, depending on whether we end up with negative offsets in
1571 	 * the client or server somewhere.  2GB-1 may be safer.
1572 	 *
1573 	 * For V3, ncl_fsinfo will adjust this as necessary.  Assume maximum
1574 	 * that we can handle until we find out otherwise.
1575 	 */
1576 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1577 		nmp->nm_maxfilesize = 0xffffffffLL;
1578 	else
1579 		nmp->nm_maxfilesize = OFF_MAX;
1580 
1581 	if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1582 		nmp->nm_wsize = NFS_WSIZE;
1583 		nmp->nm_rsize = NFS_RSIZE;
1584 		nmp->nm_readdirsize = NFS_READDIRSIZE;
1585 	}
1586 	nmp->nm_numgrps = NFS_MAXGRPS;
1587 	nmp->nm_tprintf_delay = nfs_tprintf_delay;
1588 	if (nmp->nm_tprintf_delay < 0)
1589 		nmp->nm_tprintf_delay = 0;
1590 	nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1591 	if (nmp->nm_tprintf_initial_delay < 0)
1592 		nmp->nm_tprintf_initial_delay = 0;
1593 	nmp->nm_fhsize = argp->fhsize;
1594 	if (nmp->nm_fhsize > 0)
1595 		bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1596 	strlcpy(mp->mnt_stat.f_mntfromname, hst, MNAMELEN);
1597 	nmp->nm_nam = nam;
1598 	/* Set up the sockets and per-host congestion */
1599 	nmp->nm_sotype = argp->sotype;
1600 	nmp->nm_soproto = argp->proto;
1601 	nmp->nm_sockreq.nr_prog = NFS_PROG;
1602 	if ((argp->flags & NFSMNT_NFSV4))
1603 		nmp->nm_sockreq.nr_vers = NFS_VER4;
1604 	else if ((argp->flags & NFSMNT_NFSV3))
1605 		nmp->nm_sockreq.nr_vers = NFS_VER3;
1606 	else
1607 		nmp->nm_sockreq.nr_vers = NFS_VER2;
1608 
1609 	if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false,
1610 	    &nmp->nm_sockreq.nr_client)))
1611 		goto bad;
1612 	/* For NFSv4, get the clientid now. */
1613 	if ((argp->flags & NFSMNT_NFSV4) != 0) {
1614 		NFSCL_DEBUG(3, "at getcl\n");
1615 		error = nfscl_getcl(mp, cred, td, tryminvers, true, &clp);
1616 		NFSCL_DEBUG(3, "aft getcl=%d\n", error);
1617 		if (error != 0)
1618 			goto bad;
1619 		if (aconn > 0 && nmp->nm_minorvers == 0) {
1620 			vfs_mount_error(mp, "nconnect should only be used "
1621 			    "for NFSv4.1/4.2 mounts");
1622 			error = EINVAL;
1623 			goto bad;
1624 		}
1625 	}
1626 
1627 	if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1628 	    nmp->nm_dirpathlen > 0) {
1629 		NFSCL_DEBUG(3, "in dirp\n");
1630 		/*
1631 		 * If the fhsize on the mount point == 0 for V4, the mount
1632 		 * path needs to be looked up.
1633 		 */
1634 		trycnt = 3;
1635 		do {
1636 			error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1637 			    cred, td);
1638 			NFSCL_DEBUG(3, "aft dirp=%d\n", error);
1639 			if (error)
1640 				(void) nfs_catnap(PZERO, error, "nfsgetdirp");
1641 		} while (error && --trycnt > 0);
1642 		if (error)
1643 			goto bad;
1644 	}
1645 
1646 	/*
1647 	 * A reference count is needed on the nfsnode representing the
1648 	 * remote root.  If this object is not persistent, then backward
1649 	 * traversals of the mount point (i.e. "..") will not work if
1650 	 * the nfsnode gets flushed out of the cache. Ufs does not have
1651 	 * this problem, because one can identify root inodes by their
1652 	 * number == UFS_ROOTINO (2).
1653 	 */
1654 	if (nmp->nm_fhsize > 0) {
1655 		/*
1656 		 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1657 		 * non-zero for the root vnode. f_iosize will be set correctly
1658 		 * by nfs_statfs() before any I/O occurs.
1659 		 */
1660 		mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1661 		error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1662 		    LK_EXCLUSIVE);
1663 		if (error)
1664 			goto bad;
1665 		*vpp = NFSTOV(np);
1666 
1667 		/*
1668 		 * Get file attributes and transfer parameters for the
1669 		 * mountpoint.  This has the side effect of filling in
1670 		 * (*vpp)->v_type with the correct value.
1671 		 */
1672 		ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1673 		    cred, td, &nfsva, NULL, &lease);
1674 		if (ret) {
1675 			/*
1676 			 * Just set default values to get things going.
1677 			 */
1678 			NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1679 			nfsva.na_vattr.va_type = VDIR;
1680 			nfsva.na_vattr.va_mode = 0777;
1681 			nfsva.na_vattr.va_nlink = 100;
1682 			nfsva.na_vattr.va_uid = (uid_t)0;
1683 			nfsva.na_vattr.va_gid = (gid_t)0;
1684 			nfsva.na_vattr.va_fileid = 2;
1685 			nfsva.na_vattr.va_gen = 1;
1686 			nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1687 			nfsva.na_vattr.va_size = 512 * 1024;
1688 			lease = 60;
1689 		}
1690 		(void) nfscl_loadattrcache(vpp, &nfsva, NULL, 0, 1);
1691 		if ((argp->flags & NFSMNT_NFSV4) != 0) {
1692 			NFSCL_DEBUG(3, "lease=%d\n", (int)lease);
1693 			NFSLOCKCLSTATE();
1694 			clp->nfsc_renew = NFSCL_RENEW(lease);
1695 			clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
1696 			clp->nfsc_clientidrev++;
1697 			if (clp->nfsc_clientidrev == 0)
1698 				clp->nfsc_clientidrev++;
1699 			NFSUNLOCKCLSTATE();
1700 			/*
1701 			 * Mount will succeed, so the renew thread can be
1702 			 * started now.
1703 			 */
1704 			nfscl_start_renewthread(clp);
1705 			nfscl_clientrelease(clp);
1706 		}
1707 		if (argp->flags & NFSMNT_NFSV3)
1708 			ncl_fsinfo(nmp, *vpp, cred, td);
1709 
1710 		/* Mark if the mount point supports NFSv4 ACLs. */
1711 		if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1712 		    ret == 0 &&
1713 		    NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1714 			MNT_ILOCK(mp);
1715 			mp->mnt_flag |= MNT_NFS4ACLS;
1716 			MNT_IUNLOCK(mp);
1717 		}
1718 
1719 		/* Can now allow additional connections. */
1720 		if (aconn > 0)
1721 			nmp->nm_aconnect = aconn;
1722 
1723 		/*
1724 		 * Lose the lock but keep the ref.
1725 		 */
1726 		NFSVOPUNLOCK(*vpp);
1727 		vfs_cache_root_set(mp, *vpp);
1728 		return (0);
1729 	}
1730 	error = EIO;
1731 
1732 bad:
1733 	if (clp != NULL)
1734 		nfscl_clientrelease(clp);
1735 	newnfs_disconnect(NULL, &nmp->nm_sockreq);
1736 	crfree(nmp->nm_sockreq.nr_cred);
1737 	if (nmp->nm_sockreq.nr_auth != NULL)
1738 		AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1739 	mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1740 	mtx_destroy(&nmp->nm_mtx);
1741 	if (nmp->nm_clp != NULL) {
1742 		NFSLOCKCLSTATE();
1743 		LIST_REMOVE(nmp->nm_clp, nfsc_list);
1744 		NFSUNLOCKCLSTATE();
1745 		free(nmp->nm_clp, M_NFSCLCLIENT);
1746 	}
1747 	TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1748 		if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1749 		    dsp->nfsclds_sockp != NULL)
1750 			newnfs_disconnect(NULL, dsp->nfsclds_sockp);
1751 		nfscl_freenfsclds(dsp);
1752 	}
1753 	free(nmp->nm_tlscertname, M_NEWNFSMNT);
1754 	free(nmp, M_NEWNFSMNT);
1755 	free(nam, M_SONAME);
1756 	return (error);
1757 }
1758 
1759 /*
1760  * unmount system call
1761  */
1762 static int
1763 nfs_unmount(struct mount *mp, int mntflags)
1764 {
1765 	struct thread *td;
1766 	struct nfsmount *nmp;
1767 	int error, flags = 0, i, trycnt = 0;
1768 	struct nfsclds *dsp, *tdsp;
1769 	struct nfscldeleg *dp, *ndp;
1770 	struct nfscldeleghead dh;
1771 
1772 	td = curthread;
1773 	TAILQ_INIT(&dh);
1774 
1775 	if (mntflags & MNT_FORCE)
1776 		flags |= FORCECLOSE;
1777 	nmp = VFSTONFS(mp);
1778 	error = 0;
1779 	/*
1780 	 * Goes something like this..
1781 	 * - Call vflush() to clear out vnodes for this filesystem
1782 	 * - Close the socket
1783 	 * - Free up the data structures
1784 	 */
1785 	/* In the forced case, cancel any outstanding requests. */
1786 	if (mntflags & MNT_FORCE) {
1787 		NFSDDSLOCK();
1788 		if (nfsv4_findmirror(nmp) != NULL)
1789 			error = ENXIO;
1790 		NFSDDSUNLOCK();
1791 		if (error)
1792 			goto out;
1793 		error = newnfs_nmcancelreqs(nmp);
1794 		if (error)
1795 			goto out;
1796 		/* For a forced close, get rid of the renew thread now */
1797 		nfscl_umount(nmp, td, &dh);
1798 	}
1799 	/* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1800 	do {
1801 		error = vflush(mp, 1, flags, td);
1802 		if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1803 			(void) nfs_catnap(PSOCK, error, "newndm");
1804 	} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1805 	if (error)
1806 		goto out;
1807 
1808 	/*
1809 	 * We are now committed to the unmount.
1810 	 */
1811 	if ((mntflags & MNT_FORCE) == 0)
1812 		nfscl_umount(nmp, td, NULL);
1813 	else {
1814 		mtx_lock(&nmp->nm_mtx);
1815 		nmp->nm_privflag |= NFSMNTP_FORCEDISM;
1816 		mtx_unlock(&nmp->nm_mtx);
1817 	}
1818 	/* Make sure no nfsiods are assigned to this mount. */
1819 	NFSLOCKIOD();
1820 	for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1821 		if (ncl_iodmount[i] == nmp) {
1822 			ncl_iodwant[i] = NFSIOD_AVAILABLE;
1823 			ncl_iodmount[i] = NULL;
1824 		}
1825 	NFSUNLOCKIOD();
1826 
1827 	/*
1828 	 * We can now set mnt_data to NULL and wait for
1829 	 * nfssvc(NFSSVC_FORCEDISM) to complete.
1830 	 */
1831 	mtx_lock(&mountlist_mtx);
1832 	mtx_lock(&nmp->nm_mtx);
1833 	mp->mnt_data = NULL;
1834 	mtx_unlock(&mountlist_mtx);
1835 	while ((nmp->nm_privflag & NFSMNTP_CANCELRPCS) != 0)
1836 		msleep(nmp, &nmp->nm_mtx, PVFS, "nfsfdism", 0);
1837 	mtx_unlock(&nmp->nm_mtx);
1838 
1839 	newnfs_disconnect(nmp, &nmp->nm_sockreq);
1840 	crfree(nmp->nm_sockreq.nr_cred);
1841 	free(nmp->nm_nam, M_SONAME);
1842 	if (nmp->nm_sockreq.nr_auth != NULL)
1843 		AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1844 	mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1845 	mtx_destroy(&nmp->nm_mtx);
1846 	TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1847 		if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1848 		    dsp->nfsclds_sockp != NULL)
1849 			newnfs_disconnect(NULL, dsp->nfsclds_sockp);
1850 		nfscl_freenfsclds(dsp);
1851 	}
1852 	free(nmp->nm_tlscertname, M_NEWNFSMNT);
1853 	free(nmp, M_NEWNFSMNT);
1854 
1855 	/* Free up the delegation structures for forced dismounts. */
1856 	TAILQ_FOREACH_SAFE(dp, &dh, nfsdl_list, ndp) {
1857 		TAILQ_REMOVE(&dh, dp, nfsdl_list);
1858 		free(dp, M_NFSCLDELEG);
1859 	}
1860 out:
1861 	return (error);
1862 }
1863 
1864 /*
1865  * Return root of a filesystem
1866  */
1867 static int
1868 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1869 {
1870 	struct vnode *vp;
1871 	struct nfsmount *nmp;
1872 	struct nfsnode *np;
1873 	int error;
1874 
1875 	nmp = VFSTONFS(mp);
1876 	error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1877 	if (error)
1878 		return error;
1879 	vp = NFSTOV(np);
1880 	/*
1881 	 * Get transfer parameters and attributes for root vnode once.
1882 	 */
1883 	mtx_lock(&nmp->nm_mtx);
1884 	if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1885 		mtx_unlock(&nmp->nm_mtx);
1886 		ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1887 	} else
1888 		mtx_unlock(&nmp->nm_mtx);
1889 	if (vp->v_type == VNON)
1890 	    vp->v_type = VDIR;
1891 	vp->v_vflag |= VV_ROOT;
1892 	*vpp = vp;
1893 	return (0);
1894 }
1895 
1896 /*
1897  * Flush out the buffer cache
1898  */
1899 /* ARGSUSED */
1900 static int
1901 nfs_sync(struct mount *mp, int waitfor)
1902 {
1903 	struct vnode *vp, *mvp;
1904 	struct thread *td;
1905 	int error, allerror = 0;
1906 
1907 	td = curthread;
1908 
1909 	MNT_ILOCK(mp);
1910 	/*
1911 	 * If a forced dismount is in progress, return from here so that
1912 	 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1913 	 * calling VFS_UNMOUNT().
1914 	 */
1915 	if (NFSCL_FORCEDISM(mp)) {
1916 		MNT_IUNLOCK(mp);
1917 		return (EBADF);
1918 	}
1919 	MNT_IUNLOCK(mp);
1920 
1921 	/*
1922 	 * Force stale buffer cache information to be flushed.
1923 	 */
1924 loop:
1925 	MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1926 		/* XXX Racy bv_cnt check. */
1927 		if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1928 		    waitfor == MNT_LAZY) {
1929 			VI_UNLOCK(vp);
1930 			continue;
1931 		}
1932 		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
1933 			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1934 			goto loop;
1935 		}
1936 		error = VOP_FSYNC(vp, waitfor, td);
1937 		if (error)
1938 			allerror = error;
1939 		NFSVOPUNLOCK(vp);
1940 		vrele(vp);
1941 	}
1942 	return (allerror);
1943 }
1944 
1945 static int
1946 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1947 {
1948 	struct nfsmount *nmp = VFSTONFS(mp);
1949 	struct vfsquery vq;
1950 	int error;
1951 
1952 	bzero(&vq, sizeof(vq));
1953 	switch (op) {
1954 #if 0
1955 	case VFS_CTL_NOLOCKS:
1956 		val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1957  		if (req->oldptr != NULL) {
1958  			error = SYSCTL_OUT(req, &val, sizeof(val));
1959  			if (error)
1960  				return (error);
1961  		}
1962  		if (req->newptr != NULL) {
1963  			error = SYSCTL_IN(req, &val, sizeof(val));
1964  			if (error)
1965  				return (error);
1966 			if (val)
1967 				nmp->nm_flag |= NFSMNT_NOLOCKS;
1968 			else
1969 				nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1970  		}
1971 		break;
1972 #endif
1973 	case VFS_CTL_QUERY:
1974 		mtx_lock(&nmp->nm_mtx);
1975 		if (nmp->nm_state & NFSSTA_TIMEO)
1976 			vq.vq_flags |= VQ_NOTRESP;
1977 		mtx_unlock(&nmp->nm_mtx);
1978 #if 0
1979 		if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1980 		    (nmp->nm_state & NFSSTA_LOCKTIMEO))
1981 			vq.vq_flags |= VQ_NOTRESPLOCK;
1982 #endif
1983 		error = SYSCTL_OUT(req, &vq, sizeof(vq));
1984 		break;
1985  	case VFS_CTL_TIMEO:
1986  		if (req->oldptr != NULL) {
1987  			error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1988  			    sizeof(nmp->nm_tprintf_initial_delay));
1989  			if (error)
1990  				return (error);
1991  		}
1992  		if (req->newptr != NULL) {
1993 			error = vfs_suser(mp, req->td);
1994 			if (error)
1995 				return (error);
1996  			error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1997  			    sizeof(nmp->nm_tprintf_initial_delay));
1998  			if (error)
1999  				return (error);
2000  			if (nmp->nm_tprintf_initial_delay < 0)
2001  				nmp->nm_tprintf_initial_delay = 0;
2002  		}
2003 		break;
2004 	default:
2005 		return (ENOTSUP);
2006 	}
2007 	return (0);
2008 }
2009 
2010 /*
2011  * Purge any RPCs in progress, so that they will all return errors.
2012  * This allows dounmount() to continue as far as VFS_UNMOUNT() for a
2013  * forced dismount.
2014  */
2015 static void
2016 nfs_purge(struct mount *mp)
2017 {
2018 	struct nfsmount *nmp = VFSTONFS(mp);
2019 
2020 	newnfs_nmcancelreqs(nmp);
2021 }
2022 
2023 /*
2024  * Extract the information needed by the nlm from the nfs vnode.
2025  */
2026 static void
2027 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
2028     struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
2029     struct timeval *timeop)
2030 {
2031 	struct nfsmount *nmp;
2032 	struct nfsnode *np = VTONFS(vp);
2033 
2034 	nmp = VFSTONFS(vp->v_mount);
2035 	if (fhlenp != NULL)
2036 		*fhlenp = (size_t)np->n_fhp->nfh_len;
2037 	if (fhp != NULL)
2038 		bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
2039 	if (sp != NULL)
2040 		bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
2041 	if (is_v3p != NULL)
2042 		*is_v3p = NFS_ISV3(vp);
2043 	if (sizep != NULL)
2044 		*sizep = np->n_size;
2045 	if (timeop != NULL) {
2046 		timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
2047 		timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
2048 	}
2049 }
2050 
2051 /*
2052  * This function prints out an option name, based on the conditional
2053  * argument.
2054  */
2055 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
2056     char *opt, char **buf, size_t *blen)
2057 {
2058 	int len;
2059 
2060 	if (testval != 0 && *blen > strlen(opt)) {
2061 		len = snprintf(*buf, *blen, "%s", opt);
2062 		if (len != strlen(opt))
2063 			printf("EEK!!\n");
2064 		*buf += len;
2065 		*blen -= len;
2066 	}
2067 }
2068 
2069 /*
2070  * This function printf out an options integer value.
2071  */
2072 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
2073     char *opt, char **buf, size_t *blen)
2074 {
2075 	int len;
2076 
2077 	if (*blen > strlen(opt) + 1) {
2078 		/* Could result in truncated output string. */
2079 		len = snprintf(*buf, *blen, "%s=%d", opt, optval);
2080 		if (len < *blen) {
2081 			*buf += len;
2082 			*blen -= len;
2083 		}
2084 	}
2085 }
2086 
2087 /*
2088  * Load the option flags and values into the buffer.
2089  */
2090 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
2091 {
2092 	char *buf;
2093 	size_t blen;
2094 
2095 	buf = buffer;
2096 	blen = buflen;
2097 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
2098 	    &blen);
2099 	if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) {
2100 		nfscl_printoptval(nmp, nmp->nm_minorvers, ",minorversion", &buf,
2101 		    &blen);
2102 		nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
2103 		    &buf, &blen);
2104 		nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_ONEOPENOWN) != 0 &&
2105 		    nmp->nm_minorvers > 0, ",oneopenown", &buf, &blen);
2106 	}
2107 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
2108 	    &blen);
2109 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
2110 	    "nfsv2", &buf, &blen);
2111 	nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
2112 	nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
2113 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
2114 	    &buf, &blen);
2115 	nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf,
2116 	    &blen);
2117 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
2118 	    &buf, &blen);
2119 	nfscl_printoptval(nmp, nmp->nm_aconnect + 1, ",nconnect", &buf, &blen);
2120 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
2121 	    &blen);
2122 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
2123 	    &blen);
2124 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
2125 	    &blen);
2126 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
2127 	    &blen);
2128 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
2129 	    &blen);
2130 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NONCONTIGWR) != 0,
2131 	    ",noncontigwr", &buf, &blen);
2132 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2133 	    0, ",lockd", &buf, &blen);
2134 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2135 	    NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
2136 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
2137 	    &buf, &blen);
2138 	nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
2139 	    &buf, &blen);
2140 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2141 	    NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
2142 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2143 	    NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
2144 	    &buf, &blen);
2145 	nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2146 	    NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
2147 	    &buf, &blen);
2148 	nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
2149 	nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
2150 	nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
2151 	nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
2152 	nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
2153 	nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
2154 	    &blen);
2155 	nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
2156 	nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
2157 	nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
2158 	    &blen);
2159 	nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
2160 	nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
2161 	    &blen);
2162 	nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
2163 	nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
2164 }
2165