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