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 enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON];
84 extern struct nfsmount *ncl_iodmount[NFS_MAXASYNCDAEMON];
85 extern struct mtx ncl_iod_mutex;
87 MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
88 MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
90 SYSCTL_DECL(_vfs_nfs);
91 static int nfs_ip_paranoia = 1;
92 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
93 &nfs_ip_paranoia, 0, "");
94 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
95 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
96 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
97 /* how long between console messages "nfs server foo not responding" */
98 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
99 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
100 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
102 static int nfs_mountroot(struct mount *);
103 static void nfs_sec_name(char *, int *);
104 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
105 struct nfs_args *argp, const char *, struct ucred *,
107 static int mountnfs(struct nfs_args *, struct mount *,
108 struct sockaddr *, char *, u_char *, int, u_char *, int,
109 u_char *, int, struct vnode **, struct ucred *,
110 struct thread *, int, int);
111 static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
112 struct sockaddr_storage *, int *, off_t *,
114 static vfs_mount_t nfs_mount;
115 static vfs_cmount_t nfs_cmount;
116 static vfs_unmount_t nfs_unmount;
117 static vfs_root_t nfs_root;
118 static vfs_statfs_t nfs_statfs;
119 static vfs_sync_t nfs_sync;
120 static vfs_sysctl_t nfs_sysctl;
123 * nfs vfs operations.
125 static struct vfsops nfs_vfsops = {
126 .vfs_init = ncl_init,
127 .vfs_mount = nfs_mount,
128 .vfs_cmount = nfs_cmount,
129 .vfs_root = nfs_root,
130 .vfs_statfs = nfs_statfs,
131 .vfs_sync = nfs_sync,
132 .vfs_uninit = ncl_uninit,
133 .vfs_unmount = nfs_unmount,
134 .vfs_sysctl = nfs_sysctl,
136 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY);
138 /* So that loader and kldload(2) can find us, wherever we are.. */
139 MODULE_VERSION(nfs, 1);
140 MODULE_DEPEND(nfs, nfscommon, 1, 1, 1);
141 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
142 MODULE_DEPEND(nfs, nfssvc, 1, 1, 1);
143 MODULE_DEPEND(nfs, nfslock, 1, 1, 1);
146 * This structure is now defined in sys/nfs/nfs_diskless.c so that it
147 * can be shared by both NFS clients. It is declared here so that it
148 * will be defined for kernels built without NFS_ROOT, although it
149 * isn't used in that case.
151 #if !defined(NFS_ROOT) && !defined(NFSCLIENT)
152 struct nfs_diskless nfs_diskless = { { { 0 } } };
153 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
154 int nfs_diskless_valid = 0;
157 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
158 &nfs_diskless_valid, 0,
159 "Has the diskless struct been filled correctly");
161 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
162 nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
164 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
165 &nfsv3_diskless.root_saddr, sizeof(nfsv3_diskless.root_saddr),
166 "%Ssockaddr_in", "Diskless root nfs address");
169 void newnfsargs_ntoh(struct nfs_args *);
170 static int nfs_mountdiskless(char *,
171 struct sockaddr_in *, struct nfs_args *,
172 struct thread *, struct vnode **, struct mount *);
173 static void nfs_convert_diskless(void);
174 static void nfs_convert_oargs(struct nfs_args *args,
175 struct onfs_args *oargs);
178 newnfs_iosize(struct nfsmount *nmp)
182 /* First, set the upper limit for iosize */
183 if (nmp->nm_flag & NFSMNT_NFSV4) {
184 maxio = NFS_MAXBSIZE;
185 } else if (nmp->nm_flag & NFSMNT_NFSV3) {
186 if (nmp->nm_sotype == SOCK_DGRAM)
187 maxio = NFS_MAXDGRAMDATA;
189 maxio = NFS_MAXBSIZE;
191 maxio = NFS_V2MAXDATA;
193 if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
194 nmp->nm_rsize = maxio;
195 if (nmp->nm_rsize > MAXBSIZE)
196 nmp->nm_rsize = MAXBSIZE;
197 if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
198 nmp->nm_readdirsize = maxio;
199 if (nmp->nm_readdirsize > nmp->nm_rsize)
200 nmp->nm_readdirsize = nmp->nm_rsize;
201 if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
202 nmp->nm_wsize = maxio;
203 if (nmp->nm_wsize > MAXBSIZE)
204 nmp->nm_wsize = MAXBSIZE;
207 * Calculate the size used for io buffers. Use the larger
208 * of the two sizes to minimise nfs requests but make sure
209 * that it is at least one VM page to avoid wasting buffer
212 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
213 iosize = imax(iosize, PAGE_SIZE);
214 nmp->nm_mountp->mnt_stat.f_iosize = iosize;
219 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
222 args->version = NFS_ARGSVERSION;
223 args->addr = oargs->addr;
224 args->addrlen = oargs->addrlen;
225 args->sotype = oargs->sotype;
226 args->proto = oargs->proto;
227 args->fh = oargs->fh;
228 args->fhsize = oargs->fhsize;
229 args->flags = oargs->flags;
230 args->wsize = oargs->wsize;
231 args->rsize = oargs->rsize;
232 args->readdirsize = oargs->readdirsize;
233 args->timeo = oargs->timeo;
234 args->retrans = oargs->retrans;
235 args->readahead = oargs->readahead;
236 args->hostname = oargs->hostname;
240 nfs_convert_diskless(void)
243 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
244 sizeof(struct ifaliasreq));
245 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
246 sizeof(struct sockaddr_in));
247 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
248 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
249 nfsv3_diskless.root_fhsize = NFSX_MYFH;
250 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_MYFH);
252 nfsv3_diskless.root_fhsize = NFSX_V2FH;
253 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
255 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
256 sizeof(struct sockaddr_in));
257 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
258 nfsv3_diskless.root_time = nfs_diskless.root_time;
259 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
261 nfs_diskless_valid = 3;
268 nfs_statfs(struct mount *mp, struct statfs *sbp)
272 struct nfsmount *nmp = VFSTONFS(mp);
273 struct nfsvattr nfsva;
276 int error = 0, attrflag, gotfsinfo = 0, ret;
281 error = vfs_busy(mp, MBF_NOWAIT);
284 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
290 mtx_lock(&nmp->nm_mtx);
291 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
292 mtx_unlock(&nmp->nm_mtx);
293 error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
298 mtx_unlock(&nmp->nm_mtx);
300 error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
303 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
304 td->td_ucred, td, &nfsva, NULL);
307 * Just set default values to get things going.
309 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
310 nfsva.na_vattr.va_type = VDIR;
311 nfsva.na_vattr.va_mode = 0777;
312 nfsva.na_vattr.va_nlink = 100;
313 nfsva.na_vattr.va_uid = (uid_t)0;
314 nfsva.na_vattr.va_gid = (gid_t)0;
315 nfsva.na_vattr.va_fileid = 2;
316 nfsva.na_vattr.va_gen = 1;
317 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
318 nfsva.na_vattr.va_size = 512 * 1024;
321 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
323 mtx_lock(&nmp->nm_mtx);
324 if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
325 nfscl_loadfsinfo(nmp, &fs);
326 nfscl_loadsbinfo(nmp, &sb, sbp);
327 sbp->f_iosize = newnfs_iosize(nmp);
328 mtx_unlock(&nmp->nm_mtx);
329 if (sbp != &mp->mnt_stat) {
330 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
331 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
333 strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
334 } else if (NFS_ISV4(vp)) {
335 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
343 * nfs version 3 fsinfo rpc call
346 ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
350 struct nfsvattr nfsva;
353 error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
356 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
358 mtx_lock(&nmp->nm_mtx);
359 nfscl_loadfsinfo(nmp, &fs);
360 mtx_unlock(&nmp->nm_mtx);
366 * Mount a remote root fs via. nfs. This depends on the info in the
367 * nfs_diskless structure that has been filled in properly by some primary
369 * It goes something like this:
370 * - do enough of "ifconfig" by calling ifioctl() so that the system
371 * can talk to the server
372 * - If nfs_diskless.mygateway is filled in, use that address as
374 * - build the rootfs mount point and call mountnfs() to do the rest.
376 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
377 * structure, as well as other global NFS client variables here, as
378 * nfs_mountroot() will be called once in the boot before any other NFS
379 * client activity occurs.
382 nfs_mountroot(struct mount *mp)
384 struct thread *td = curthread;
385 struct nfsv3_diskless *nd = &nfsv3_diskless;
394 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
395 bootpc_init(); /* use bootp to get nfs_diskless filled in */
396 #elif defined(NFS_ROOT)
397 nfs_setup_diskless();
400 if (nfs_diskless_valid == 0)
402 if (nfs_diskless_valid == 1)
403 nfs_convert_diskless();
406 * XXX splnet, so networks will receive...
411 * Do enough of ifconfig(8) so that the critical net interface can
412 * talk to the server.
414 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
417 panic("nfs_mountroot: socreate(%04x): %d",
418 nd->myif.ifra_addr.sa_family, error);
420 #if 0 /* XXX Bad idea */
422 * We might not have been told the right interface, so we pass
423 * over the first ten interfaces of the same kind, until we get
424 * one of them configured.
427 for (i = strlen(nd->myif.ifra_name) - 1;
428 nd->myif.ifra_name[i] >= '0' &&
429 nd->myif.ifra_name[i] <= '9';
430 nd->myif.ifra_name[i] ++) {
431 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
436 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
438 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
439 if ((cp = getenv("boot.netif.mtu")) != NULL) {
440 ir.ifr_mtu = strtol(cp, NULL, 10);
441 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
443 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
445 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
450 * If the gateway field is filled in, set it as the default route.
451 * Note that pxeboot will set a default route of 0 if the route
452 * is not set by the DHCP server. Check also for a value of 0
453 * to avoid panicking inappropriately in that situation.
455 if (nd->mygateway.sin_len != 0 &&
456 nd->mygateway.sin_addr.s_addr != 0) {
457 struct sockaddr_in mask, sin;
459 bzero((caddr_t)&mask, sizeof(mask));
461 sin.sin_family = AF_INET;
462 sin.sin_len = sizeof(sin);
463 /* XXX MRT use table 0 for this sort of thing */
464 CURVNET_SET(TD_TO_VNET(td));
465 error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
466 (struct sockaddr *)&nd->mygateway,
467 (struct sockaddr *)&mask,
468 RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
471 panic("nfs_mountroot: RTM_ADD: %d", error);
475 * Create the rootfs mount point.
477 nd->root_args.fh = nd->root_fh;
478 nd->root_args.fhsize = nd->root_fhsize;
479 l = ntohl(nd->root_saddr.sin_addr.s_addr);
480 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
481 (l >> 24) & 0xff, (l >> 16) & 0xff,
482 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
483 printf("NFS ROOT: %s\n", buf);
484 nd->root_args.hostname = buf;
485 if ((error = nfs_mountdiskless(buf,
486 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
491 * This is not really an nfs issue, but it is much easier to
492 * set hostname here and then let the "/etc/rc.xxx" files
493 * mount the right /var based upon its preset value.
495 mtx_lock(&prison0.pr_mtx);
496 strlcpy(prison0.pr_hostname, nd->my_hostnam,
497 sizeof(prison0.pr_hostname));
498 mtx_unlock(&prison0.pr_mtx);
499 inittodr(ntohl(nd->root_time));
504 * Internal version of mount system call for diskless setup.
507 nfs_mountdiskless(char *path,
508 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
509 struct vnode **vpp, struct mount *mp)
511 struct sockaddr *nam;
516 * Find the directory path in "path", which also has the server's
517 * name/ip address in it.
519 dirpath = strchr(path, ':');
521 dirlen = strlen(++dirpath);
524 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
525 if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
526 NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
527 NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
528 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
535 nfs_sec_name(char *sec, int *flagsp)
537 if (!strcmp(sec, "krb5"))
538 *flagsp |= NFSMNT_KERB;
539 else if (!strcmp(sec, "krb5i"))
540 *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
541 else if (!strcmp(sec, "krb5p"))
542 *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
546 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
547 const char *hostname, struct ucred *cred, struct thread *td)
556 * Set read-only flag if requested; otherwise, clear it if this is
557 * an update. If this is not an update, then either the read-only
558 * flag is already clear, or this is a root mount and it was set
559 * intentionally at some previous point.
561 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
563 mp->mnt_flag |= MNT_RDONLY;
565 } else if (mp->mnt_flag & MNT_UPDATE) {
567 mp->mnt_flag &= ~MNT_RDONLY;
572 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
573 * no sense in that context. Also, set up appropriate retransmit
574 * and soft timeout behavior.
576 if (argp->sotype == SOCK_STREAM) {
577 nmp->nm_flag &= ~NFSMNT_NOCONN;
578 nmp->nm_timeo = NFS_MAXTIMEO;
579 if ((argp->flags & NFSMNT_NFSV4) != 0)
580 nmp->nm_retry = INT_MAX;
582 nmp->nm_retry = NFS_RETRANS_TCP;
585 /* Also clear RDIRPLUS if NFSv2, it crashes some servers */
586 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
587 argp->flags &= ~NFSMNT_RDIRPLUS;
588 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
591 /* Re-bind if rsrvd port requested and wasn't on one */
592 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
593 && (argp->flags & NFSMNT_RESVPORT);
594 /* Also re-bind if we're switching to/from a connected UDP socket */
595 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
596 (argp->flags & NFSMNT_NOCONN));
598 /* Update flags atomically. Don't change the lock bits. */
599 nmp->nm_flag = argp->flags | nmp->nm_flag;
602 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
603 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
604 if (nmp->nm_timeo < NFS_MINTIMEO)
605 nmp->nm_timeo = NFS_MINTIMEO;
606 else if (nmp->nm_timeo > NFS_MAXTIMEO)
607 nmp->nm_timeo = NFS_MAXTIMEO;
610 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
611 nmp->nm_retry = argp->retrans;
612 if (nmp->nm_retry > NFS_MAXREXMIT)
613 nmp->nm_retry = NFS_MAXREXMIT;
616 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
617 nmp->nm_wsize = argp->wsize;
618 /* Round down to multiple of blocksize */
619 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
620 if (nmp->nm_wsize <= 0)
621 nmp->nm_wsize = NFS_FABLKSIZE;
624 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
625 nmp->nm_rsize = argp->rsize;
626 /* Round down to multiple of blocksize */
627 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
628 if (nmp->nm_rsize <= 0)
629 nmp->nm_rsize = NFS_FABLKSIZE;
632 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
633 nmp->nm_readdirsize = argp->readdirsize;
636 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
637 nmp->nm_acregmin = argp->acregmin;
639 nmp->nm_acregmin = NFS_MINATTRTIMO;
640 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
641 nmp->nm_acregmax = argp->acregmax;
643 nmp->nm_acregmax = NFS_MAXATTRTIMO;
644 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
645 nmp->nm_acdirmin = argp->acdirmin;
647 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
648 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
649 nmp->nm_acdirmax = argp->acdirmax;
651 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
652 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
653 nmp->nm_acdirmin = nmp->nm_acdirmax;
654 if (nmp->nm_acregmin > nmp->nm_acregmax)
655 nmp->nm_acregmin = nmp->nm_acregmax;
657 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
658 if (argp->readahead <= NFS_MAXRAHEAD)
659 nmp->nm_readahead = argp->readahead;
661 nmp->nm_readahead = NFS_MAXRAHEAD;
663 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
664 if (argp->wcommitsize < nmp->nm_wsize)
665 nmp->nm_wcommitsize = nmp->nm_wsize;
667 nmp->nm_wcommitsize = argp->wcommitsize;
670 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
671 (nmp->nm_soproto != argp->proto));
673 if (nmp->nm_client != NULL && adjsock) {
674 int haslock = 0, error = 0;
676 if (nmp->nm_sotype == SOCK_STREAM) {
677 error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
682 newnfs_disconnect(&nmp->nm_sockreq);
684 newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
685 nmp->nm_sotype = argp->sotype;
686 nmp->nm_soproto = argp->proto;
687 if (nmp->nm_sotype == SOCK_DGRAM)
688 while (newnfs_connect(nmp, &nmp->nm_sockreq,
690 printf("newnfs_args: retrying connect\n");
691 (void) nfs_catnap(PSOCK, 0, "newnfscon");
695 nmp->nm_sotype = argp->sotype;
696 nmp->nm_soproto = argp->proto;
699 if (hostname != NULL) {
700 strlcpy(nmp->nm_hostname, hostname,
701 sizeof(nmp->nm_hostname));
702 p = strchr(nmp->nm_hostname, ':');
708 static const char *nfs_opts[] = { "from", "nfs_args",
709 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
710 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
711 "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
712 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
713 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport",
714 "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
715 "principal", "nfsv4", "gssname", "allgssname", "dirpath",
716 "nametimeo", "negnametimeo", "nocto", "noncontigwr", "wcommitsize",
723 * It seems a bit dumb to copyinstr() the host and path here and then
724 * bcopy() them in mountnfs(), but I wanted to detect errors before
725 * doing the sockargs() call because sockargs() allocates an mbuf and
726 * an error after that means that I have to release the mbuf.
730 nfs_mount(struct mount *mp)
732 struct nfs_args args = {
733 .version = NFS_ARGSVERSION,
735 .addrlen = sizeof (struct sockaddr_in),
736 .sotype = SOCK_STREAM,
740 .flags = NFSMNT_RESVPORT,
743 .readdirsize = NFS_READDIRSIZE,
745 .retrans = NFS_RETRANS,
746 .readahead = NFS_DEFRAHEAD,
747 .wcommitsize = 0, /* was: NQ_DEFLEASE */
749 .acregmin = NFS_MINATTRTIMO,
750 .acregmax = NFS_MAXATTRTIMO,
751 .acdirmin = NFS_MINDIRATTRTIMO,
752 .acdirmax = NFS_MAXDIRATTRTIMO,
754 int error = 0, ret, len;
755 struct sockaddr *nam = NULL;
759 u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
760 char *opt, *name, *secname;
761 int nametimeo = NFS_DEFAULT_NAMETIMEO;
762 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
763 int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen;
766 has_nfs_args_opt = 0;
767 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
773 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
774 error = nfs_mountroot(mp);
781 * The old mount_nfs program passed the struct nfs_args
782 * from userspace to kernel. The new mount_nfs program
783 * passes string options via nmount() from userspace to kernel
784 * and we populate the struct nfs_args in the kernel.
786 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
787 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
792 if (args.version != NFS_ARGSVERSION) {
793 error = EPROGMISMATCH;
796 has_nfs_args_opt = 1;
799 /* Handle the new style options. */
800 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
801 args.flags |= NFSMNT_NOCONN;
802 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
803 args.flags |= NFSMNT_NOCONN;
804 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
805 args.flags |= NFSMNT_NOLOCKD;
806 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
807 args.flags &= ~NFSMNT_NOLOCKD;
808 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
809 args.flags |= NFSMNT_INT;
810 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
811 args.flags |= NFSMNT_RDIRPLUS;
812 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
813 args.flags |= NFSMNT_RESVPORT;
814 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
815 args.flags &= ~NFSMNT_RESVPORT;
816 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
817 args.flags |= NFSMNT_SOFT;
818 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
819 args.flags &= ~NFSMNT_SOFT;
820 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
821 args.sotype = SOCK_DGRAM;
822 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
823 args.sotype = SOCK_DGRAM;
824 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
825 args.sotype = SOCK_STREAM;
826 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
827 args.flags |= NFSMNT_NFSV3;
828 if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
829 args.flags |= NFSMNT_NFSV4;
830 args.sotype = SOCK_STREAM;
832 if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
833 args.flags |= NFSMNT_ALLGSSNAME;
834 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
835 args.flags |= NFSMNT_NOCTO;
836 if (vfs_getopt(mp->mnt_optnew, "noncontigwr", NULL, NULL) == 0)
837 args.flags |= NFSMNT_NONCONTIGWR;
838 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
840 vfs_mount_error(mp, "illegal readdirsize");
844 ret = sscanf(opt, "%d", &args.readdirsize);
845 if (ret != 1 || args.readdirsize <= 0) {
846 vfs_mount_error(mp, "illegal readdirsize: %s",
851 args.flags |= NFSMNT_READDIRSIZE;
853 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
855 vfs_mount_error(mp, "illegal readahead");
859 ret = sscanf(opt, "%d", &args.readahead);
860 if (ret != 1 || args.readahead <= 0) {
861 vfs_mount_error(mp, "illegal readahead: %s",
866 args.flags |= NFSMNT_READAHEAD;
868 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
870 vfs_mount_error(mp, "illegal wsize");
874 ret = sscanf(opt, "%d", &args.wsize);
875 if (ret != 1 || args.wsize <= 0) {
876 vfs_mount_error(mp, "illegal wsize: %s",
881 args.flags |= NFSMNT_WSIZE;
883 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
885 vfs_mount_error(mp, "illegal rsize");
889 ret = sscanf(opt, "%d", &args.rsize);
890 if (ret != 1 || args.rsize <= 0) {
891 vfs_mount_error(mp, "illegal wsize: %s",
896 args.flags |= NFSMNT_RSIZE;
898 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
900 vfs_mount_error(mp, "illegal retrans");
904 ret = sscanf(opt, "%d", &args.retrans);
905 if (ret != 1 || args.retrans <= 0) {
906 vfs_mount_error(mp, "illegal retrans: %s",
911 args.flags |= NFSMNT_RETRANS;
913 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
914 ret = sscanf(opt, "%d", &args.acregmin);
915 if (ret != 1 || args.acregmin < 0) {
916 vfs_mount_error(mp, "illegal acregmin: %s",
921 args.flags |= NFSMNT_ACREGMIN;
923 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
924 ret = sscanf(opt, "%d", &args.acregmax);
925 if (ret != 1 || args.acregmax < 0) {
926 vfs_mount_error(mp, "illegal acregmax: %s",
931 args.flags |= NFSMNT_ACREGMAX;
933 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
934 ret = sscanf(opt, "%d", &args.acdirmin);
935 if (ret != 1 || args.acdirmin < 0) {
936 vfs_mount_error(mp, "illegal acdirmin: %s",
941 args.flags |= NFSMNT_ACDIRMIN;
943 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
944 ret = sscanf(opt, "%d", &args.acdirmax);
945 if (ret != 1 || args.acdirmax < 0) {
946 vfs_mount_error(mp, "illegal acdirmax: %s",
951 args.flags |= NFSMNT_ACDIRMAX;
953 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
954 ret = sscanf(opt, "%d", &args.wcommitsize);
955 if (ret != 1 || args.wcommitsize < 0) {
956 vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
960 args.flags |= NFSMNT_WCOMMITSIZE;
962 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
963 ret = sscanf(opt, "%d", &args.timeo);
964 if (ret != 1 || args.timeo <= 0) {
965 vfs_mount_error(mp, "illegal timeout: %s",
970 args.flags |= NFSMNT_TIMEO;
972 if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
973 ret = sscanf(opt, "%d", &nametimeo);
974 if (ret != 1 || nametimeo < 0) {
975 vfs_mount_error(mp, "illegal nametimeo: %s", opt);
980 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
982 ret = sscanf(opt, "%d", &negnametimeo);
983 if (ret != 1 || negnametimeo < 0) {
984 vfs_mount_error(mp, "illegal negnametimeo: %s",
990 if (vfs_getopt(mp->mnt_optnew, "sec",
991 (void **) &secname, NULL) == 0)
992 nfs_sec_name(secname, &args.flags);
994 if (mp->mnt_flag & MNT_UPDATE) {
995 struct nfsmount *nmp = VFSTONFS(mp);
1003 * If a change from TCP->UDP is done and there are thread(s)
1004 * that have I/O RPC(s) in progress with a tranfer size
1005 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1006 * hung, retrying the RPC(s) forever. Usually these threads
1007 * will be seen doing an uninterruptible sleep on wait channel
1008 * "newnfsreq" (truncated to "newnfsre" by procstat).
1010 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1011 tprintf(td->td_proc, LOG_WARNING,
1012 "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1015 * When doing an update, we can't change version,
1016 * security, switch lockd strategies or change cookie
1019 args.flags = (args.flags &
1025 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1032 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1033 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1038 * Make the nfs_ip_paranoia sysctl serve as the default connection
1039 * or no-connection mode for those protocols that support
1040 * no-connection mode (the flag will be cleared later for protocols
1041 * that do not support no-connection mode). This will allow a client
1042 * to receive replies from a different IP then the request was
1043 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1046 if (nfs_ip_paranoia == 0)
1047 args.flags |= NFSMNT_NOCONN;
1049 if (has_nfs_args_opt != 0) {
1051 * In the 'nfs_args' case, the pointers in the args
1052 * structure are in userland - we copy them in here.
1054 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1055 vfs_mount_error(mp, "Bad file handle");
1059 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1063 error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1066 bzero(&hst[hstlen], MNAMELEN - hstlen);
1067 args.hostname = hst;
1068 /* sockargs() call must be after above copyin() calls */
1069 error = getsockaddr(&nam, (caddr_t)args.addr,
1074 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1075 &args.fhsize) == 0) {
1076 if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1077 vfs_mount_error(mp, "Bad file handle");
1081 bcopy(args.fh, nfh, args.fhsize);
1085 (void) vfs_getopt(mp->mnt_optnew, "hostname",
1086 (void **)&args.hostname, &len);
1087 if (args.hostname == NULL) {
1088 vfs_mount_error(mp, "Invalid hostname");
1092 bcopy(args.hostname, hst, MNAMELEN);
1093 hst[MNAMELEN - 1] = '\0';
1096 if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1097 strlcpy(srvkrbname, name, sizeof (srvkrbname));
1099 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1100 srvkrbnamelen = strlen(srvkrbname);
1102 if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1103 strlcpy(krbname, name, sizeof (krbname));
1106 krbnamelen = strlen(krbname);
1108 if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0)
1109 strlcpy(dirpath, name, sizeof (dirpath));
1112 dirlen = strlen(dirpath);
1114 if (has_nfs_args_opt == 0) {
1115 if (vfs_getopt(mp->mnt_optnew, "addr",
1116 (void **)&args.addr, &args.addrlen) == 0) {
1117 if (args.addrlen > SOCK_MAXADDRLEN) {
1118 error = ENAMETOOLONG;
1121 nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1122 bcopy(args.addr, nam, args.addrlen);
1123 nam->sa_len = args.addrlen;
1125 vfs_mount_error(mp, "No server address");
1132 error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1133 dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1134 nametimeo, negnametimeo);
1138 mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED |
1150 * It seems a bit dumb to copyinstr() the host and path here and then
1151 * bcopy() them in mountnfs(), but I wanted to detect errors before
1152 * doing the sockargs() call because sockargs() allocates an mbuf and
1153 * an error after that means that I have to release the mbuf.
1157 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1160 struct nfs_args args;
1162 error = copyin(data, &args, sizeof (struct nfs_args));
1166 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1168 error = kernel_mount(ma, flags);
1173 * Common code for mount and mountroot
1176 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1177 char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1178 u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1179 struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo)
1181 struct nfsmount *nmp;
1183 int error, trycnt, ret;
1184 struct nfsvattr nfsva;
1185 static u_int64_t clval = 0;
1187 if (mp->mnt_flag & MNT_UPDATE) {
1189 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1190 FREE(nam, M_SONAME);
1193 MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) +
1194 krbnamelen + dirlen + srvkrbnamelen + 2,
1195 M_NEWNFSMNT, M_WAITOK | M_ZERO);
1196 TAILQ_INIT(&nmp->nm_bufq);
1198 clval = (u_int64_t)nfsboottime.tv_sec;
1199 nmp->nm_clval = clval++;
1200 nmp->nm_krbnamelen = krbnamelen;
1201 nmp->nm_dirpathlen = dirlen;
1202 nmp->nm_srvkrbnamelen = srvkrbnamelen;
1203 if (td->td_ucred->cr_uid != (uid_t)0) {
1205 * nm_uid is used to get KerberosV credentials for
1206 * the nfsv4 state handling operations if there is
1207 * no host based principal set. Use the uid of
1208 * this user if not root, since they are doing the
1209 * mount. I don't think setting this for root will
1210 * work, since root normally does not have user
1211 * credentials in a credentials cache.
1213 nmp->nm_uid = td->td_ucred->cr_uid;
1216 * Just set to -1, so it won't be used.
1218 nmp->nm_uid = (uid_t)-1;
1221 /* Copy and null terminate all the names */
1222 if (nmp->nm_krbnamelen > 0) {
1223 bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1224 nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1226 if (nmp->nm_dirpathlen > 0) {
1227 bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1228 nmp->nm_dirpathlen);
1229 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1232 if (nmp->nm_srvkrbnamelen > 0) {
1233 bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1234 nmp->nm_srvkrbnamelen);
1235 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1236 + nmp->nm_srvkrbnamelen + 2] = '\0';
1238 nmp->nm_sockreq.nr_cred = crhold(cred);
1239 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1241 nmp->nm_getinfo = nfs_getnlminfo;
1242 nmp->nm_vinvalbuf = ncl_vinvalbuf;
1245 nmp->nm_mountp = mp;
1246 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1249 * Since nfs_decode_args() might optionally set them, these
1250 * need to be set to defaults before the call, so that the
1251 * optional settings aren't overwritten.
1253 nmp->nm_nametimeo = nametimeo;
1254 nmp->nm_negnametimeo = negnametimeo;
1255 nmp->nm_timeo = NFS_TIMEO;
1256 nmp->nm_retry = NFS_RETRANS;
1257 nmp->nm_readahead = NFS_DEFRAHEAD;
1258 if (desiredvnodes >= 11000)
1259 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1261 nmp->nm_wcommitsize = hibufspace / 10;
1263 nfs_decode_args(mp, nmp, argp, hst, cred, td);
1266 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1267 * high, depending on whether we end up with negative offsets in
1268 * the client or server somewhere. 2GB-1 may be safer.
1270 * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum
1271 * that we can handle until we find out otherwise.
1272 * XXX Our "safe" limit on the client is what we can store in our
1273 * buffer cache using signed(!) block numbers.
1275 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1276 nmp->nm_maxfilesize = 0xffffffffLL;
1278 nmp->nm_maxfilesize = OFF_MAX;
1280 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1281 nmp->nm_wsize = NFS_WSIZE;
1282 nmp->nm_rsize = NFS_RSIZE;
1283 nmp->nm_readdirsize = NFS_READDIRSIZE;
1285 nmp->nm_numgrps = NFS_MAXGRPS;
1286 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1287 if (nmp->nm_tprintf_delay < 0)
1288 nmp->nm_tprintf_delay = 0;
1289 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1290 if (nmp->nm_tprintf_initial_delay < 0)
1291 nmp->nm_tprintf_initial_delay = 0;
1292 nmp->nm_fhsize = argp->fhsize;
1293 if (nmp->nm_fhsize > 0)
1294 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1295 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1297 /* Set up the sockets and per-host congestion */
1298 nmp->nm_sotype = argp->sotype;
1299 nmp->nm_soproto = argp->proto;
1300 nmp->nm_sockreq.nr_prog = NFS_PROG;
1301 if ((argp->flags & NFSMNT_NFSV4))
1302 nmp->nm_sockreq.nr_vers = NFS_VER4;
1303 else if ((argp->flags & NFSMNT_NFSV3))
1304 nmp->nm_sockreq.nr_vers = NFS_VER3;
1306 nmp->nm_sockreq.nr_vers = NFS_VER2;
1309 if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
1313 * A reference count is needed on the nfsnode representing the
1314 * remote root. If this object is not persistent, then backward
1315 * traversals of the mount point (i.e. "..") will not work if
1316 * the nfsnode gets flushed out of the cache. Ufs does not have
1317 * this problem, because one can identify root inodes by their
1318 * number == ROOTINO (2).
1320 if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1321 nmp->nm_dirpathlen > 0) {
1323 * If the fhsize on the mount point == 0 for V4, the mount
1324 * path needs to be looked up.
1328 error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1331 (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1332 } while (error && --trycnt > 0);
1334 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
1338 if (nmp->nm_fhsize > 0) {
1340 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1341 * non-zero for the root vnode. f_iosize will be set correctly
1342 * by nfs_statfs() before any I/O occurs.
1344 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1345 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1352 * Get file attributes and transfer parameters for the
1353 * mountpoint. This has the side effect of filling in
1354 * (*vpp)->v_type with the correct value.
1356 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1357 cred, td, &nfsva, NULL);
1360 * Just set default values to get things going.
1362 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1363 nfsva.na_vattr.va_type = VDIR;
1364 nfsva.na_vattr.va_mode = 0777;
1365 nfsva.na_vattr.va_nlink = 100;
1366 nfsva.na_vattr.va_uid = (uid_t)0;
1367 nfsva.na_vattr.va_gid = (gid_t)0;
1368 nfsva.na_vattr.va_fileid = 2;
1369 nfsva.na_vattr.va_gen = 1;
1370 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1371 nfsva.na_vattr.va_size = 512 * 1024;
1373 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1374 if (argp->flags & NFSMNT_NFSV3)
1375 ncl_fsinfo(nmp, *vpp, cred, td);
1377 /* Mark if the mount point supports NFSv4 ACLs. */
1378 if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1380 NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1382 mp->mnt_flag |= MNT_NFS4ACLS;
1387 * Lose the lock but keep the ref.
1389 NFSVOPUNLOCK(*vpp, 0);
1395 newnfs_disconnect(&nmp->nm_sockreq);
1396 crfree(nmp->nm_sockreq.nr_cred);
1397 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1398 mtx_destroy(&nmp->nm_mtx);
1399 FREE(nmp, M_NEWNFSMNT);
1400 FREE(nam, M_SONAME);
1405 * unmount system call
1408 nfs_unmount(struct mount *mp, int mntflags)
1411 struct nfsmount *nmp;
1412 int error, flags = 0, i, trycnt = 0;
1416 if (mntflags & MNT_FORCE)
1417 flags |= FORCECLOSE;
1420 * Goes something like this..
1421 * - Call vflush() to clear out vnodes for this filesystem
1422 * - Close the socket
1423 * - Free up the data structures
1425 /* In the forced case, cancel any outstanding requests. */
1426 if (mntflags & MNT_FORCE) {
1427 error = newnfs_nmcancelreqs(nmp);
1430 /* For a forced close, get rid of the renew thread now */
1431 nfscl_umount(nmp, td);
1433 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1435 error = vflush(mp, 1, flags, td);
1436 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1437 (void) nfs_catnap(PSOCK, error, "newndm");
1438 } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1443 * We are now committed to the unmount.
1445 if ((mntflags & MNT_FORCE) == 0)
1446 nfscl_umount(nmp, td);
1447 /* Make sure no nfsiods are assigned to this mount. */
1448 mtx_lock(&ncl_iod_mutex);
1449 for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1450 if (ncl_iodmount[i] == nmp) {
1451 ncl_iodwant[i] = NFSIOD_AVAILABLE;
1452 ncl_iodmount[i] = NULL;
1454 mtx_unlock(&ncl_iod_mutex);
1455 newnfs_disconnect(&nmp->nm_sockreq);
1456 crfree(nmp->nm_sockreq.nr_cred);
1457 FREE(nmp->nm_nam, M_SONAME);
1459 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1460 mtx_destroy(&nmp->nm_mtx);
1461 FREE(nmp, M_NEWNFSMNT);
1467 * Return root of a filesystem
1470 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1473 struct nfsmount *nmp;
1478 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1483 * Get transfer parameters and attributes for root vnode once.
1485 mtx_lock(&nmp->nm_mtx);
1486 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1487 mtx_unlock(&nmp->nm_mtx);
1488 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1490 mtx_unlock(&nmp->nm_mtx);
1491 if (vp->v_type == VNON)
1493 vp->v_vflag |= VV_ROOT;
1499 * Flush out the buffer cache
1503 nfs_sync(struct mount *mp, int waitfor)
1505 struct vnode *vp, *mvp;
1507 int error, allerror = 0;
1513 * If a forced dismount is in progress, return from here so that
1514 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1515 * calling VFS_UNMOUNT().
1517 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1524 * Force stale buffer cache information to be flushed.
1527 MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1528 /* XXX Racy bv_cnt check. */
1529 if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1530 waitfor == MNT_LAZY) {
1534 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1535 MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1538 error = VOP_FSYNC(vp, waitfor, td);
1541 NFSVOPUNLOCK(vp, 0);
1548 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1550 struct nfsmount *nmp = VFSTONFS(mp);
1554 bzero(&vq, sizeof(vq));
1557 case VFS_CTL_NOLOCKS:
1558 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1559 if (req->oldptr != NULL) {
1560 error = SYSCTL_OUT(req, &val, sizeof(val));
1564 if (req->newptr != NULL) {
1565 error = SYSCTL_IN(req, &val, sizeof(val));
1569 nmp->nm_flag |= NFSMNT_NOLOCKS;
1571 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1576 mtx_lock(&nmp->nm_mtx);
1577 if (nmp->nm_state & NFSSTA_TIMEO)
1578 vq.vq_flags |= VQ_NOTRESP;
1579 mtx_unlock(&nmp->nm_mtx);
1581 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1582 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1583 vq.vq_flags |= VQ_NOTRESPLOCK;
1585 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1588 if (req->oldptr != NULL) {
1589 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1590 sizeof(nmp->nm_tprintf_initial_delay));
1594 if (req->newptr != NULL) {
1595 error = vfs_suser(mp, req->td);
1598 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1599 sizeof(nmp->nm_tprintf_initial_delay));
1602 if (nmp->nm_tprintf_initial_delay < 0)
1603 nmp->nm_tprintf_initial_delay = 0;
1613 * Extract the information needed by the nlm from the nfs vnode.
1616 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1617 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1618 struct timeval *timeop)
1620 struct nfsmount *nmp;
1621 struct nfsnode *np = VTONFS(vp);
1623 nmp = VFSTONFS(vp->v_mount);
1625 *fhlenp = (size_t)np->n_fhp->nfh_len;
1627 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1629 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1631 *is_v3p = NFS_ISV3(vp);
1633 *sizep = np->n_size;
1634 if (timeop != NULL) {
1635 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1636 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1641 * This function prints out an option name, based on the conditional
1644 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
1645 char *opt, char **buf, size_t *blen)
1649 if (testval != 0 && *blen > strlen(opt)) {
1650 len = snprintf(*buf, *blen, "%s", opt);
1651 if (len != strlen(opt))
1659 * This function printf out an options integer value.
1661 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
1662 char *opt, char **buf, size_t *blen)
1666 if (*blen > strlen(opt) + 1) {
1667 /* Could result in truncated output string. */
1668 len = snprintf(*buf, *blen, "%s=%d", opt, optval);
1677 * Load the option flags and values into the buffer.
1679 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
1686 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
1688 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
1690 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
1691 "nfsv2", &buf, &blen);
1692 nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
1693 nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
1694 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
1696 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
1698 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
1700 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
1702 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
1704 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
1706 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
1708 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NONCONTIGWR) != 0,
1709 ",noncontigwr", &buf, &blen);
1710 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1711 0, ",lockd", &buf, &blen);
1712 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1713 NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
1714 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
1716 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
1718 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1719 NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
1720 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1721 NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
1723 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1724 NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
1726 nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
1727 nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
1728 nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
1729 nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
1730 nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
1731 nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
1733 nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
1734 nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
1735 nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
1737 nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
1738 nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
1740 nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
1741 nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);