2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
32 * from nfs_vfsops.c 8.12 (Berkeley) 5/20/95
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
39 #include "opt_bootp.h"
40 #include "opt_nfsroot.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
47 #include <sys/clock.h>
49 #include <sys/limits.h>
51 #include <sys/malloc.h>
53 #include <sys/module.h>
54 #include <sys/mount.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>
64 #include <vm/vm_extern.h>
68 #include <net/route.h>
69 #include <netinet/in.h>
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>
77 FEATURE(nfscl, "NFSv4 client");
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;
89 MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
90 MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
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, "");
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 *,
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 *,
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;
125 * nfs vfs operations.
127 static struct vfsops nfs_vfsops = {
128 .vfs_init = ncl_init,
129 .vfs_mount = nfs_mount,
130 .vfs_cmount = nfs_cmount,
131 .vfs_root = nfs_root,
132 .vfs_statfs = nfs_statfs,
133 .vfs_sync = nfs_sync,
134 .vfs_uninit = ncl_uninit,
135 .vfs_unmount = nfs_unmount,
136 .vfs_sysctl = nfs_sysctl,
138 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY);
140 /* So that loader and kldload(2) can find us, wherever we are.. */
141 MODULE_VERSION(nfs, 1);
142 MODULE_DEPEND(nfs, nfscommon, 1, 1, 1);
143 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
144 MODULE_DEPEND(nfs, nfssvc, 1, 1, 1);
145 MODULE_DEPEND(nfs, nfslock, 1, 1, 1);
148 * This structure is now defined in sys/nfs/nfs_diskless.c so that it
149 * can be shared by both NFS clients. It is declared here so that it
150 * will be defined for kernels built without NFS_ROOT, although it
151 * isn't used in that case.
153 #if !defined(NFS_ROOT) && !defined(NFSCLIENT)
154 struct nfs_diskless nfs_diskless = { { { 0 } } };
155 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
156 int nfs_diskless_valid = 0;
159 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
160 &nfs_diskless_valid, 0,
161 "Has the diskless struct been filled correctly");
163 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
164 nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
166 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
167 &nfsv3_diskless.root_saddr, sizeof(nfsv3_diskless.root_saddr),
168 "%Ssockaddr_in", "Diskless root nfs address");
171 void newnfsargs_ntoh(struct nfs_args *);
172 static int nfs_mountdiskless(char *,
173 struct sockaddr_in *, struct nfs_args *,
174 struct thread *, struct vnode **, struct mount *);
175 static void nfs_convert_diskless(void);
176 static void nfs_convert_oargs(struct nfs_args *args,
177 struct onfs_args *oargs);
180 newnfs_iosize(struct nfsmount *nmp)
184 /* First, set the upper limit for iosize */
185 if (nmp->nm_flag & NFSMNT_NFSV4) {
186 maxio = NFS_MAXBSIZE;
187 } else if (nmp->nm_flag & NFSMNT_NFSV3) {
188 if (nmp->nm_sotype == SOCK_DGRAM)
189 maxio = NFS_MAXDGRAMDATA;
191 maxio = NFS_MAXBSIZE;
193 maxio = NFS_V2MAXDATA;
195 if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
196 nmp->nm_rsize = maxio;
197 if (nmp->nm_rsize > MAXBSIZE)
198 nmp->nm_rsize = MAXBSIZE;
199 if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
200 nmp->nm_readdirsize = maxio;
201 if (nmp->nm_readdirsize > nmp->nm_rsize)
202 nmp->nm_readdirsize = nmp->nm_rsize;
203 if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
204 nmp->nm_wsize = maxio;
205 if (nmp->nm_wsize > MAXBSIZE)
206 nmp->nm_wsize = MAXBSIZE;
209 * Calculate the size used for io buffers. Use the larger
210 * of the two sizes to minimise nfs requests but make sure
211 * that it is at least one VM page to avoid wasting buffer
214 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
215 iosize = imax(iosize, PAGE_SIZE);
216 nmp->nm_mountp->mnt_stat.f_iosize = iosize;
221 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
224 args->version = NFS_ARGSVERSION;
225 args->addr = oargs->addr;
226 args->addrlen = oargs->addrlen;
227 args->sotype = oargs->sotype;
228 args->proto = oargs->proto;
229 args->fh = oargs->fh;
230 args->fhsize = oargs->fhsize;
231 args->flags = oargs->flags;
232 args->wsize = oargs->wsize;
233 args->rsize = oargs->rsize;
234 args->readdirsize = oargs->readdirsize;
235 args->timeo = oargs->timeo;
236 args->retrans = oargs->retrans;
237 args->readahead = oargs->readahead;
238 args->hostname = oargs->hostname;
242 nfs_convert_diskless(void)
245 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
246 sizeof(struct ifaliasreq));
247 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
248 sizeof(struct sockaddr_in));
249 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
250 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
251 nfsv3_diskless.root_fhsize = NFSX_MYFH;
252 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_MYFH);
254 nfsv3_diskless.root_fhsize = NFSX_V2FH;
255 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
257 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
258 sizeof(struct sockaddr_in));
259 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
260 nfsv3_diskless.root_time = nfs_diskless.root_time;
261 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
263 nfs_diskless_valid = 3;
270 nfs_statfs(struct mount *mp, struct statfs *sbp)
274 struct nfsmount *nmp = VFSTONFS(mp);
275 struct nfsvattr nfsva;
278 int error = 0, attrflag, gotfsinfo = 0, ret;
283 error = vfs_busy(mp, MBF_NOWAIT);
286 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
292 mtx_lock(&nmp->nm_mtx);
293 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
294 mtx_unlock(&nmp->nm_mtx);
295 error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
300 mtx_unlock(&nmp->nm_mtx);
302 error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
305 NFSCL_DEBUG(2, "statfs=%d\n", error);
307 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
308 td->td_ucred, td, &nfsva, NULL, NULL);
311 * Just set default values to get things going.
313 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
314 nfsva.na_vattr.va_type = VDIR;
315 nfsva.na_vattr.va_mode = 0777;
316 nfsva.na_vattr.va_nlink = 100;
317 nfsva.na_vattr.va_uid = (uid_t)0;
318 nfsva.na_vattr.va_gid = (gid_t)0;
319 nfsva.na_vattr.va_fileid = 2;
320 nfsva.na_vattr.va_gen = 1;
321 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
322 nfsva.na_vattr.va_size = 512 * 1024;
325 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
327 mtx_lock(&nmp->nm_mtx);
328 if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
329 nfscl_loadfsinfo(nmp, &fs);
330 nfscl_loadsbinfo(nmp, &sb, sbp);
331 sbp->f_iosize = newnfs_iosize(nmp);
332 mtx_unlock(&nmp->nm_mtx);
333 if (sbp != &mp->mnt_stat) {
334 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
335 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
337 strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
338 } else if (NFS_ISV4(vp)) {
339 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
347 * nfs version 3 fsinfo rpc call
350 ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
354 struct nfsvattr nfsva;
357 error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
360 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
362 mtx_lock(&nmp->nm_mtx);
363 nfscl_loadfsinfo(nmp, &fs);
364 mtx_unlock(&nmp->nm_mtx);
370 * Mount a remote root fs via. nfs. This depends on the info in the
371 * nfs_diskless structure that has been filled in properly by some primary
373 * It goes something like this:
374 * - do enough of "ifconfig" by calling ifioctl() so that the system
375 * can talk to the server
376 * - If nfs_diskless.mygateway is filled in, use that address as
378 * - build the rootfs mount point and call mountnfs() to do the rest.
380 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
381 * structure, as well as other global NFS client variables here, as
382 * nfs_mountroot() will be called once in the boot before any other NFS
383 * client activity occurs.
386 nfs_mountroot(struct mount *mp)
388 struct thread *td = curthread;
389 struct nfsv3_diskless *nd = &nfsv3_diskless;
398 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
399 bootpc_init(); /* use bootp to get nfs_diskless filled in */
400 #elif defined(NFS_ROOT)
401 nfs_setup_diskless();
404 if (nfs_diskless_valid == 0)
406 if (nfs_diskless_valid == 1)
407 nfs_convert_diskless();
410 * XXX splnet, so networks will receive...
415 * Do enough of ifconfig(8) so that the critical net interface can
416 * talk to the server.
418 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
421 panic("nfs_mountroot: socreate(%04x): %d",
422 nd->myif.ifra_addr.sa_family, error);
424 #if 0 /* XXX Bad idea */
426 * We might not have been told the right interface, so we pass
427 * over the first ten interfaces of the same kind, until we get
428 * one of them configured.
431 for (i = strlen(nd->myif.ifra_name) - 1;
432 nd->myif.ifra_name[i] >= '0' &&
433 nd->myif.ifra_name[i] <= '9';
434 nd->myif.ifra_name[i] ++) {
435 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
440 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
442 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
443 if ((cp = getenv("boot.netif.mtu")) != NULL) {
444 ir.ifr_mtu = strtol(cp, NULL, 10);
445 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
447 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
449 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
454 * If the gateway field is filled in, set it as the default route.
455 * Note that pxeboot will set a default route of 0 if the route
456 * is not set by the DHCP server. Check also for a value of 0
457 * to avoid panicking inappropriately in that situation.
459 if (nd->mygateway.sin_len != 0 &&
460 nd->mygateway.sin_addr.s_addr != 0) {
461 struct sockaddr_in mask, sin;
463 bzero((caddr_t)&mask, sizeof(mask));
465 sin.sin_family = AF_INET;
466 sin.sin_len = sizeof(sin);
467 /* XXX MRT use table 0 for this sort of thing */
468 CURVNET_SET(TD_TO_VNET(td));
469 error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
470 (struct sockaddr *)&nd->mygateway,
471 (struct sockaddr *)&mask,
472 RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
475 panic("nfs_mountroot: RTM_ADD: %d", error);
479 * Create the rootfs mount point.
481 nd->root_args.fh = nd->root_fh;
482 nd->root_args.fhsize = nd->root_fhsize;
483 l = ntohl(nd->root_saddr.sin_addr.s_addr);
484 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
485 (l >> 24) & 0xff, (l >> 16) & 0xff,
486 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
487 printf("NFS ROOT: %s\n", buf);
488 nd->root_args.hostname = buf;
489 if ((error = nfs_mountdiskless(buf,
490 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
495 * This is not really an nfs issue, but it is much easier to
496 * set hostname here and then let the "/etc/rc.xxx" files
497 * mount the right /var based upon its preset value.
499 mtx_lock(&prison0.pr_mtx);
500 strlcpy(prison0.pr_hostname, nd->my_hostnam,
501 sizeof(prison0.pr_hostname));
502 mtx_unlock(&prison0.pr_mtx);
503 inittodr(ntohl(nd->root_time));
508 * Internal version of mount system call for diskless setup.
511 nfs_mountdiskless(char *path,
512 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
513 struct vnode **vpp, struct mount *mp)
515 struct sockaddr *nam;
520 * Find the directory path in "path", which also has the server's
521 * name/ip address in it.
523 dirpath = strchr(path, ':');
525 dirlen = strlen(++dirpath);
528 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
529 if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
530 NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
531 NFS_DEFAULT_NEGNAMETIMEO, 0)) != 0) {
532 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
539 nfs_sec_name(char *sec, int *flagsp)
541 if (!strcmp(sec, "krb5"))
542 *flagsp |= NFSMNT_KERB;
543 else if (!strcmp(sec, "krb5i"))
544 *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
545 else if (!strcmp(sec, "krb5p"))
546 *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
550 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
551 const char *hostname, struct ucred *cred, struct thread *td)
560 * Set read-only flag if requested; otherwise, clear it if this is
561 * an update. If this is not an update, then either the read-only
562 * flag is already clear, or this is a root mount and it was set
563 * intentionally at some previous point.
565 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
567 mp->mnt_flag |= MNT_RDONLY;
569 } else if (mp->mnt_flag & MNT_UPDATE) {
571 mp->mnt_flag &= ~MNT_RDONLY;
576 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
577 * no sense in that context. Also, set up appropriate retransmit
578 * and soft timeout behavior.
580 if (argp->sotype == SOCK_STREAM) {
581 nmp->nm_flag &= ~NFSMNT_NOCONN;
582 nmp->nm_timeo = NFS_MAXTIMEO;
583 if ((argp->flags & NFSMNT_NFSV4) != 0)
584 nmp->nm_retry = INT_MAX;
586 nmp->nm_retry = NFS_RETRANS_TCP;
589 /* Also clear RDIRPLUS if NFSv2, it crashes some servers */
590 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
591 argp->flags &= ~NFSMNT_RDIRPLUS;
592 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
595 /* Re-bind if rsrvd port requested and wasn't on one */
596 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
597 && (argp->flags & NFSMNT_RESVPORT);
598 /* Also re-bind if we're switching to/from a connected UDP socket */
599 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
600 (argp->flags & NFSMNT_NOCONN));
602 /* Update flags atomically. Don't change the lock bits. */
603 nmp->nm_flag = argp->flags | nmp->nm_flag;
606 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
607 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
608 if (nmp->nm_timeo < NFS_MINTIMEO)
609 nmp->nm_timeo = NFS_MINTIMEO;
610 else if (nmp->nm_timeo > NFS_MAXTIMEO)
611 nmp->nm_timeo = NFS_MAXTIMEO;
614 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
615 nmp->nm_retry = argp->retrans;
616 if (nmp->nm_retry > NFS_MAXREXMIT)
617 nmp->nm_retry = NFS_MAXREXMIT;
620 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
621 nmp->nm_wsize = argp->wsize;
622 /* Round down to multiple of blocksize */
623 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
624 if (nmp->nm_wsize <= 0)
625 nmp->nm_wsize = NFS_FABLKSIZE;
628 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
629 nmp->nm_rsize = argp->rsize;
630 /* Round down to multiple of blocksize */
631 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
632 if (nmp->nm_rsize <= 0)
633 nmp->nm_rsize = NFS_FABLKSIZE;
636 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
637 nmp->nm_readdirsize = argp->readdirsize;
640 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
641 nmp->nm_acregmin = argp->acregmin;
643 nmp->nm_acregmin = NFS_MINATTRTIMO;
644 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
645 nmp->nm_acregmax = argp->acregmax;
647 nmp->nm_acregmax = NFS_MAXATTRTIMO;
648 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
649 nmp->nm_acdirmin = argp->acdirmin;
651 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
652 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
653 nmp->nm_acdirmax = argp->acdirmax;
655 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
656 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
657 nmp->nm_acdirmin = nmp->nm_acdirmax;
658 if (nmp->nm_acregmin > nmp->nm_acregmax)
659 nmp->nm_acregmin = nmp->nm_acregmax;
661 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
662 if (argp->readahead <= NFS_MAXRAHEAD)
663 nmp->nm_readahead = argp->readahead;
665 nmp->nm_readahead = NFS_MAXRAHEAD;
667 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
668 if (argp->wcommitsize < nmp->nm_wsize)
669 nmp->nm_wcommitsize = nmp->nm_wsize;
671 nmp->nm_wcommitsize = argp->wcommitsize;
674 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
675 (nmp->nm_soproto != argp->proto));
677 if (nmp->nm_client != NULL && adjsock) {
678 int haslock = 0, error = 0;
680 if (nmp->nm_sotype == SOCK_STREAM) {
681 error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
686 newnfs_disconnect(&nmp->nm_sockreq);
688 newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
689 nmp->nm_sotype = argp->sotype;
690 nmp->nm_soproto = argp->proto;
691 if (nmp->nm_sotype == SOCK_DGRAM)
692 while (newnfs_connect(nmp, &nmp->nm_sockreq,
694 printf("newnfs_args: retrying connect\n");
695 (void) nfs_catnap(PSOCK, 0, "newnfscon");
699 nmp->nm_sotype = argp->sotype;
700 nmp->nm_soproto = argp->proto;
703 if (hostname != NULL) {
704 strlcpy(nmp->nm_hostname, hostname,
705 sizeof(nmp->nm_hostname));
706 p = strchr(nmp->nm_hostname, ':');
712 static const char *nfs_opts[] = { "from", "nfs_args",
713 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
714 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
715 "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
716 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
717 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport",
718 "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
719 "principal", "nfsv4", "gssname", "allgssname", "dirpath", "minorversion",
720 "nametimeo", "negnametimeo", "nocto", "pnfs", "wcommitsize",
727 * It seems a bit dumb to copyinstr() the host and path here and then
728 * bcopy() them in mountnfs(), but I wanted to detect errors before
729 * doing the sockargs() call because sockargs() allocates an mbuf and
730 * an error after that means that I have to release the mbuf.
734 nfs_mount(struct mount *mp)
736 struct nfs_args args = {
737 .version = NFS_ARGSVERSION,
739 .addrlen = sizeof (struct sockaddr_in),
740 .sotype = SOCK_STREAM,
744 .flags = NFSMNT_RESVPORT,
747 .readdirsize = NFS_READDIRSIZE,
749 .retrans = NFS_RETRANS,
750 .readahead = NFS_DEFRAHEAD,
751 .wcommitsize = 0, /* was: NQ_DEFLEASE */
753 .acregmin = NFS_MINATTRTIMO,
754 .acregmax = NFS_MAXATTRTIMO,
755 .acdirmin = NFS_MINDIRATTRTIMO,
756 .acdirmax = NFS_MAXDIRATTRTIMO,
758 int error = 0, ret, len;
759 struct sockaddr *nam = NULL;
763 u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
764 char *opt, *name, *secname;
765 int nametimeo = NFS_DEFAULT_NAMETIMEO;
766 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
768 int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen;
771 has_nfs_args_opt = 0;
772 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
778 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
779 error = nfs_mountroot(mp);
786 * The old mount_nfs program passed the struct nfs_args
787 * from userspace to kernel. The new mount_nfs program
788 * passes string options via nmount() from userspace to kernel
789 * and we populate the struct nfs_args in the kernel.
791 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
792 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
797 if (args.version != NFS_ARGSVERSION) {
798 error = EPROGMISMATCH;
801 has_nfs_args_opt = 1;
804 /* Handle the new style options. */
805 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
806 args.flags |= NFSMNT_NOCONN;
807 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
808 args.flags |= NFSMNT_NOCONN;
809 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
810 args.flags |= NFSMNT_NOLOCKD;
811 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
812 args.flags &= ~NFSMNT_NOLOCKD;
813 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
814 args.flags |= NFSMNT_INT;
815 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
816 args.flags |= NFSMNT_RDIRPLUS;
817 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
818 args.flags |= NFSMNT_RESVPORT;
819 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
820 args.flags &= ~NFSMNT_RESVPORT;
821 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
822 args.flags |= NFSMNT_SOFT;
823 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
824 args.flags &= ~NFSMNT_SOFT;
825 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
826 args.sotype = SOCK_DGRAM;
827 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
828 args.sotype = SOCK_DGRAM;
829 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
830 args.sotype = SOCK_STREAM;
831 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
832 args.flags |= NFSMNT_NFSV3;
833 if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
834 args.flags |= NFSMNT_NFSV4;
835 args.sotype = SOCK_STREAM;
837 if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
838 args.flags |= NFSMNT_ALLGSSNAME;
839 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
840 args.flags |= NFSMNT_NOCTO;
841 if (vfs_getopt(mp->mnt_optnew, "pnfs", NULL, NULL) == 0)
842 args.flags |= NFSMNT_PNFS;
843 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
845 vfs_mount_error(mp, "illegal readdirsize");
849 ret = sscanf(opt, "%d", &args.readdirsize);
850 if (ret != 1 || args.readdirsize <= 0) {
851 vfs_mount_error(mp, "illegal readdirsize: %s",
856 args.flags |= NFSMNT_READDIRSIZE;
858 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
860 vfs_mount_error(mp, "illegal readahead");
864 ret = sscanf(opt, "%d", &args.readahead);
865 if (ret != 1 || args.readahead <= 0) {
866 vfs_mount_error(mp, "illegal readahead: %s",
871 args.flags |= NFSMNT_READAHEAD;
873 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
875 vfs_mount_error(mp, "illegal wsize");
879 ret = sscanf(opt, "%d", &args.wsize);
880 if (ret != 1 || args.wsize <= 0) {
881 vfs_mount_error(mp, "illegal wsize: %s",
886 args.flags |= NFSMNT_WSIZE;
888 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
890 vfs_mount_error(mp, "illegal rsize");
894 ret = sscanf(opt, "%d", &args.rsize);
895 if (ret != 1 || args.rsize <= 0) {
896 vfs_mount_error(mp, "illegal wsize: %s",
901 args.flags |= NFSMNT_RSIZE;
903 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
905 vfs_mount_error(mp, "illegal retrans");
909 ret = sscanf(opt, "%d", &args.retrans);
910 if (ret != 1 || args.retrans <= 0) {
911 vfs_mount_error(mp, "illegal retrans: %s",
916 args.flags |= NFSMNT_RETRANS;
918 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
919 ret = sscanf(opt, "%d", &args.acregmin);
920 if (ret != 1 || args.acregmin < 0) {
921 vfs_mount_error(mp, "illegal acregmin: %s",
926 args.flags |= NFSMNT_ACREGMIN;
928 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
929 ret = sscanf(opt, "%d", &args.acregmax);
930 if (ret != 1 || args.acregmax < 0) {
931 vfs_mount_error(mp, "illegal acregmax: %s",
936 args.flags |= NFSMNT_ACREGMAX;
938 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
939 ret = sscanf(opt, "%d", &args.acdirmin);
940 if (ret != 1 || args.acdirmin < 0) {
941 vfs_mount_error(mp, "illegal acdirmin: %s",
946 args.flags |= NFSMNT_ACDIRMIN;
948 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
949 ret = sscanf(opt, "%d", &args.acdirmax);
950 if (ret != 1 || args.acdirmax < 0) {
951 vfs_mount_error(mp, "illegal acdirmax: %s",
956 args.flags |= NFSMNT_ACDIRMAX;
958 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
959 ret = sscanf(opt, "%d", &args.wcommitsize);
960 if (ret != 1 || args.wcommitsize < 0) {
961 vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
965 args.flags |= NFSMNT_WCOMMITSIZE;
967 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
968 ret = sscanf(opt, "%d", &args.timeo);
969 if (ret != 1 || args.timeo <= 0) {
970 vfs_mount_error(mp, "illegal timeout: %s",
975 args.flags |= NFSMNT_TIMEO;
977 if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
978 ret = sscanf(opt, "%d", &nametimeo);
979 if (ret != 1 || nametimeo < 0) {
980 vfs_mount_error(mp, "illegal nametimeo: %s", opt);
985 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
987 ret = sscanf(opt, "%d", &negnametimeo);
988 if (ret != 1 || negnametimeo < 0) {
989 vfs_mount_error(mp, "illegal negnametimeo: %s",
995 if (vfs_getopt(mp->mnt_optnew, "minorversion", (void **)&opt, NULL) ==
997 ret = sscanf(opt, "%d", &minvers);
998 if (ret != 1 || minvers < 0 || minvers > 1 ||
999 (args.flags & NFSMNT_NFSV4) == 0) {
1000 vfs_mount_error(mp, "illegal minorversion: %s", opt);
1005 if (vfs_getopt(mp->mnt_optnew, "sec",
1006 (void **) &secname, NULL) == 0)
1007 nfs_sec_name(secname, &args.flags);
1009 if (mp->mnt_flag & MNT_UPDATE) {
1010 struct nfsmount *nmp = VFSTONFS(mp);
1018 * If a change from TCP->UDP is done and there are thread(s)
1019 * that have I/O RPC(s) in progress with a tranfer size
1020 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1021 * hung, retrying the RPC(s) forever. Usually these threads
1022 * will be seen doing an uninterruptible sleep on wait channel
1023 * "newnfsreq" (truncated to "newnfsre" by procstat).
1025 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1026 tprintf(td->td_proc, LOG_WARNING,
1027 "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1030 * When doing an update, we can't change version,
1031 * security, switch lockd strategies or change cookie
1034 args.flags = (args.flags &
1040 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1047 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1048 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1053 * Make the nfs_ip_paranoia sysctl serve as the default connection
1054 * or no-connection mode for those protocols that support
1055 * no-connection mode (the flag will be cleared later for protocols
1056 * that do not support no-connection mode). This will allow a client
1057 * to receive replies from a different IP then the request was
1058 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1061 if (nfs_ip_paranoia == 0)
1062 args.flags |= NFSMNT_NOCONN;
1064 if (has_nfs_args_opt != 0) {
1066 * In the 'nfs_args' case, the pointers in the args
1067 * structure are in userland - we copy them in here.
1069 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1070 vfs_mount_error(mp, "Bad file handle");
1074 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1078 error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1081 bzero(&hst[hstlen], MNAMELEN - hstlen);
1082 args.hostname = hst;
1083 /* sockargs() call must be after above copyin() calls */
1084 error = getsockaddr(&nam, (caddr_t)args.addr,
1089 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1090 &args.fhsize) == 0) {
1091 if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1092 vfs_mount_error(mp, "Bad file handle");
1096 bcopy(args.fh, nfh, args.fhsize);
1100 (void) vfs_getopt(mp->mnt_optnew, "hostname",
1101 (void **)&args.hostname, &len);
1102 if (args.hostname == NULL) {
1103 vfs_mount_error(mp, "Invalid hostname");
1107 bcopy(args.hostname, hst, MNAMELEN);
1108 hst[MNAMELEN - 1] = '\0';
1111 if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1112 strlcpy(srvkrbname, name, sizeof (srvkrbname));
1114 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1115 srvkrbnamelen = strlen(srvkrbname);
1117 if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1118 strlcpy(krbname, name, sizeof (krbname));
1121 krbnamelen = strlen(krbname);
1123 if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0)
1124 strlcpy(dirpath, name, sizeof (dirpath));
1127 dirlen = strlen(dirpath);
1129 if (has_nfs_args_opt == 0) {
1130 if (vfs_getopt(mp->mnt_optnew, "addr",
1131 (void **)&args.addr, &args.addrlen) == 0) {
1132 if (args.addrlen > SOCK_MAXADDRLEN) {
1133 error = ENAMETOOLONG;
1136 nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1137 bcopy(args.addr, nam, args.addrlen);
1138 nam->sa_len = args.addrlen;
1140 vfs_mount_error(mp, "No server address");
1147 error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1148 dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1149 nametimeo, negnametimeo, minvers);
1153 mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF;
1164 * It seems a bit dumb to copyinstr() the host and path here and then
1165 * bcopy() them in mountnfs(), but I wanted to detect errors before
1166 * doing the sockargs() call because sockargs() allocates an mbuf and
1167 * an error after that means that I have to release the mbuf.
1171 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1174 struct nfs_args args;
1176 error = copyin(data, &args, sizeof (struct nfs_args));
1180 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1182 error = kernel_mount(ma, flags);
1187 * Common code for mount and mountroot
1190 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1191 char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1192 u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1193 struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
1196 struct nfsmount *nmp;
1198 int error, trycnt, ret;
1199 struct nfsvattr nfsva;
1200 struct nfsclclient *clp;
1201 struct nfsclds *dsp, *tdsp;
1203 static u_int64_t clval = 0;
1205 NFSCL_DEBUG(3, "in mnt\n");
1207 if (mp->mnt_flag & MNT_UPDATE) {
1209 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1210 FREE(nam, M_SONAME);
1213 MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) +
1214 krbnamelen + dirlen + srvkrbnamelen + 2,
1215 M_NEWNFSMNT, M_WAITOK | M_ZERO);
1216 TAILQ_INIT(&nmp->nm_bufq);
1218 clval = (u_int64_t)nfsboottime.tv_sec;
1219 nmp->nm_clval = clval++;
1220 nmp->nm_krbnamelen = krbnamelen;
1221 nmp->nm_dirpathlen = dirlen;
1222 nmp->nm_srvkrbnamelen = srvkrbnamelen;
1223 if (td->td_ucred->cr_uid != (uid_t)0) {
1225 * nm_uid is used to get KerberosV credentials for
1226 * the nfsv4 state handling operations if there is
1227 * no host based principal set. Use the uid of
1228 * this user if not root, since they are doing the
1229 * mount. I don't think setting this for root will
1230 * work, since root normally does not have user
1231 * credentials in a credentials cache.
1233 nmp->nm_uid = td->td_ucred->cr_uid;
1236 * Just set to -1, so it won't be used.
1238 nmp->nm_uid = (uid_t)-1;
1241 /* Copy and null terminate all the names */
1242 if (nmp->nm_krbnamelen > 0) {
1243 bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1244 nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1246 if (nmp->nm_dirpathlen > 0) {
1247 bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1248 nmp->nm_dirpathlen);
1249 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1252 if (nmp->nm_srvkrbnamelen > 0) {
1253 bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1254 nmp->nm_srvkrbnamelen);
1255 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1256 + nmp->nm_srvkrbnamelen + 2] = '\0';
1258 nmp->nm_sockreq.nr_cred = crhold(cred);
1259 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1261 nmp->nm_getinfo = nfs_getnlminfo;
1262 nmp->nm_vinvalbuf = ncl_vinvalbuf;
1265 nmp->nm_mountp = mp;
1266 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1269 * Since nfs_decode_args() might optionally set them, these
1270 * need to be set to defaults before the call, so that the
1271 * optional settings aren't overwritten.
1273 nmp->nm_nametimeo = nametimeo;
1274 nmp->nm_negnametimeo = negnametimeo;
1275 nmp->nm_timeo = NFS_TIMEO;
1276 nmp->nm_retry = NFS_RETRANS;
1277 nmp->nm_readahead = NFS_DEFRAHEAD;
1278 if (desiredvnodes >= 11000)
1279 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1281 nmp->nm_wcommitsize = hibufspace / 10;
1282 if ((argp->flags & NFSMNT_NFSV4) != 0)
1283 nmp->nm_minorvers = minvers;
1285 nmp->nm_minorvers = 0;
1287 nfs_decode_args(mp, nmp, argp, hst, cred, td);
1290 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1291 * high, depending on whether we end up with negative offsets in
1292 * the client or server somewhere. 2GB-1 may be safer.
1294 * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum
1295 * that we can handle until we find out otherwise.
1297 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1298 nmp->nm_maxfilesize = 0xffffffffLL;
1300 nmp->nm_maxfilesize = OFF_MAX;
1302 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1303 nmp->nm_wsize = NFS_WSIZE;
1304 nmp->nm_rsize = NFS_RSIZE;
1305 nmp->nm_readdirsize = NFS_READDIRSIZE;
1307 nmp->nm_numgrps = NFS_MAXGRPS;
1308 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1309 if (nmp->nm_tprintf_delay < 0)
1310 nmp->nm_tprintf_delay = 0;
1311 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1312 if (nmp->nm_tprintf_initial_delay < 0)
1313 nmp->nm_tprintf_initial_delay = 0;
1314 nmp->nm_fhsize = argp->fhsize;
1315 if (nmp->nm_fhsize > 0)
1316 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1317 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1319 /* Set up the sockets and per-host congestion */
1320 nmp->nm_sotype = argp->sotype;
1321 nmp->nm_soproto = argp->proto;
1322 nmp->nm_sockreq.nr_prog = NFS_PROG;
1323 if ((argp->flags & NFSMNT_NFSV4))
1324 nmp->nm_sockreq.nr_vers = NFS_VER4;
1325 else if ((argp->flags & NFSMNT_NFSV3))
1326 nmp->nm_sockreq.nr_vers = NFS_VER3;
1328 nmp->nm_sockreq.nr_vers = NFS_VER2;
1331 if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
1333 /* For NFSv4.1, get the clientid now. */
1334 if (nmp->nm_minorvers > 0) {
1335 NFSCL_DEBUG(3, "at getcl\n");
1336 error = nfscl_getcl(mp, cred, td, 0, &clp);
1337 NFSCL_DEBUG(3, "aft getcl=%d\n", error);
1342 if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1343 nmp->nm_dirpathlen > 0) {
1344 NFSCL_DEBUG(3, "in dirp\n");
1346 * If the fhsize on the mount point == 0 for V4, the mount
1347 * path needs to be looked up.
1351 error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1353 NFSCL_DEBUG(3, "aft dirp=%d\n", error);
1355 (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1356 } while (error && --trycnt > 0);
1358 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
1364 * A reference count is needed on the nfsnode representing the
1365 * remote root. If this object is not persistent, then backward
1366 * traversals of the mount point (i.e. "..") will not work if
1367 * the nfsnode gets flushed out of the cache. Ufs does not have
1368 * this problem, because one can identify root inodes by their
1369 * number == ROOTINO (2).
1371 if (nmp->nm_fhsize > 0) {
1373 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1374 * non-zero for the root vnode. f_iosize will be set correctly
1375 * by nfs_statfs() before any I/O occurs.
1377 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1378 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1385 * Get file attributes and transfer parameters for the
1386 * mountpoint. This has the side effect of filling in
1387 * (*vpp)->v_type with the correct value.
1389 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1390 cred, td, &nfsva, NULL, &lease);
1393 * Just set default values to get things going.
1395 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1396 nfsva.na_vattr.va_type = VDIR;
1397 nfsva.na_vattr.va_mode = 0777;
1398 nfsva.na_vattr.va_nlink = 100;
1399 nfsva.na_vattr.va_uid = (uid_t)0;
1400 nfsva.na_vattr.va_gid = (gid_t)0;
1401 nfsva.na_vattr.va_fileid = 2;
1402 nfsva.na_vattr.va_gen = 1;
1403 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1404 nfsva.na_vattr.va_size = 512 * 1024;
1407 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1408 if (nmp->nm_minorvers > 0) {
1409 NFSCL_DEBUG(3, "lease=%d\n", (int)lease);
1411 clp->nfsc_renew = NFSCL_RENEW(lease);
1412 clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
1413 clp->nfsc_clientidrev++;
1414 if (clp->nfsc_clientidrev == 0)
1415 clp->nfsc_clientidrev++;
1418 * Mount will succeed, so the renew thread can be
1421 nfscl_start_renewthread(clp);
1422 nfscl_clientrelease(clp);
1424 if (argp->flags & NFSMNT_NFSV3)
1425 ncl_fsinfo(nmp, *vpp, cred, td);
1427 /* Mark if the mount point supports NFSv4 ACLs. */
1428 if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1430 NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1432 mp->mnt_flag |= MNT_NFS4ACLS;
1437 * Lose the lock but keep the ref.
1439 NFSVOPUNLOCK(*vpp, 0);
1446 nfscl_clientrelease(clp);
1447 newnfs_disconnect(&nmp->nm_sockreq);
1448 crfree(nmp->nm_sockreq.nr_cred);
1449 if (nmp->nm_sockreq.nr_auth != NULL)
1450 AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1451 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1452 mtx_destroy(&nmp->nm_mtx);
1453 if (nmp->nm_clp != NULL) {
1455 LIST_REMOVE(nmp->nm_clp, nfsc_list);
1457 free(nmp->nm_clp, M_NFSCLCLIENT);
1459 TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp)
1460 nfscl_freenfsclds(dsp);
1461 FREE(nmp, M_NEWNFSMNT);
1462 FREE(nam, M_SONAME);
1467 * unmount system call
1470 nfs_unmount(struct mount *mp, int mntflags)
1473 struct nfsmount *nmp;
1474 int error, flags = 0, i, trycnt = 0;
1475 struct nfsclds *dsp, *tdsp;
1479 if (mntflags & MNT_FORCE)
1480 flags |= FORCECLOSE;
1483 * Goes something like this..
1484 * - Call vflush() to clear out vnodes for this filesystem
1485 * - Close the socket
1486 * - Free up the data structures
1488 /* In the forced case, cancel any outstanding requests. */
1489 if (mntflags & MNT_FORCE) {
1490 error = newnfs_nmcancelreqs(nmp);
1493 /* For a forced close, get rid of the renew thread now */
1494 nfscl_umount(nmp, td);
1496 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1498 error = vflush(mp, 1, flags, td);
1499 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1500 (void) nfs_catnap(PSOCK, error, "newndm");
1501 } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1506 * We are now committed to the unmount.
1508 if ((mntflags & MNT_FORCE) == 0)
1509 nfscl_umount(nmp, td);
1510 /* Make sure no nfsiods are assigned to this mount. */
1511 mtx_lock(&ncl_iod_mutex);
1512 for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1513 if (ncl_iodmount[i] == nmp) {
1514 ncl_iodwant[i] = NFSIOD_AVAILABLE;
1515 ncl_iodmount[i] = NULL;
1517 mtx_unlock(&ncl_iod_mutex);
1518 newnfs_disconnect(&nmp->nm_sockreq);
1519 crfree(nmp->nm_sockreq.nr_cred);
1520 FREE(nmp->nm_nam, M_SONAME);
1521 if (nmp->nm_sockreq.nr_auth != NULL)
1522 AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1523 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1524 mtx_destroy(&nmp->nm_mtx);
1525 TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp)
1526 nfscl_freenfsclds(dsp);
1527 FREE(nmp, M_NEWNFSMNT);
1533 * Return root of a filesystem
1536 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1539 struct nfsmount *nmp;
1544 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1549 * Get transfer parameters and attributes for root vnode once.
1551 mtx_lock(&nmp->nm_mtx);
1552 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1553 mtx_unlock(&nmp->nm_mtx);
1554 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1556 mtx_unlock(&nmp->nm_mtx);
1557 if (vp->v_type == VNON)
1559 vp->v_vflag |= VV_ROOT;
1565 * Flush out the buffer cache
1569 nfs_sync(struct mount *mp, int waitfor)
1571 struct vnode *vp, *mvp;
1573 int error, allerror = 0;
1579 * If a forced dismount is in progress, return from here so that
1580 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1581 * calling VFS_UNMOUNT().
1583 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1590 * Force stale buffer cache information to be flushed.
1593 MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1594 /* XXX Racy bv_cnt check. */
1595 if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1596 waitfor == MNT_LAZY) {
1600 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1601 MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1604 error = VOP_FSYNC(vp, waitfor, td);
1607 NFSVOPUNLOCK(vp, 0);
1614 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1616 struct nfsmount *nmp = VFSTONFS(mp);
1620 bzero(&vq, sizeof(vq));
1623 case VFS_CTL_NOLOCKS:
1624 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1625 if (req->oldptr != NULL) {
1626 error = SYSCTL_OUT(req, &val, sizeof(val));
1630 if (req->newptr != NULL) {
1631 error = SYSCTL_IN(req, &val, sizeof(val));
1635 nmp->nm_flag |= NFSMNT_NOLOCKS;
1637 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1642 mtx_lock(&nmp->nm_mtx);
1643 if (nmp->nm_state & NFSSTA_TIMEO)
1644 vq.vq_flags |= VQ_NOTRESP;
1645 mtx_unlock(&nmp->nm_mtx);
1647 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1648 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1649 vq.vq_flags |= VQ_NOTRESPLOCK;
1651 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1654 if (req->oldptr != NULL) {
1655 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1656 sizeof(nmp->nm_tprintf_initial_delay));
1660 if (req->newptr != NULL) {
1661 error = vfs_suser(mp, req->td);
1664 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1665 sizeof(nmp->nm_tprintf_initial_delay));
1668 if (nmp->nm_tprintf_initial_delay < 0)
1669 nmp->nm_tprintf_initial_delay = 0;
1679 * Extract the information needed by the nlm from the nfs vnode.
1682 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1683 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1684 struct timeval *timeop)
1686 struct nfsmount *nmp;
1687 struct nfsnode *np = VTONFS(vp);
1689 nmp = VFSTONFS(vp->v_mount);
1691 *fhlenp = (size_t)np->n_fhp->nfh_len;
1693 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1695 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1697 *is_v3p = NFS_ISV3(vp);
1699 *sizep = np->n_size;
1700 if (timeop != NULL) {
1701 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1702 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1707 * This function prints out an option name, based on the conditional
1710 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
1711 char *opt, char **buf, size_t *blen)
1715 if (testval != 0 && *blen > strlen(opt)) {
1716 len = snprintf(*buf, *blen, "%s", opt);
1717 if (len != strlen(opt))
1725 * This function printf out an options integer value.
1727 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
1728 char *opt, char **buf, size_t *blen)
1732 if (*blen > strlen(opt) + 1) {
1733 /* Could result in truncated output string. */
1734 len = snprintf(*buf, *blen, "%s=%d", opt, optval);
1743 * Load the option flags and values into the buffer.
1745 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
1752 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
1754 if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) {
1755 nfscl_printoptval(nmp, nmp->nm_minorvers, ",minorversion", &buf,
1757 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
1760 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
1762 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
1763 "nfsv2", &buf, &blen);
1764 nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
1765 nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
1766 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
1768 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
1770 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
1772 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
1774 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
1776 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
1778 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
1780 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1781 0, ",lockd", &buf, &blen);
1782 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1783 NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
1784 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
1786 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
1788 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1789 NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
1790 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1791 NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
1793 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1794 NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
1796 nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
1797 nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
1798 nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
1799 nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
1800 nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
1801 nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
1803 nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
1804 nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
1805 nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
1807 nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
1808 nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
1810 nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
1811 nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);