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