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