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", "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, "readdirsize", (void **)&opt, NULL) == 0) {
838 vfs_mount_error(mp, "illegal readdirsize");
842 ret = sscanf(opt, "%d", &args.readdirsize);
843 if (ret != 1 || args.readdirsize <= 0) {
844 vfs_mount_error(mp, "illegal readdirsize: %s",
849 args.flags |= NFSMNT_READDIRSIZE;
851 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
853 vfs_mount_error(mp, "illegal readahead");
857 ret = sscanf(opt, "%d", &args.readahead);
858 if (ret != 1 || args.readahead <= 0) {
859 vfs_mount_error(mp, "illegal readahead: %s",
864 args.flags |= NFSMNT_READAHEAD;
866 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
868 vfs_mount_error(mp, "illegal wsize");
872 ret = sscanf(opt, "%d", &args.wsize);
873 if (ret != 1 || args.wsize <= 0) {
874 vfs_mount_error(mp, "illegal wsize: %s",
879 args.flags |= NFSMNT_WSIZE;
881 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
883 vfs_mount_error(mp, "illegal rsize");
887 ret = sscanf(opt, "%d", &args.rsize);
888 if (ret != 1 || args.rsize <= 0) {
889 vfs_mount_error(mp, "illegal wsize: %s",
894 args.flags |= NFSMNT_RSIZE;
896 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
898 vfs_mount_error(mp, "illegal retrans");
902 ret = sscanf(opt, "%d", &args.retrans);
903 if (ret != 1 || args.retrans <= 0) {
904 vfs_mount_error(mp, "illegal retrans: %s",
909 args.flags |= NFSMNT_RETRANS;
911 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
912 ret = sscanf(opt, "%d", &args.acregmin);
913 if (ret != 1 || args.acregmin < 0) {
914 vfs_mount_error(mp, "illegal acregmin: %s",
919 args.flags |= NFSMNT_ACREGMIN;
921 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
922 ret = sscanf(opt, "%d", &args.acregmax);
923 if (ret != 1 || args.acregmax < 0) {
924 vfs_mount_error(mp, "illegal acregmax: %s",
929 args.flags |= NFSMNT_ACREGMAX;
931 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
932 ret = sscanf(opt, "%d", &args.acdirmin);
933 if (ret != 1 || args.acdirmin < 0) {
934 vfs_mount_error(mp, "illegal acdirmin: %s",
939 args.flags |= NFSMNT_ACDIRMIN;
941 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
942 ret = sscanf(opt, "%d", &args.acdirmax);
943 if (ret != 1 || args.acdirmax < 0) {
944 vfs_mount_error(mp, "illegal acdirmax: %s",
949 args.flags |= NFSMNT_ACDIRMAX;
951 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
952 ret = sscanf(opt, "%d", &args.wcommitsize);
953 if (ret != 1 || args.wcommitsize < 0) {
954 vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
958 args.flags |= NFSMNT_WCOMMITSIZE;
960 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
961 ret = sscanf(opt, "%d", &args.timeo);
962 if (ret != 1 || args.timeo <= 0) {
963 vfs_mount_error(mp, "illegal timeout: %s",
968 args.flags |= NFSMNT_TIMEO;
970 if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
971 ret = sscanf(opt, "%d", &nametimeo);
972 if (ret != 1 || nametimeo < 0) {
973 vfs_mount_error(mp, "illegal nametimeo: %s", opt);
978 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
980 ret = sscanf(opt, "%d", &negnametimeo);
981 if (ret != 1 || negnametimeo < 0) {
982 vfs_mount_error(mp, "illegal negnametimeo: %s",
988 if (vfs_getopt(mp->mnt_optnew, "sec",
989 (void **) &secname, NULL) == 0)
990 nfs_sec_name(secname, &args.flags);
992 if (mp->mnt_flag & MNT_UPDATE) {
993 struct nfsmount *nmp = VFSTONFS(mp);
1001 * If a change from TCP->UDP is done and there are thread(s)
1002 * that have I/O RPC(s) in progress with a tranfer size
1003 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1004 * hung, retrying the RPC(s) forever. Usually these threads
1005 * will be seen doing an uninterruptible sleep on wait channel
1006 * "newnfsreq" (truncated to "newnfsre" by procstat).
1008 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1009 tprintf(td->td_proc, LOG_WARNING,
1010 "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1013 * When doing an update, we can't change version,
1014 * security, switch lockd strategies or change cookie
1017 args.flags = (args.flags &
1023 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1030 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1031 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1036 * Make the nfs_ip_paranoia sysctl serve as the default connection
1037 * or no-connection mode for those protocols that support
1038 * no-connection mode (the flag will be cleared later for protocols
1039 * that do not support no-connection mode). This will allow a client
1040 * to receive replies from a different IP then the request was
1041 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1044 if (nfs_ip_paranoia == 0)
1045 args.flags |= NFSMNT_NOCONN;
1047 if (has_nfs_args_opt != 0) {
1049 * In the 'nfs_args' case, the pointers in the args
1050 * structure are in userland - we copy them in here.
1052 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1053 vfs_mount_error(mp, "Bad file handle");
1057 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1061 error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1064 bzero(&hst[hstlen], MNAMELEN - hstlen);
1065 args.hostname = hst;
1066 /* sockargs() call must be after above copyin() calls */
1067 error = getsockaddr(&nam, (caddr_t)args.addr,
1072 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1073 &args.fhsize) == 0) {
1074 if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1075 vfs_mount_error(mp, "Bad file handle");
1079 bcopy(args.fh, nfh, args.fhsize);
1083 (void) vfs_getopt(mp->mnt_optnew, "hostname",
1084 (void **)&args.hostname, &len);
1085 if (args.hostname == NULL) {
1086 vfs_mount_error(mp, "Invalid hostname");
1090 bcopy(args.hostname, hst, MNAMELEN);
1091 hst[MNAMELEN - 1] = '\0';
1094 if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1095 strlcpy(srvkrbname, name, sizeof (srvkrbname));
1097 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1098 srvkrbnamelen = strlen(srvkrbname);
1100 if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1101 strlcpy(krbname, name, sizeof (krbname));
1104 krbnamelen = strlen(krbname);
1106 if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0)
1107 strlcpy(dirpath, name, sizeof (dirpath));
1110 dirlen = strlen(dirpath);
1112 if (has_nfs_args_opt == 0) {
1113 if (vfs_getopt(mp->mnt_optnew, "addr",
1114 (void **)&args.addr, &args.addrlen) == 0) {
1115 if (args.addrlen > SOCK_MAXADDRLEN) {
1116 error = ENAMETOOLONG;
1119 nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1120 bcopy(args.addr, nam, args.addrlen);
1121 nam->sa_len = args.addrlen;
1123 vfs_mount_error(mp, "No server address");
1130 error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1131 dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1132 nametimeo, negnametimeo);
1136 mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED |
1148 * It seems a bit dumb to copyinstr() the host and path here and then
1149 * bcopy() them in mountnfs(), but I wanted to detect errors before
1150 * doing the sockargs() call because sockargs() allocates an mbuf and
1151 * an error after that means that I have to release the mbuf.
1155 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1158 struct nfs_args args;
1160 error = copyin(data, &args, sizeof (struct nfs_args));
1164 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1166 error = kernel_mount(ma, flags);
1171 * Common code for mount and mountroot
1174 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1175 char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1176 u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1177 struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo)
1179 struct nfsmount *nmp;
1181 int error, trycnt, ret;
1182 struct nfsvattr nfsva;
1183 static u_int64_t clval = 0;
1185 if (mp->mnt_flag & MNT_UPDATE) {
1187 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1188 FREE(nam, M_SONAME);
1191 MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) +
1192 krbnamelen + dirlen + srvkrbnamelen + 2,
1193 M_NEWNFSMNT, M_WAITOK | M_ZERO);
1194 TAILQ_INIT(&nmp->nm_bufq);
1196 clval = (u_int64_t)nfsboottime.tv_sec;
1197 nmp->nm_clval = clval++;
1198 nmp->nm_krbnamelen = krbnamelen;
1199 nmp->nm_dirpathlen = dirlen;
1200 nmp->nm_srvkrbnamelen = srvkrbnamelen;
1201 if (td->td_ucred->cr_uid != (uid_t)0) {
1203 * nm_uid is used to get KerberosV credentials for
1204 * the nfsv4 state handling operations if there is
1205 * no host based principal set. Use the uid of
1206 * this user if not root, since they are doing the
1207 * mount. I don't think setting this for root will
1208 * work, since root normally does not have user
1209 * credentials in a credentials cache.
1211 nmp->nm_uid = td->td_ucred->cr_uid;
1214 * Just set to -1, so it won't be used.
1216 nmp->nm_uid = (uid_t)-1;
1219 /* Copy and null terminate all the names */
1220 if (nmp->nm_krbnamelen > 0) {
1221 bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1222 nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1224 if (nmp->nm_dirpathlen > 0) {
1225 bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1226 nmp->nm_dirpathlen);
1227 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1230 if (nmp->nm_srvkrbnamelen > 0) {
1231 bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1232 nmp->nm_srvkrbnamelen);
1233 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1234 + nmp->nm_srvkrbnamelen + 2] = '\0';
1236 nmp->nm_sockreq.nr_cred = crhold(cred);
1237 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1239 nmp->nm_getinfo = nfs_getnlminfo;
1240 nmp->nm_vinvalbuf = ncl_vinvalbuf;
1243 nmp->nm_mountp = mp;
1244 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1247 * Since nfs_decode_args() might optionally set them, these
1248 * need to be set to defaults before the call, so that the
1249 * optional settings aren't overwritten.
1251 nmp->nm_nametimeo = nametimeo;
1252 nmp->nm_negnametimeo = negnametimeo;
1253 nmp->nm_timeo = NFS_TIMEO;
1254 nmp->nm_retry = NFS_RETRANS;
1255 nmp->nm_readahead = NFS_DEFRAHEAD;
1256 if (desiredvnodes >= 11000)
1257 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1259 nmp->nm_wcommitsize = hibufspace / 10;
1261 nfs_decode_args(mp, nmp, argp, hst, cred, td);
1264 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1265 * high, depending on whether we end up with negative offsets in
1266 * the client or server somewhere. 2GB-1 may be safer.
1268 * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum
1269 * that we can handle until we find out otherwise.
1270 * XXX Our "safe" limit on the client is what we can store in our
1271 * buffer cache using signed(!) block numbers.
1273 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1274 nmp->nm_maxfilesize = 0xffffffffLL;
1276 nmp->nm_maxfilesize = OFF_MAX;
1278 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1279 nmp->nm_wsize = NFS_WSIZE;
1280 nmp->nm_rsize = NFS_RSIZE;
1281 nmp->nm_readdirsize = NFS_READDIRSIZE;
1283 nmp->nm_numgrps = NFS_MAXGRPS;
1284 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1285 if (nmp->nm_tprintf_delay < 0)
1286 nmp->nm_tprintf_delay = 0;
1287 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1288 if (nmp->nm_tprintf_initial_delay < 0)
1289 nmp->nm_tprintf_initial_delay = 0;
1290 nmp->nm_fhsize = argp->fhsize;
1291 if (nmp->nm_fhsize > 0)
1292 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1293 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1295 /* Set up the sockets and per-host congestion */
1296 nmp->nm_sotype = argp->sotype;
1297 nmp->nm_soproto = argp->proto;
1298 nmp->nm_sockreq.nr_prog = NFS_PROG;
1299 if ((argp->flags & NFSMNT_NFSV4))
1300 nmp->nm_sockreq.nr_vers = NFS_VER4;
1301 else if ((argp->flags & NFSMNT_NFSV3))
1302 nmp->nm_sockreq.nr_vers = NFS_VER3;
1304 nmp->nm_sockreq.nr_vers = NFS_VER2;
1307 if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
1311 * A reference count is needed on the nfsnode representing the
1312 * remote root. If this object is not persistent, then backward
1313 * traversals of the mount point (i.e. "..") will not work if
1314 * the nfsnode gets flushed out of the cache. Ufs does not have
1315 * this problem, because one can identify root inodes by their
1316 * number == ROOTINO (2).
1318 if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1319 nmp->nm_dirpathlen > 0) {
1321 * If the fhsize on the mount point == 0 for V4, the mount
1322 * path needs to be looked up.
1326 error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1329 (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1330 } while (error && --trycnt > 0);
1332 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
1336 if (nmp->nm_fhsize > 0) {
1338 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1339 * non-zero for the root vnode. f_iosize will be set correctly
1340 * by nfs_statfs() before any I/O occurs.
1342 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1343 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1350 * Get file attributes and transfer parameters for the
1351 * mountpoint. This has the side effect of filling in
1352 * (*vpp)->v_type with the correct value.
1354 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1355 cred, td, &nfsva, NULL);
1358 * Just set default values to get things going.
1360 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1361 nfsva.na_vattr.va_type = VDIR;
1362 nfsva.na_vattr.va_mode = 0777;
1363 nfsva.na_vattr.va_nlink = 100;
1364 nfsva.na_vattr.va_uid = (uid_t)0;
1365 nfsva.na_vattr.va_gid = (gid_t)0;
1366 nfsva.na_vattr.va_fileid = 2;
1367 nfsva.na_vattr.va_gen = 1;
1368 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1369 nfsva.na_vattr.va_size = 512 * 1024;
1371 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1372 if (argp->flags & NFSMNT_NFSV3)
1373 ncl_fsinfo(nmp, *vpp, cred, td);
1375 /* Mark if the mount point supports NFSv4 ACLs. */
1376 if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1378 NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1380 mp->mnt_flag |= MNT_NFS4ACLS;
1385 * Lose the lock but keep the ref.
1387 NFSVOPUNLOCK(*vpp, 0);
1393 newnfs_disconnect(&nmp->nm_sockreq);
1394 crfree(nmp->nm_sockreq.nr_cred);
1395 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1396 mtx_destroy(&nmp->nm_mtx);
1397 FREE(nmp, M_NEWNFSMNT);
1398 FREE(nam, M_SONAME);
1403 * unmount system call
1406 nfs_unmount(struct mount *mp, int mntflags)
1409 struct nfsmount *nmp;
1410 int error, flags = 0, i, trycnt = 0;
1414 if (mntflags & MNT_FORCE)
1415 flags |= FORCECLOSE;
1418 * Goes something like this..
1419 * - Call vflush() to clear out vnodes for this filesystem
1420 * - Close the socket
1421 * - Free up the data structures
1423 /* In the forced case, cancel any outstanding requests. */
1424 if (mntflags & MNT_FORCE) {
1425 error = newnfs_nmcancelreqs(nmp);
1428 /* For a forced close, get rid of the renew thread now */
1429 nfscl_umount(nmp, td);
1431 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1433 error = vflush(mp, 1, flags, td);
1434 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1435 (void) nfs_catnap(PSOCK, error, "newndm");
1436 } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1441 * We are now committed to the unmount.
1443 if ((mntflags & MNT_FORCE) == 0)
1444 nfscl_umount(nmp, td);
1445 /* Make sure no nfsiods are assigned to this mount. */
1446 mtx_lock(&ncl_iod_mutex);
1447 for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1448 if (ncl_iodmount[i] == nmp) {
1449 ncl_iodwant[i] = NFSIOD_AVAILABLE;
1450 ncl_iodmount[i] = NULL;
1452 mtx_unlock(&ncl_iod_mutex);
1453 newnfs_disconnect(&nmp->nm_sockreq);
1454 crfree(nmp->nm_sockreq.nr_cred);
1455 FREE(nmp->nm_nam, M_SONAME);
1457 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1458 mtx_destroy(&nmp->nm_mtx);
1459 FREE(nmp, M_NEWNFSMNT);
1465 * Return root of a filesystem
1468 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1471 struct nfsmount *nmp;
1476 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1481 * Get transfer parameters and attributes for root vnode once.
1483 mtx_lock(&nmp->nm_mtx);
1484 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1485 mtx_unlock(&nmp->nm_mtx);
1486 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1488 mtx_unlock(&nmp->nm_mtx);
1489 if (vp->v_type == VNON)
1491 vp->v_vflag |= VV_ROOT;
1497 * Flush out the buffer cache
1501 nfs_sync(struct mount *mp, int waitfor)
1503 struct vnode *vp, *mvp;
1505 int error, allerror = 0;
1511 * If a forced dismount is in progress, return from here so that
1512 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1513 * calling VFS_UNMOUNT().
1515 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1522 * Force stale buffer cache information to be flushed.
1525 MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1526 /* XXX Racy bv_cnt check. */
1527 if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1528 waitfor == MNT_LAZY) {
1532 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1533 MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1536 error = VOP_FSYNC(vp, waitfor, td);
1539 NFSVOPUNLOCK(vp, 0);
1546 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1548 struct nfsmount *nmp = VFSTONFS(mp);
1552 bzero(&vq, sizeof(vq));
1555 case VFS_CTL_NOLOCKS:
1556 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1557 if (req->oldptr != NULL) {
1558 error = SYSCTL_OUT(req, &val, sizeof(val));
1562 if (req->newptr != NULL) {
1563 error = SYSCTL_IN(req, &val, sizeof(val));
1567 nmp->nm_flag |= NFSMNT_NOLOCKS;
1569 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1574 mtx_lock(&nmp->nm_mtx);
1575 if (nmp->nm_state & NFSSTA_TIMEO)
1576 vq.vq_flags |= VQ_NOTRESP;
1577 mtx_unlock(&nmp->nm_mtx);
1579 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1580 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1581 vq.vq_flags |= VQ_NOTRESPLOCK;
1583 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1586 if (req->oldptr != NULL) {
1587 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1588 sizeof(nmp->nm_tprintf_initial_delay));
1592 if (req->newptr != NULL) {
1593 error = vfs_suser(mp, req->td);
1596 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1597 sizeof(nmp->nm_tprintf_initial_delay));
1600 if (nmp->nm_tprintf_initial_delay < 0)
1601 nmp->nm_tprintf_initial_delay = 0;
1611 * Extract the information needed by the nlm from the nfs vnode.
1614 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1615 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1616 struct timeval *timeop)
1618 struct nfsmount *nmp;
1619 struct nfsnode *np = VTONFS(vp);
1621 nmp = VFSTONFS(vp->v_mount);
1623 *fhlenp = (size_t)np->n_fhp->nfh_len;
1625 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1627 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1629 *is_v3p = NFS_ISV3(vp);
1631 *sizep = np->n_size;
1632 if (timeop != NULL) {
1633 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1634 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1639 * This function prints out an option name, based on the conditional
1642 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
1643 char *opt, char **buf, size_t *blen)
1647 if (testval != 0 && *blen > strlen(opt)) {
1648 len = snprintf(*buf, *blen, "%s", opt);
1649 if (len != strlen(opt))
1657 * This function printf out an options integer value.
1659 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
1660 char *opt, char **buf, size_t *blen)
1664 if (*blen > strlen(opt) + 1) {
1665 /* Could result in truncated output string. */
1666 len = snprintf(*buf, *blen, "%s=%d", opt, optval);
1675 * Load the option flags and values into the buffer.
1677 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
1684 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
1686 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
1688 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
1689 "nfsv2", &buf, &blen);
1690 nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
1691 nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
1692 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
1694 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
1696 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
1698 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
1700 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
1702 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
1704 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
1706 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1707 0, ",lockd", &buf, &blen);
1708 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1709 NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
1710 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
1712 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
1714 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1715 NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
1716 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1717 NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
1719 nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1720 NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
1722 nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
1723 nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
1724 nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
1725 nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
1726 nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
1727 nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
1729 nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
1730 nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
1731 nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
1733 nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
1734 nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
1736 nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
1737 nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);