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