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