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 extern int nfscl_ticks;
78 extern struct timeval nfsboottime;
79 extern struct nfsstats newnfsstats;
80 extern int nfsrv_useacl;
82 MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
83 MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
85 SYSCTL_DECL(_vfs_newnfs);
86 SYSCTL_STRUCT(_vfs_newnfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
87 &newnfsstats, nfsstats, "S,nfsstats");
88 static int nfs_ip_paranoia = 1;
89 SYSCTL_INT(_vfs_newnfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
90 &nfs_ip_paranoia, 0, "");
91 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
92 SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_INITIAL_DELAY,
93 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
94 /* how long between console messages "nfs server foo not responding" */
95 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
96 SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_DELAY,
97 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
99 static int nfs_mountroot(struct mount *);
100 static void nfs_sec_name(char *, int *);
101 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
102 struct nfs_args *argp, const char *, struct ucred *,
104 static int mountnfs(struct nfs_args *, struct mount *,
105 struct sockaddr *, char *, u_char *, int, u_char *, int,
106 u_char *, int, struct vnode **, struct ucred *,
107 struct thread *, int);
108 static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
109 struct sockaddr_storage *, int *, off_t *,
111 static vfs_mount_t nfs_mount;
112 static vfs_cmount_t nfs_cmount;
113 static vfs_unmount_t nfs_unmount;
114 static vfs_root_t nfs_root;
115 static vfs_statfs_t nfs_statfs;
116 static vfs_sync_t nfs_sync;
117 static vfs_sysctl_t nfs_sysctl;
120 * nfs vfs operations.
122 static struct vfsops nfs_vfsops = {
123 .vfs_init = ncl_init,
124 .vfs_mount = nfs_mount,
125 .vfs_cmount = nfs_cmount,
126 .vfs_root = nfs_root,
127 .vfs_statfs = nfs_statfs,
128 .vfs_sync = nfs_sync,
129 .vfs_uninit = ncl_uninit,
130 .vfs_unmount = nfs_unmount,
131 .vfs_sysctl = nfs_sysctl,
133 VFS_SET(nfs_vfsops, newnfs, VFCF_NETWORK);
135 /* So that loader and kldload(2) can find us, wherever we are.. */
136 MODULE_VERSION(newnfs, 1);
139 * This structure is now defined in sys/nfs/nfs_diskless.c so that it
140 * can be shared by both NFS clients. It is declared here so that it
141 * will be defined for kernels built without NFS_ROOT, although it
142 * isn't used in that case.
144 #if !defined(NFS_ROOT) && !defined(NFSCLIENT)
145 struct nfs_diskless nfs_diskless = { { { 0 } } };
146 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
147 int nfs_diskless_valid = 0;
150 SYSCTL_INT(_vfs_newnfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
151 &nfs_diskless_valid, 0,
152 "Has the diskless struct been filled correctly");
154 SYSCTL_STRING(_vfs_newnfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
155 nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
157 SYSCTL_OPAQUE(_vfs_newnfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
158 &nfsv3_diskless.root_saddr, sizeof(nfsv3_diskless.root_saddr),
159 "%Ssockaddr_in", "Diskless root nfs address");
162 void newnfsargs_ntoh(struct nfs_args *);
163 static int nfs_mountdiskless(char *,
164 struct sockaddr_in *, struct nfs_args *,
165 struct thread *, struct vnode **, struct mount *);
166 static void nfs_convert_diskless(void);
167 static void nfs_convert_oargs(struct nfs_args *args,
168 struct onfs_args *oargs);
171 newnfs_iosize(struct nfsmount *nmp)
175 /* First, set the upper limit for iosize */
176 if (nmp->nm_flag & NFSMNT_NFSV4) {
177 maxio = NFS_MAXBSIZE;
178 } else if (nmp->nm_flag & NFSMNT_NFSV3) {
179 if (nmp->nm_sotype == SOCK_DGRAM)
180 maxio = NFS_MAXDGRAMDATA;
182 maxio = NFS_MAXBSIZE;
184 maxio = NFS_V2MAXDATA;
186 if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
187 nmp->nm_rsize = maxio;
188 if (nmp->nm_rsize > MAXBSIZE)
189 nmp->nm_rsize = MAXBSIZE;
190 if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
191 nmp->nm_readdirsize = maxio;
192 if (nmp->nm_readdirsize > nmp->nm_rsize)
193 nmp->nm_readdirsize = nmp->nm_rsize;
194 if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
195 nmp->nm_wsize = maxio;
196 if (nmp->nm_wsize > MAXBSIZE)
197 nmp->nm_wsize = MAXBSIZE;
200 * Calculate the size used for io buffers. Use the larger
201 * of the two sizes to minimise nfs requests but make sure
202 * that it is at least one VM page to avoid wasting buffer
205 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
206 iosize = imax(iosize, PAGE_SIZE);
207 nmp->nm_mountp->mnt_stat.f_iosize = iosize;
212 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
215 args->version = NFS_ARGSVERSION;
216 args->addr = oargs->addr;
217 args->addrlen = oargs->addrlen;
218 args->sotype = oargs->sotype;
219 args->proto = oargs->proto;
220 args->fh = oargs->fh;
221 args->fhsize = oargs->fhsize;
222 args->flags = oargs->flags;
223 args->wsize = oargs->wsize;
224 args->rsize = oargs->rsize;
225 args->readdirsize = oargs->readdirsize;
226 args->timeo = oargs->timeo;
227 args->retrans = oargs->retrans;
228 args->readahead = oargs->readahead;
229 args->hostname = oargs->hostname;
233 nfs_convert_diskless(void)
236 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
237 sizeof(struct ifaliasreq));
238 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
239 sizeof(struct sockaddr_in));
240 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
241 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
242 nfsv3_diskless.root_fhsize = NFSX_MYFH;
243 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_MYFH);
245 nfsv3_diskless.root_fhsize = NFSX_V2FH;
246 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
248 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
249 sizeof(struct sockaddr_in));
250 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
251 nfsv3_diskless.root_time = nfs_diskless.root_time;
252 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
254 nfs_diskless_valid = 3;
261 nfs_statfs(struct mount *mp, struct statfs *sbp)
265 struct nfsmount *nmp = VFSTONFS(mp);
266 struct nfsvattr nfsva;
269 int error = 0, attrflag, gotfsinfo = 0, ret;
274 error = vfs_busy(mp, MBF_NOWAIT);
277 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
283 mtx_lock(&nmp->nm_mtx);
284 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
285 mtx_unlock(&nmp->nm_mtx);
286 error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
291 mtx_unlock(&nmp->nm_mtx);
293 error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
296 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
297 td->td_ucred, td, &nfsva, NULL);
300 * Just set default values to get things going.
302 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
303 nfsva.na_vattr.va_type = VDIR;
304 nfsva.na_vattr.va_mode = 0777;
305 nfsva.na_vattr.va_nlink = 100;
306 nfsva.na_vattr.va_uid = (uid_t)0;
307 nfsva.na_vattr.va_gid = (gid_t)0;
308 nfsva.na_vattr.va_fileid = 2;
309 nfsva.na_vattr.va_gen = 1;
310 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
311 nfsva.na_vattr.va_size = 512 * 1024;
314 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
316 mtx_lock(&nmp->nm_mtx);
317 if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
318 nfscl_loadfsinfo(nmp, &fs);
319 nfscl_loadsbinfo(nmp, &sb, sbp);
320 sbp->f_iosize = newnfs_iosize(nmp);
321 mtx_unlock(&nmp->nm_mtx);
322 if (sbp != &mp->mnt_stat) {
323 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
324 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
326 strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
327 } else if (NFS_ISV4(vp)) {
328 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
336 * nfs version 3 fsinfo rpc call
339 ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
343 struct nfsvattr nfsva;
346 error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
349 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
351 mtx_lock(&nmp->nm_mtx);
352 nfscl_loadfsinfo(nmp, &fs);
353 mtx_unlock(&nmp->nm_mtx);
359 * Mount a remote root fs via. nfs. This depends on the info in the
360 * nfs_diskless structure that has been filled in properly by some primary
362 * It goes something like this:
363 * - do enough of "ifconfig" by calling ifioctl() so that the system
364 * can talk to the server
365 * - If nfs_diskless.mygateway is filled in, use that address as
367 * - build the rootfs mount point and call mountnfs() to do the rest.
369 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
370 * structure, as well as other global NFS client variables here, as
371 * nfs_mountroot() will be called once in the boot before any other NFS
372 * client activity occurs.
375 nfs_mountroot(struct mount *mp)
377 struct thread *td = curthread;
378 struct nfsv3_diskless *nd = &nfsv3_diskless;
387 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
388 bootpc_init(); /* use bootp to get nfs_diskless filled in */
389 #elif defined(NFS_ROOT)
390 nfs_setup_diskless();
393 if (nfs_diskless_valid == 0)
395 if (nfs_diskless_valid == 1)
396 nfs_convert_diskless();
399 * XXX splnet, so networks will receive...
404 * Do enough of ifconfig(8) so that the critical net interface can
405 * talk to the server.
407 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
410 panic("nfs_mountroot: socreate(%04x): %d",
411 nd->myif.ifra_addr.sa_family, error);
413 #if 0 /* XXX Bad idea */
415 * We might not have been told the right interface, so we pass
416 * over the first ten interfaces of the same kind, until we get
417 * one of them configured.
420 for (i = strlen(nd->myif.ifra_name) - 1;
421 nd->myif.ifra_name[i] >= '0' &&
422 nd->myif.ifra_name[i] <= '9';
423 nd->myif.ifra_name[i] ++) {
424 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
429 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
431 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
432 if ((cp = getenv("boot.netif.mtu")) != NULL) {
433 ir.ifr_mtu = strtol(cp, NULL, 10);
434 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
436 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
438 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
443 * If the gateway field is filled in, set it as the default route.
444 * Note that pxeboot will set a default route of 0 if the route
445 * is not set by the DHCP server. Check also for a value of 0
446 * to avoid panicking inappropriately in that situation.
448 if (nd->mygateway.sin_len != 0 &&
449 nd->mygateway.sin_addr.s_addr != 0) {
450 struct sockaddr_in mask, sin;
452 bzero((caddr_t)&mask, sizeof(mask));
454 sin.sin_family = AF_INET;
455 sin.sin_len = sizeof(sin);
456 /* XXX MRT use table 0 for this sort of thing */
457 CURVNET_SET(TD_TO_VNET(td));
458 error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
459 (struct sockaddr *)&nd->mygateway,
460 (struct sockaddr *)&mask,
461 RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
464 panic("nfs_mountroot: RTM_ADD: %d", error);
468 * Create the rootfs mount point.
470 nd->root_args.fh = nd->root_fh;
471 nd->root_args.fhsize = nd->root_fhsize;
472 l = ntohl(nd->root_saddr.sin_addr.s_addr);
473 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
474 (l >> 24) & 0xff, (l >> 16) & 0xff,
475 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
476 printf("NFS ROOT: %s\n", buf);
477 nd->root_args.hostname = buf;
478 if ((error = nfs_mountdiskless(buf,
479 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
484 * This is not really an nfs issue, but it is much easier to
485 * set hostname here and then let the "/etc/rc.xxx" files
486 * mount the right /var based upon its preset value.
488 mtx_lock(&prison0.pr_mtx);
489 strlcpy(prison0.pr_hostname, nd->my_hostnam,
490 sizeof(prison0.pr_hostname));
491 mtx_unlock(&prison0.pr_mtx);
492 inittodr(ntohl(nd->root_time));
497 * Internal version of mount system call for diskless setup.
500 nfs_mountdiskless(char *path,
501 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
502 struct vnode **vpp, struct mount *mp)
504 struct sockaddr *nam;
509 * Find the directory path in "path", which also has the server's
510 * name/ip address in it.
512 dirpath = strchr(path, ':');
514 dirlen = strlen(++dirpath);
517 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
518 if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
519 NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
520 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
527 nfs_sec_name(char *sec, int *flagsp)
529 if (!strcmp(sec, "krb5"))
530 *flagsp |= NFSMNT_KERB;
531 else if (!strcmp(sec, "krb5i"))
532 *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
533 else if (!strcmp(sec, "krb5p"))
534 *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
538 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
539 const char *hostname, struct ucred *cred, struct thread *td)
548 * Set read-only flag if requested; otherwise, clear it if this is
549 * an update. If this is not an update, then either the read-only
550 * flag is already clear, or this is a root mount and it was set
551 * intentionally at some previous point.
553 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
555 mp->mnt_flag |= MNT_RDONLY;
557 } else if (mp->mnt_flag & MNT_UPDATE) {
559 mp->mnt_flag &= ~MNT_RDONLY;
564 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
565 * no sense in that context. Also, set up appropriate retransmit
566 * and soft timeout behavior.
568 if (argp->sotype == SOCK_STREAM) {
569 nmp->nm_flag &= ~NFSMNT_NOCONN;
570 nmp->nm_timeo = NFS_MAXTIMEO;
571 if ((argp->flags & NFSMNT_NFSV4) != 0)
572 nmp->nm_retry = INT_MAX;
574 nmp->nm_retry = NFS_RETRANS_TCP;
577 /* Also clear RDIRPLUS if NFSv2, it crashes some servers */
578 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
579 argp->flags &= ~NFSMNT_RDIRPLUS;
580 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
583 /* Clear NFSMNT_RESVPORT for NFSv4, since it is not required. */
584 if ((argp->flags & NFSMNT_NFSV4) != 0) {
585 argp->flags &= ~NFSMNT_RESVPORT;
586 nmp->nm_flag &= ~NFSMNT_RESVPORT;
589 /* Re-bind if rsrvd port requested and wasn't on one */
590 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
591 && (argp->flags & NFSMNT_RESVPORT);
592 /* Also re-bind if we're switching to/from a connected UDP socket */
593 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
594 (argp->flags & NFSMNT_NOCONN));
596 /* Update flags atomically. Don't change the lock bits. */
597 nmp->nm_flag = argp->flags | nmp->nm_flag;
600 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
601 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
602 if (nmp->nm_timeo < NFS_MINTIMEO)
603 nmp->nm_timeo = NFS_MINTIMEO;
604 else if (nmp->nm_timeo > NFS_MAXTIMEO)
605 nmp->nm_timeo = NFS_MAXTIMEO;
608 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
609 nmp->nm_retry = argp->retrans;
610 if (nmp->nm_retry > NFS_MAXREXMIT)
611 nmp->nm_retry = NFS_MAXREXMIT;
614 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
615 nmp->nm_wsize = argp->wsize;
616 /* Round down to multiple of blocksize */
617 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
618 if (nmp->nm_wsize <= 0)
619 nmp->nm_wsize = NFS_FABLKSIZE;
622 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
623 nmp->nm_rsize = argp->rsize;
624 /* Round down to multiple of blocksize */
625 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
626 if (nmp->nm_rsize <= 0)
627 nmp->nm_rsize = NFS_FABLKSIZE;
630 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
631 nmp->nm_readdirsize = argp->readdirsize;
634 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
635 nmp->nm_acregmin = argp->acregmin;
637 nmp->nm_acregmin = NFS_MINATTRTIMO;
638 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
639 nmp->nm_acregmax = argp->acregmax;
641 nmp->nm_acregmax = NFS_MAXATTRTIMO;
642 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
643 nmp->nm_acdirmin = argp->acdirmin;
645 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
646 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
647 nmp->nm_acdirmax = argp->acdirmax;
649 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
650 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
651 nmp->nm_acdirmin = nmp->nm_acdirmax;
652 if (nmp->nm_acregmin > nmp->nm_acregmax)
653 nmp->nm_acregmin = nmp->nm_acregmax;
655 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
656 if (argp->readahead <= NFS_MAXRAHEAD)
657 nmp->nm_readahead = argp->readahead;
659 nmp->nm_readahead = NFS_MAXRAHEAD;
661 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
662 if (argp->wcommitsize < nmp->nm_wsize)
663 nmp->nm_wcommitsize = nmp->nm_wsize;
665 nmp->nm_wcommitsize = argp->wcommitsize;
668 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
669 (nmp->nm_soproto != argp->proto));
671 if (nmp->nm_client != NULL && adjsock) {
672 int haslock = 0, error = 0;
674 if (nmp->nm_sotype == SOCK_STREAM) {
675 error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
680 newnfs_disconnect(&nmp->nm_sockreq);
682 newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
683 nmp->nm_sotype = argp->sotype;
684 nmp->nm_soproto = argp->proto;
685 if (nmp->nm_sotype == SOCK_DGRAM)
686 while (newnfs_connect(nmp, &nmp->nm_sockreq,
688 printf("newnfs_args: retrying connect\n");
689 (void) nfs_catnap(PSOCK, 0, "newnfscon");
693 nmp->nm_sotype = argp->sotype;
694 nmp->nm_soproto = argp->proto;
697 if (hostname != NULL) {
698 strlcpy(nmp->nm_hostname, hostname,
699 sizeof(nmp->nm_hostname));
700 p = strchr(nmp->nm_hostname, ':');
706 static const char *nfs_opts[] = { "from", "nfs_args",
707 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
708 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
709 "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
710 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
711 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport",
712 "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
713 "principal", "nfsv4", "gssname", "allgssname", "dirpath",
714 "negnametimeo", "nocto", "wcommitsize",
721 * It seems a bit dumb to copyinstr() the host and path here and then
722 * bcopy() them in mountnfs(), but I wanted to detect errors before
723 * doing the sockargs() call because sockargs() allocates an mbuf and
724 * an error after that means that I have to release the mbuf.
728 nfs_mount(struct mount *mp)
730 struct nfs_args args = {
731 .version = NFS_ARGSVERSION,
733 .addrlen = sizeof (struct sockaddr_in),
734 .sotype = SOCK_STREAM,
738 .flags = NFSMNT_RESVPORT,
741 .readdirsize = NFS_READDIRSIZE,
743 .retrans = NFS_RETRANS,
744 .readahead = NFS_DEFRAHEAD,
745 .wcommitsize = 0, /* was: NQ_DEFLEASE */
747 .acregmin = NFS_MINATTRTIMO,
748 .acregmax = NFS_MAXATTRTIMO,
749 .acdirmin = NFS_MINDIRATTRTIMO,
750 .acdirmax = NFS_MAXDIRATTRTIMO,
752 int error = 0, ret, len;
753 struct sockaddr *nam = NULL;
757 u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
758 char *opt, *name, *secname;
759 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
760 int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen;
763 has_nfs_args_opt = 0;
764 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
770 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
771 error = nfs_mountroot(mp);
778 * The old mount_nfs program passed the struct nfs_args
779 * from userspace to kernel. The new mount_nfs program
780 * passes string options via nmount() from userspace to kernel
781 * and we populate the struct nfs_args in the kernel.
783 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
784 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
789 if (args.version != NFS_ARGSVERSION) {
790 error = EPROGMISMATCH;
793 has_nfs_args_opt = 1;
796 /* Handle the new style options. */
797 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
798 args.flags |= NFSMNT_NOCONN;
799 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
800 args.flags |= NFSMNT_NOCONN;
801 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
802 args.flags |= NFSMNT_NOLOCKD;
803 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
804 args.flags &= ~NFSMNT_NOLOCKD;
805 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
806 args.flags |= NFSMNT_INT;
807 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
808 args.flags |= NFSMNT_RDIRPLUS;
809 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
810 args.flags |= NFSMNT_RESVPORT;
811 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
812 args.flags &= ~NFSMNT_RESVPORT;
813 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
814 args.flags |= NFSMNT_SOFT;
815 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
816 args.flags &= ~NFSMNT_SOFT;
817 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
818 args.sotype = SOCK_DGRAM;
819 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
820 args.sotype = SOCK_DGRAM;
821 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
822 args.sotype = SOCK_STREAM;
823 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
824 args.flags |= NFSMNT_NFSV3;
825 if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
826 args.flags |= NFSMNT_NFSV4;
827 args.sotype = SOCK_STREAM;
829 if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
830 args.flags |= NFSMNT_ALLGSSNAME;
831 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
832 args.flags |= NFSMNT_NOCTO;
833 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
835 vfs_mount_error(mp, "illegal readdirsize");
839 ret = sscanf(opt, "%d", &args.readdirsize);
840 if (ret != 1 || args.readdirsize <= 0) {
841 vfs_mount_error(mp, "illegal readdirsize: %s",
846 args.flags |= NFSMNT_READDIRSIZE;
848 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
850 vfs_mount_error(mp, "illegal readahead");
854 ret = sscanf(opt, "%d", &args.readahead);
855 if (ret != 1 || args.readahead <= 0) {
856 vfs_mount_error(mp, "illegal readahead: %s",
861 args.flags |= NFSMNT_READAHEAD;
863 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
865 vfs_mount_error(mp, "illegal wsize");
869 ret = sscanf(opt, "%d", &args.wsize);
870 if (ret != 1 || args.wsize <= 0) {
871 vfs_mount_error(mp, "illegal wsize: %s",
876 args.flags |= NFSMNT_WSIZE;
878 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
880 vfs_mount_error(mp, "illegal rsize");
884 ret = sscanf(opt, "%d", &args.rsize);
885 if (ret != 1 || args.rsize <= 0) {
886 vfs_mount_error(mp, "illegal wsize: %s",
891 args.flags |= NFSMNT_RSIZE;
893 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
895 vfs_mount_error(mp, "illegal retrans");
899 ret = sscanf(opt, "%d", &args.retrans);
900 if (ret != 1 || args.retrans <= 0) {
901 vfs_mount_error(mp, "illegal retrans: %s",
906 args.flags |= NFSMNT_RETRANS;
908 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
909 ret = sscanf(opt, "%d", &args.acregmin);
910 if (ret != 1 || args.acregmin < 0) {
911 vfs_mount_error(mp, "illegal acregmin: %s",
916 args.flags |= NFSMNT_ACREGMIN;
918 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
919 ret = sscanf(opt, "%d", &args.acregmax);
920 if (ret != 1 || args.acregmax < 0) {
921 vfs_mount_error(mp, "illegal acregmax: %s",
926 args.flags |= NFSMNT_ACREGMAX;
928 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
929 ret = sscanf(opt, "%d", &args.acdirmin);
930 if (ret != 1 || args.acdirmin < 0) {
931 vfs_mount_error(mp, "illegal acdirmin: %s",
936 args.flags |= NFSMNT_ACDIRMIN;
938 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
939 ret = sscanf(opt, "%d", &args.acdirmax);
940 if (ret != 1 || args.acdirmax < 0) {
941 vfs_mount_error(mp, "illegal acdirmax: %s",
946 args.flags |= NFSMNT_ACDIRMAX;
948 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
949 ret = sscanf(opt, "%d", &args.wcommitsize);
950 if (ret != 1 || args.wcommitsize < 0) {
951 vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
955 args.flags |= NFSMNT_WCOMMITSIZE;
957 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
958 ret = sscanf(opt, "%d", &args.timeo);
959 if (ret != 1 || args.timeo <= 0) {
960 vfs_mount_error(mp, "illegal timeout: %s",
965 args.flags |= NFSMNT_TIMEO;
967 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
969 ret = sscanf(opt, "%d", &negnametimeo);
970 if (ret != 1 || negnametimeo < 0) {
971 vfs_mount_error(mp, "illegal negnametimeo: %s",
977 if (vfs_getopt(mp->mnt_optnew, "sec",
978 (void **) &secname, NULL) == 0)
979 nfs_sec_name(secname, &args.flags);
981 if (mp->mnt_flag & MNT_UPDATE) {
982 struct nfsmount *nmp = VFSTONFS(mp);
990 * If a change from TCP->UDP is done and there are thread(s)
991 * that have I/O RPC(s) in progress with a tranfer size
992 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
993 * hung, retrying the RPC(s) forever. Usually these threads
994 * will be seen doing an uninterruptible sleep on wait channel
995 * "newnfsreq" (truncated to "newnfsre" by procstat).
997 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
998 tprintf(td->td_proc, LOG_WARNING,
999 "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1002 * When doing an update, we can't change version,
1003 * security, switch lockd strategies or change cookie
1006 args.flags = (args.flags &
1012 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1019 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1020 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1025 * Make the nfs_ip_paranoia sysctl serve as the default connection
1026 * or no-connection mode for those protocols that support
1027 * no-connection mode (the flag will be cleared later for protocols
1028 * that do not support no-connection mode). This will allow a client
1029 * to receive replies from a different IP then the request was
1030 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1033 if (nfs_ip_paranoia == 0)
1034 args.flags |= NFSMNT_NOCONN;
1036 if (has_nfs_args_opt != 0) {
1038 * In the 'nfs_args' case, the pointers in the args
1039 * structure are in userland - we copy them in here.
1041 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1042 vfs_mount_error(mp, "Bad file handle");
1046 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1050 error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1053 bzero(&hst[hstlen], MNAMELEN - hstlen);
1054 args.hostname = hst;
1055 /* sockargs() call must be after above copyin() calls */
1056 error = getsockaddr(&nam, (caddr_t)args.addr,
1061 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1062 &args.fhsize) == 0) {
1063 if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1064 vfs_mount_error(mp, "Bad file handle");
1068 bcopy(args.fh, nfh, args.fhsize);
1072 (void) vfs_getopt(mp->mnt_optnew, "hostname",
1073 (void **)&args.hostname, &len);
1074 if (args.hostname == NULL) {
1075 vfs_mount_error(mp, "Invalid hostname");
1079 bcopy(args.hostname, hst, MNAMELEN);
1080 hst[MNAMELEN - 1] = '\0';
1083 if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1084 strlcpy(srvkrbname, name, sizeof (srvkrbname));
1086 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1087 srvkrbnamelen = strlen(srvkrbname);
1089 if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1090 strlcpy(krbname, name, sizeof (krbname));
1093 krbnamelen = strlen(krbname);
1095 if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0)
1096 strlcpy(dirpath, name, sizeof (dirpath));
1099 dirlen = strlen(dirpath);
1101 if (has_nfs_args_opt == 0) {
1102 if (vfs_getopt(mp->mnt_optnew, "addr",
1103 (void **)&args.addr, &args.addrlen) == 0) {
1104 if (args.addrlen > SOCK_MAXADDRLEN) {
1105 error = ENAMETOOLONG;
1108 nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1109 bcopy(args.addr, nam, args.addrlen);
1110 nam->sa_len = args.addrlen;
1112 vfs_mount_error(mp, "No server address");
1119 error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1120 dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1125 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1136 * It seems a bit dumb to copyinstr() the host and path here and then
1137 * bcopy() them in mountnfs(), but I wanted to detect errors before
1138 * doing the sockargs() call because sockargs() allocates an mbuf and
1139 * an error after that means that I have to release the mbuf.
1143 nfs_cmount(struct mntarg *ma, void *data, int flags)
1146 struct nfs_args args;
1148 error = copyin(data, &args, sizeof (struct nfs_args));
1152 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1154 error = kernel_mount(ma, flags);
1159 * Common code for mount and mountroot
1162 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1163 char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1164 u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1165 struct ucred *cred, struct thread *td, int negnametimeo)
1167 struct nfsmount *nmp;
1169 int error, trycnt, ret;
1170 struct nfsvattr nfsva;
1171 static u_int64_t clval = 0;
1173 if (mp->mnt_flag & MNT_UPDATE) {
1175 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1176 FREE(nam, M_SONAME);
1179 MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) +
1180 krbnamelen + dirlen + srvkrbnamelen + 2,
1181 M_NEWNFSMNT, M_WAITOK | M_ZERO);
1182 TAILQ_INIT(&nmp->nm_bufq);
1184 clval = (u_int64_t)nfsboottime.tv_sec;
1185 nmp->nm_clval = clval++;
1186 nmp->nm_krbnamelen = krbnamelen;
1187 nmp->nm_dirpathlen = dirlen;
1188 nmp->nm_srvkrbnamelen = srvkrbnamelen;
1189 if (td->td_ucred->cr_uid != (uid_t)0) {
1191 * nm_uid is used to get KerberosV credentials for
1192 * the nfsv4 state handling operations if there is
1193 * no host based principal set. Use the uid of
1194 * this user if not root, since they are doing the
1195 * mount. I don't think setting this for root will
1196 * work, since root normally does not have user
1197 * credentials in a credentials cache.
1199 nmp->nm_uid = td->td_ucred->cr_uid;
1202 * Just set to -1, so it won't be used.
1204 nmp->nm_uid = (uid_t)-1;
1207 /* Copy and null terminate all the names */
1208 if (nmp->nm_krbnamelen > 0) {
1209 bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1210 nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1212 if (nmp->nm_dirpathlen > 0) {
1213 bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1214 nmp->nm_dirpathlen);
1215 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1218 if (nmp->nm_srvkrbnamelen > 0) {
1219 bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1220 nmp->nm_srvkrbnamelen);
1221 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1222 + nmp->nm_srvkrbnamelen + 2] = '\0';
1224 nmp->nm_sockreq.nr_cred = crhold(cred);
1225 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1227 nmp->nm_getinfo = nfs_getnlminfo;
1228 nmp->nm_vinvalbuf = ncl_vinvalbuf;
1231 nmp->nm_mountp = mp;
1232 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1235 * Since nfs_decode_args() might optionally set them, these need to
1236 * set to defaults before the call, so that the optional settings
1237 * aren't overwritten.
1239 nmp->nm_negnametimeo = negnametimeo;
1240 nmp->nm_timeo = NFS_TIMEO;
1241 nmp->nm_retry = NFS_RETRANS;
1242 nmp->nm_readahead = NFS_DEFRAHEAD;
1243 if (desiredvnodes >= 11000)
1244 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1246 nmp->nm_wcommitsize = hibufspace / 10;
1248 nfs_decode_args(mp, nmp, argp, hst, cred, td);
1251 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1252 * high, depending on whether we end up with negative offsets in
1253 * the client or server somewhere. 2GB-1 may be safer.
1255 * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum
1256 * that we can handle until we find out otherwise.
1257 * XXX Our "safe" limit on the client is what we can store in our
1258 * buffer cache using signed(!) block numbers.
1260 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1261 nmp->nm_maxfilesize = 0xffffffffLL;
1263 nmp->nm_maxfilesize = OFF_MAX;
1265 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1266 nmp->nm_wsize = NFS_WSIZE;
1267 nmp->nm_rsize = NFS_RSIZE;
1268 nmp->nm_readdirsize = NFS_READDIRSIZE;
1270 nmp->nm_numgrps = NFS_MAXGRPS;
1271 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1272 if (nmp->nm_tprintf_delay < 0)
1273 nmp->nm_tprintf_delay = 0;
1274 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1275 if (nmp->nm_tprintf_initial_delay < 0)
1276 nmp->nm_tprintf_initial_delay = 0;
1277 nmp->nm_fhsize = argp->fhsize;
1278 if (nmp->nm_fhsize > 0)
1279 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1280 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1282 /* Set up the sockets and per-host congestion */
1283 nmp->nm_sotype = argp->sotype;
1284 nmp->nm_soproto = argp->proto;
1285 nmp->nm_sockreq.nr_prog = NFS_PROG;
1286 if ((argp->flags & NFSMNT_NFSV4))
1287 nmp->nm_sockreq.nr_vers = NFS_VER4;
1288 else if ((argp->flags & NFSMNT_NFSV3))
1289 nmp->nm_sockreq.nr_vers = NFS_VER3;
1291 nmp->nm_sockreq.nr_vers = NFS_VER2;
1294 if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
1298 * A reference count is needed on the nfsnode representing the
1299 * remote root. If this object is not persistent, then backward
1300 * traversals of the mount point (i.e. "..") will not work if
1301 * the nfsnode gets flushed out of the cache. Ufs does not have
1302 * this problem, because one can identify root inodes by their
1303 * number == ROOTINO (2).
1305 if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1306 nmp->nm_dirpathlen > 0) {
1308 * If the fhsize on the mount point == 0 for V4, the mount
1309 * path needs to be looked up.
1313 error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1316 (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1317 } while (error && --trycnt > 0);
1319 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
1323 if (nmp->nm_fhsize > 0) {
1325 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1326 * non-zero for the root vnode. f_iosize will be set correctly
1327 * by nfs_statfs() before any I/O occurs.
1329 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1330 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1337 * Get file attributes and transfer parameters for the
1338 * mountpoint. This has the side effect of filling in
1339 * (*vpp)->v_type with the correct value.
1341 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1342 cred, td, &nfsva, NULL);
1345 * Just set default values to get things going.
1347 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1348 nfsva.na_vattr.va_type = VDIR;
1349 nfsva.na_vattr.va_mode = 0777;
1350 nfsva.na_vattr.va_nlink = 100;
1351 nfsva.na_vattr.va_uid = (uid_t)0;
1352 nfsva.na_vattr.va_gid = (gid_t)0;
1353 nfsva.na_vattr.va_fileid = 2;
1354 nfsva.na_vattr.va_gen = 1;
1355 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1356 nfsva.na_vattr.va_size = 512 * 1024;
1358 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1359 if (argp->flags & NFSMNT_NFSV3)
1360 ncl_fsinfo(nmp, *vpp, cred, td);
1362 /* Mark if the mount point supports NFSv4 ACLs. */
1363 if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1365 NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1367 mp->mnt_flag |= MNT_NFS4ACLS;
1372 * Lose the lock but keep the ref.
1374 NFSVOPUNLOCK(*vpp, 0);
1380 newnfs_disconnect(&nmp->nm_sockreq);
1381 crfree(nmp->nm_sockreq.nr_cred);
1382 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1383 mtx_destroy(&nmp->nm_mtx);
1384 FREE(nmp, M_NEWNFSMNT);
1385 FREE(nam, M_SONAME);
1390 * unmount system call
1393 nfs_unmount(struct mount *mp, int mntflags)
1396 struct nfsmount *nmp;
1397 int error, flags = 0, trycnt = 0;
1401 if (mntflags & MNT_FORCE)
1402 flags |= FORCECLOSE;
1405 * Goes something like this..
1406 * - Call vflush() to clear out vnodes for this filesystem
1407 * - Close the socket
1408 * - Free up the data structures
1410 /* In the forced case, cancel any outstanding requests. */
1411 if (mntflags & MNT_FORCE) {
1412 error = newnfs_nmcancelreqs(nmp);
1415 /* For a forced close, get rid of the renew thread now */
1416 nfscl_umount(nmp, td);
1418 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1420 error = vflush(mp, 1, flags, td);
1421 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1422 (void) nfs_catnap(PSOCK, error, "newndm");
1423 } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1428 * We are now committed to the unmount.
1430 if ((mntflags & MNT_FORCE) == 0)
1431 nfscl_umount(nmp, td);
1432 newnfs_disconnect(&nmp->nm_sockreq);
1433 crfree(nmp->nm_sockreq.nr_cred);
1434 FREE(nmp->nm_nam, M_SONAME);
1436 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1437 mtx_destroy(&nmp->nm_mtx);
1438 FREE(nmp, M_NEWNFSMNT);
1444 * Return root of a filesystem
1447 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1450 struct nfsmount *nmp;
1455 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1460 * Get transfer parameters and attributes for root vnode once.
1462 mtx_lock(&nmp->nm_mtx);
1463 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1464 mtx_unlock(&nmp->nm_mtx);
1465 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1467 mtx_unlock(&nmp->nm_mtx);
1468 if (vp->v_type == VNON)
1470 vp->v_vflag |= VV_ROOT;
1476 * Flush out the buffer cache
1480 nfs_sync(struct mount *mp, int waitfor)
1482 struct vnode *vp, *mvp;
1484 int error, allerror = 0;
1490 * If a forced dismount is in progress, return from here so that
1491 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1492 * calling VFS_UNMOUNT().
1494 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1500 * Force stale buffer cache information to be flushed.
1503 MNT_VNODE_FOREACH(vp, mp, mvp) {
1506 /* XXX Racy bv_cnt check. */
1507 if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1508 waitfor == MNT_LAZY) {
1513 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1515 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1518 error = VOP_FSYNC(vp, waitfor, td);
1521 NFSVOPUNLOCK(vp, 0);
1531 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1533 struct nfsmount *nmp = VFSTONFS(mp);
1537 bzero(&vq, sizeof(vq));
1540 case VFS_CTL_NOLOCKS:
1541 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1542 if (req->oldptr != NULL) {
1543 error = SYSCTL_OUT(req, &val, sizeof(val));
1547 if (req->newptr != NULL) {
1548 error = SYSCTL_IN(req, &val, sizeof(val));
1552 nmp->nm_flag |= NFSMNT_NOLOCKS;
1554 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1559 mtx_lock(&nmp->nm_mtx);
1560 if (nmp->nm_state & NFSSTA_TIMEO)
1561 vq.vq_flags |= VQ_NOTRESP;
1562 mtx_unlock(&nmp->nm_mtx);
1564 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1565 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1566 vq.vq_flags |= VQ_NOTRESPLOCK;
1568 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1571 if (req->oldptr != NULL) {
1572 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1573 sizeof(nmp->nm_tprintf_initial_delay));
1577 if (req->newptr != NULL) {
1578 error = vfs_suser(mp, req->td);
1581 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1582 sizeof(nmp->nm_tprintf_initial_delay));
1585 if (nmp->nm_tprintf_initial_delay < 0)
1586 nmp->nm_tprintf_initial_delay = 0;
1596 * Extract the information needed by the nlm from the nfs vnode.
1599 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1600 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1601 struct timeval *timeop)
1603 struct nfsmount *nmp;
1604 struct nfsnode *np = VTONFS(vp);
1606 nmp = VFSTONFS(vp->v_mount);
1608 *fhlenp = (size_t)np->n_fhp->nfh_len;
1610 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1612 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1614 *is_v3p = NFS_ISV3(vp);
1616 *sizep = np->n_size;
1617 if (timeop != NULL) {
1618 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1619 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);