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