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