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 * @(#)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>
48 #include <sys/limits.h>
50 #include <sys/malloc.h>
52 #include <sys/module.h>
53 #include <sys/mount.h>
55 #include <sys/socket.h>
56 #include <sys/socketvar.h>
57 #include <sys/sockio.h>
58 #include <sys/sysctl.h>
59 #include <sys/syslog.h>
60 #include <sys/vnode.h>
61 #include <sys/signalvar.h>
64 #include <vm/vm_extern.h>
68 #include <net/route.h>
71 #include <netinet/in.h>
75 #include <nfs/nfsproto.h>
76 #include <nfsclient/nfs.h>
77 #include <nfsclient/nfsnode.h>
78 #include <nfsclient/nfsmount.h>
79 #include <nfs/xdr_subs.h>
80 #include <nfsclient/nfsm_subs.h>
81 #include <nfs/nfsdiskless.h>
83 MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
84 MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
85 MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
86 MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
87 MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
89 uma_zone_t nfsmount_zone;
91 struct nfsstats nfsstats;
93 SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem");
94 SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
95 &nfsstats, nfsstats, "S,nfsstats");
96 static int nfs_ip_paranoia = 1;
97 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
99 "Disallow accepting replies from IPs which differ from those sent");
102 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
103 "Toggle debug flag");
105 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
106 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
107 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0,
108 "Delay before printing \"nfs server not responding\" messages");
109 /* how long between console messages "nfs server foo not responding" */
110 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
111 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
112 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0,
113 "Delay between printing \"nfs server not responding\" messages");
115 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
116 struct nfs_args *argp, const char *hostname);
117 static int mountnfs(struct nfs_args *, struct mount *,
118 struct sockaddr *, char *, struct vnode **,
119 struct ucred *cred, int, int);
120 static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
121 struct sockaddr_storage *, int *, off_t *,
123 static vfs_mount_t nfs_mount;
124 static vfs_cmount_t nfs_cmount;
125 static vfs_unmount_t nfs_unmount;
126 static vfs_root_t nfs_root;
127 static vfs_statfs_t nfs_statfs;
128 static vfs_sync_t nfs_sync;
129 static vfs_sysctl_t nfs_sysctl;
131 static int fake_wchan;
134 * nfs vfs operations.
136 static struct vfsops nfs_vfsops = {
137 .vfs_init = nfs_init,
138 .vfs_mount = nfs_mount,
139 .vfs_cmount = nfs_cmount,
140 .vfs_root = nfs_root,
141 .vfs_statfs = nfs_statfs,
142 .vfs_sync = nfs_sync,
143 .vfs_uninit = nfs_uninit,
144 .vfs_unmount = nfs_unmount,
145 .vfs_sysctl = nfs_sysctl,
147 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY);
149 /* So that loader and kldload(2) can find us, wherever we are.. */
150 MODULE_VERSION(nfs, 1);
151 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
153 MODULE_DEPEND(nfs, kgssapi, 1, 1, 1);
155 MODULE_DEPEND(nfs, nfs_common, 1, 1, 1);
156 MODULE_DEPEND(nfs, nfslock, 1, 1, 1);
158 static struct nfs_rpcops nfs_rpcops = {
168 * This structure is now defined in sys/nfs/nfs_diskless.c so that it
169 * can be shared by both NFS clients. It is declared here so that it
170 * will be defined for kernels built without NFS_ROOT, although it
171 * isn't used in that case.
174 struct nfs_diskless nfs_diskless = { { { 0 } } };
175 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
176 int nfs_diskless_valid = 0;
179 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
180 &nfs_diskless_valid, 0,
181 "Has the diskless struct been filled correctly");
183 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
184 nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
186 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
187 &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
188 "%Ssockaddr_in", "Diskless root nfs address");
191 void nfsargs_ntoh(struct nfs_args *);
192 static int nfs_mountdiskless(char *,
193 struct sockaddr_in *, struct nfs_args *,
194 struct thread *, struct vnode **, struct mount *);
195 static void nfs_convert_diskless(void);
196 static void nfs_convert_oargs(struct nfs_args *args,
197 struct onfs_args *oargs);
200 nfs_iosize(struct nfsmount *nmp)
205 * Calculate the size used for io buffers. Use the larger
206 * of the two sizes to minimise nfs requests but make sure
207 * that it is at least one VM page to avoid wasting buffer
210 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
211 iosize = imax(iosize, PAGE_SIZE);
216 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
219 args->version = NFS_ARGSVERSION;
220 args->addr = oargs->addr;
221 args->addrlen = oargs->addrlen;
222 args->sotype = oargs->sotype;
223 args->proto = oargs->proto;
224 args->fh = oargs->fh;
225 args->fhsize = oargs->fhsize;
226 args->flags = oargs->flags;
227 args->wsize = oargs->wsize;
228 args->rsize = oargs->rsize;
229 args->readdirsize = oargs->readdirsize;
230 args->timeo = oargs->timeo;
231 args->retrans = oargs->retrans;
232 args->maxgrouplist = oargs->maxgrouplist;
233 args->readahead = oargs->readahead;
234 args->deadthresh = oargs->deadthresh;
235 args->hostname = oargs->hostname;
239 nfs_convert_diskless(void)
242 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
243 sizeof(struct ifaliasreq));
244 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
245 sizeof(struct sockaddr_in));
246 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
247 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
248 nfsv3_diskless.root_fhsize = NFSX_V3FH;
249 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
251 nfsv3_diskless.root_fhsize = NFSX_V2FH;
252 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
254 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
255 sizeof(struct sockaddr_in));
256 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
257 nfsv3_diskless.root_time = nfs_diskless.root_time;
258 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
260 nfs_diskless_valid = 3;
267 nfs_statfs(struct mount *mp, struct statfs *sbp)
271 struct nfs_statfs *sfp;
273 struct nfsmount *nmp = VFSTONFS(mp);
274 int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
275 struct mbuf *mreq, *mrep, *md, *mb;
283 error = vfs_busy(mp, MBF_NOWAIT);
286 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
292 mtx_lock(&nmp->nm_mtx);
293 if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
294 mtx_unlock(&nmp->nm_mtx);
295 (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
297 mtx_unlock(&nmp->nm_mtx);
298 nfsstats.rpccnt[NFSPROC_FSSTAT]++;
299 mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
301 bpos = mtod(mb, caddr_t);
303 nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
305 nfsm_postop_attr(vp, retattr);
311 sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
312 mtx_lock(&nmp->nm_mtx);
313 sbp->f_iosize = nfs_iosize(nmp);
314 mtx_unlock(&nmp->nm_mtx);
316 sbp->f_bsize = NFS_FABLKSIZE;
317 tquad = fxdr_hyper(&sfp->sf_tbytes);
318 sbp->f_blocks = tquad / NFS_FABLKSIZE;
319 tquad = fxdr_hyper(&sfp->sf_fbytes);
320 sbp->f_bfree = tquad / NFS_FABLKSIZE;
321 tquad = fxdr_hyper(&sfp->sf_abytes);
322 sbp->f_bavail = tquad / NFS_FABLKSIZE;
323 sbp->f_files = (fxdr_unsigned(int32_t,
324 sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
325 sbp->f_ffree = (fxdr_unsigned(int32_t,
326 sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
328 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
329 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
330 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
331 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
343 * nfs version 3 fsinfo rpc call
346 nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
349 struct nfsv3_fsinfo *fsp;
352 int error = 0, retattr;
353 struct mbuf *mreq, *mrep, *md, *mb;
356 nfsstats.rpccnt[NFSPROC_FSINFO]++;
357 mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
359 bpos = mtod(mb, caddr_t);
361 nfsm_request(vp, NFSPROC_FSINFO, td, cred);
362 nfsm_postop_attr(vp, retattr);
364 fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
365 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
366 mtx_lock(&nmp->nm_mtx);
367 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
368 nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
369 ~(NFS_FABLKSIZE - 1);
370 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
371 if (max < nmp->nm_wsize && max > 0) {
372 nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
373 if (nmp->nm_wsize == 0)
376 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
377 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
378 nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
379 ~(NFS_FABLKSIZE - 1);
380 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
381 if (max < nmp->nm_rsize && max > 0) {
382 nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
383 if (nmp->nm_rsize == 0)
386 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
387 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
388 nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
389 ~(NFS_DIRBLKSIZ - 1);
390 if (max < nmp->nm_readdirsize && max > 0) {
391 nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
392 if (nmp->nm_readdirsize == 0)
393 nmp->nm_readdirsize = max;
395 maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
396 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
397 nmp->nm_maxfilesize = maxfsize;
398 nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
399 nmp->nm_state |= NFSSTA_GOTFSINFO;
400 mtx_unlock(&nmp->nm_mtx);
408 * Mount a remote root fs via. nfs. This depends on the info in the
409 * nfs_diskless structure that has been filled in properly by some primary
411 * It goes something like this:
412 * - do enough of "ifconfig" by calling ifioctl() so that the system
413 * can talk to the server
414 * - If nfs_diskless.mygateway is filled in, use that address as
416 * - build the rootfs mount point and call mountnfs() to do the rest.
418 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
419 * structure, as well as other global NFS client variables here, as
420 * nfs_mountroot() will be called once in the boot before any other NFS
421 * client activity occurs.
424 nfs_mountroot(struct mount *mp)
426 struct thread *td = curthread;
427 struct nfsv3_diskless *nd = &nfsv3_diskless;
437 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
438 bootpc_init(); /* use bootp to get nfs_diskless filled in */
439 #elif defined(NFS_ROOT)
440 nfs_setup_diskless();
443 if (nfs_diskless_valid == 0) {
446 if (nfs_diskless_valid == 1)
447 nfs_convert_diskless();
450 * XXX splnet, so networks will receive...
455 * Do enough of ifconfig(8) so that the critical net interface can
456 * talk to the server.
458 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
461 panic("nfs_mountroot: socreate(%04x): %d",
462 nd->myif.ifra_addr.sa_family, error);
464 #if 0 /* XXX Bad idea */
466 * We might not have been told the right interface, so we pass
467 * over the first ten interfaces of the same kind, until we get
468 * one of them configured.
471 for (i = strlen(nd->myif.ifra_name) - 1;
472 nd->myif.ifra_name[i] >= '0' &&
473 nd->myif.ifra_name[i] <= '9';
474 nd->myif.ifra_name[i] ++) {
475 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
481 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
483 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
485 if ((cp = getenv("boot.netif.mtu")) != NULL) {
486 ir.ifr_mtu = strtol(cp, NULL, 10);
487 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
489 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
491 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
496 * If the gateway field is filled in, set it as the default route.
497 * Note that pxeboot will set a default route of 0 if the route
498 * is not set by the DHCP server. Check also for a value of 0
499 * to avoid panicking inappropriately in that situation.
501 if (nd->mygateway.sin_len != 0 &&
502 nd->mygateway.sin_addr.s_addr != 0) {
503 struct sockaddr_in mask, sin;
505 bzero((caddr_t)&mask, sizeof(mask));
507 sin.sin_family = AF_INET;
508 sin.sin_len = sizeof(sin);
509 /* XXX MRT use table 0 for this sort of thing */
510 CURVNET_SET(TD_TO_VNET(td));
511 error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
512 (struct sockaddr *)&nd->mygateway,
513 (struct sockaddr *)&mask,
514 RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
517 panic("nfs_mountroot: RTM_ADD: %d", error);
521 * Create the rootfs mount point.
523 nd->root_args.fh = nd->root_fh;
524 nd->root_args.fhsize = nd->root_fhsize;
525 l = ntohl(nd->root_saddr.sin_addr.s_addr);
526 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
527 (l >> 24) & 0xff, (l >> 16) & 0xff,
528 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
529 printf("NFS ROOT: %s\n", buf);
530 nd->root_args.hostname = buf;
531 if ((error = nfs_mountdiskless(buf,
532 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
537 * This is not really an nfs issue, but it is much easier to
538 * set hostname here and then let the "/etc/rc.xxx" files
539 * mount the right /var based upon its preset value.
541 mtx_lock(&prison0.pr_mtx);
542 strlcpy(prison0.pr_hostname, nd->my_hostnam,
543 sizeof (prison0.pr_hostname));
544 mtx_unlock(&prison0.pr_mtx);
545 inittodr(ntohl(nd->root_time));
550 * Internal version of mount system call for diskless setup.
553 nfs_mountdiskless(char *path,
554 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
555 struct vnode **vpp, struct mount *mp)
557 struct sockaddr *nam;
560 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
561 if ((error = mountnfs(args, mp, nam, path, vpp, td->td_ucred,
562 NFS_DEFAULT_NAMETIMEO, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
563 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
570 nfs_sec_name_to_num(char *sec)
572 if (!strcmp(sec, "krb5"))
573 return (RPCSEC_GSS_KRB5);
574 if (!strcmp(sec, "krb5i"))
575 return (RPCSEC_GSS_KRB5I);
576 if (!strcmp(sec, "krb5p"))
577 return (RPCSEC_GSS_KRB5P);
578 if (!strcmp(sec, "sys"))
581 * Userland should validate the string but we will try and
582 * cope with unexpected values.
588 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
589 const char *hostname)
601 * Set read-only flag if requested; otherwise, clear it if this is
602 * an update. If this is not an update, then either the read-only
603 * flag is already clear, or this is a root mount and it was set
604 * intentionally at some previous point.
606 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
608 mp->mnt_flag |= MNT_RDONLY;
610 } else if (mp->mnt_flag & MNT_UPDATE) {
612 mp->mnt_flag &= ~MNT_RDONLY;
617 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
618 * no sense in that context. Also, set up appropriate retransmit
619 * and soft timeout behavior.
621 if (argp->sotype == SOCK_STREAM) {
622 nmp->nm_flag &= ~NFSMNT_NOCONN;
623 nmp->nm_flag |= NFSMNT_DUMBTIMR;
624 nmp->nm_timeo = NFS_MAXTIMEO;
625 nmp->nm_retry = NFS_RETRANS_TCP;
628 /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
629 if ((argp->flags & NFSMNT_NFSV3) == 0)
630 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
632 /* Re-bind if rsrvd port requested and wasn't on one */
633 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
634 && (argp->flags & NFSMNT_RESVPORT);
635 /* Also re-bind if we're switching to/from a connected UDP socket */
636 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
637 (argp->flags & NFSMNT_NOCONN));
639 /* Update flags atomically. Don't change the lock bits. */
640 nmp->nm_flag = argp->flags | nmp->nm_flag;
643 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
644 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
645 if (nmp->nm_timeo < NFS_MINTIMEO)
646 nmp->nm_timeo = NFS_MINTIMEO;
647 else if (nmp->nm_timeo > NFS_MAXTIMEO)
648 nmp->nm_timeo = NFS_MAXTIMEO;
651 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
652 nmp->nm_retry = argp->retrans;
653 if (nmp->nm_retry > NFS_MAXREXMIT)
654 nmp->nm_retry = NFS_MAXREXMIT;
657 if (argp->flags & NFSMNT_NFSV3) {
658 if (argp->sotype == SOCK_DGRAM)
659 maxio = NFS_MAXDGRAMDATA;
663 maxio = NFS_V2MAXDATA;
665 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
666 nmp->nm_wsize = argp->wsize;
667 /* Round down to multiple of blocksize */
668 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
669 if (nmp->nm_wsize <= 0)
670 nmp->nm_wsize = NFS_FABLKSIZE;
672 if (nmp->nm_wsize > maxio)
673 nmp->nm_wsize = maxio;
674 if (nmp->nm_wsize > MAXBSIZE)
675 nmp->nm_wsize = MAXBSIZE;
677 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
678 nmp->nm_rsize = argp->rsize;
679 /* Round down to multiple of blocksize */
680 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
681 if (nmp->nm_rsize <= 0)
682 nmp->nm_rsize = NFS_FABLKSIZE;
684 if (nmp->nm_rsize > maxio)
685 nmp->nm_rsize = maxio;
686 if (nmp->nm_rsize > MAXBSIZE)
687 nmp->nm_rsize = MAXBSIZE;
689 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
690 nmp->nm_readdirsize = argp->readdirsize;
692 if (nmp->nm_readdirsize > maxio)
693 nmp->nm_readdirsize = maxio;
694 if (nmp->nm_readdirsize > nmp->nm_rsize)
695 nmp->nm_readdirsize = nmp->nm_rsize;
697 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
698 nmp->nm_acregmin = argp->acregmin;
700 nmp->nm_acregmin = NFS_MINATTRTIMO;
701 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
702 nmp->nm_acregmax = argp->acregmax;
704 nmp->nm_acregmax = NFS_MAXATTRTIMO;
705 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
706 nmp->nm_acdirmin = argp->acdirmin;
708 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
709 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
710 nmp->nm_acdirmax = argp->acdirmax;
712 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
713 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
714 nmp->nm_acdirmin = nmp->nm_acdirmax;
715 if (nmp->nm_acregmin > nmp->nm_acregmax)
716 nmp->nm_acregmin = nmp->nm_acregmax;
718 if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
719 if (argp->maxgrouplist <= NFS_MAXGRPS)
720 nmp->nm_numgrps = argp->maxgrouplist;
722 nmp->nm_numgrps = NFS_MAXGRPS;
724 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
725 if (argp->readahead <= NFS_MAXRAHEAD)
726 nmp->nm_readahead = argp->readahead;
728 nmp->nm_readahead = NFS_MAXRAHEAD;
730 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
731 if (argp->wcommitsize < nmp->nm_wsize)
732 nmp->nm_wcommitsize = nmp->nm_wsize;
734 nmp->nm_wcommitsize = argp->wcommitsize;
736 if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
737 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
738 nmp->nm_deadthresh = argp->deadthresh;
740 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
743 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
744 (nmp->nm_soproto != argp->proto));
745 nmp->nm_sotype = argp->sotype;
746 nmp->nm_soproto = argp->proto;
748 if (nmp->nm_client && adjsock) {
749 nfs_safedisconnect(nmp);
750 if (nmp->nm_sotype == SOCK_DGRAM)
751 while (nfs_connect(nmp)) {
752 printf("nfs_args: retrying connect\n");
753 (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
758 strlcpy(nmp->nm_hostname, hostname,
759 sizeof(nmp->nm_hostname));
760 p = strchr(nmp->nm_hostname, ':');
765 if (vfs_getopt(mp->mnt_optnew, "sec",
766 (void **) &secname, NULL) == 0) {
767 nmp->nm_secflavor = nfs_sec_name_to_num(secname);
769 nmp->nm_secflavor = AUTH_SYS;
772 if (vfs_getopt(mp->mnt_optnew, "principal",
773 (void **) &principal, NULL) == 0) {
774 strlcpy(nmp->nm_principal, principal,
775 sizeof(nmp->nm_principal));
777 snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
778 "nfs@%s", nmp->nm_hostname);
782 static const char *nfs_opts[] = { "from", "nfs_args",
783 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
784 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
785 "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
786 "readahead", "readdirsize", "soft", "hard", "mntudp", "tcp", "udp",
787 "wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin",
788 "acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3",
789 "sec", "maxgroups", "principal", "negnametimeo", "nocto", "wcommitsize",
797 * It seems a bit dumb to copyinstr() the host and path here and then
798 * bcopy() them in mountnfs(), but I wanted to detect errors before
799 * doing the sockargs() call because sockargs() allocates an mbuf and
800 * an error after that means that I have to release the mbuf.
804 nfs_mount(struct mount *mp)
806 struct nfs_args args = {
807 .version = NFS_ARGSVERSION,
809 .addrlen = sizeof (struct sockaddr_in),
810 .sotype = SOCK_STREAM,
814 .flags = NFSMNT_RESVPORT,
817 .readdirsize = NFS_READDIRSIZE,
819 .retrans = NFS_RETRANS,
820 .maxgrouplist = NFS_MAXGRPS,
821 .readahead = NFS_DEFRAHEAD,
822 .wcommitsize = 0, /* was: NQ_DEFLEASE */
823 .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */
826 .acregmin = NFS_MINATTRTIMO,
827 .acregmax = NFS_MAXATTRTIMO,
828 .acdirmin = NFS_MINDIRATTRTIMO,
829 .acdirmax = NFS_MAXDIRATTRTIMO,
831 int error, ret, has_nfs_args_opt;
832 int has_addr_opt, has_fh_opt, has_hostname_opt;
833 struct sockaddr *nam;
837 u_char nfh[NFSX_V3FHMAX];
839 int nametimeo = NFS_DEFAULT_NAMETIMEO;
840 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
842 has_nfs_args_opt = 0;
845 has_hostname_opt = 0;
847 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
852 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
853 error = nfs_mountroot(mp);
858 * The old mount_nfs program passed the struct nfs_args
859 * from userspace to kernel. The new mount_nfs program
860 * passes string options via nmount() from userspace to kernel
861 * and we populate the struct nfs_args in the kernel.
863 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
864 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
869 if (args.version != NFS_ARGSVERSION) {
870 error = EPROGMISMATCH;
873 has_nfs_args_opt = 1;
876 if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
877 args.flags |= NFSMNT_DUMBTIMR;
878 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
879 args.flags |= NFSMNT_NOCONN;
880 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
881 args.flags |= NFSMNT_NOCONN;
882 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
883 args.flags |= NFSMNT_NOLOCKD;
884 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
885 args.flags &= ~NFSMNT_NOLOCKD;
886 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
887 args.flags |= NFSMNT_INT;
888 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
889 args.flags |= NFSMNT_RDIRPLUS;
890 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
891 args.flags |= NFSMNT_RESVPORT;
892 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
893 args.flags &= ~NFSMNT_RESVPORT;
894 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
895 args.flags |= NFSMNT_SOFT;
896 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
897 args.flags &= ~NFSMNT_SOFT;
898 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
899 args.sotype = SOCK_DGRAM;
900 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
901 args.sotype = SOCK_DGRAM;
902 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
903 args.sotype = SOCK_STREAM;
904 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
905 args.flags |= NFSMNT_NFSV3;
906 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
907 args.flags |= NFSMNT_NOCTO;
908 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
910 vfs_mount_error(mp, "illegal readdirsize");
914 ret = sscanf(opt, "%d", &args.readdirsize);
915 if (ret != 1 || args.readdirsize <= 0) {
916 vfs_mount_error(mp, "illegal readdirsize: %s",
921 args.flags |= NFSMNT_READDIRSIZE;
923 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
925 vfs_mount_error(mp, "illegal readahead");
929 ret = sscanf(opt, "%d", &args.readahead);
930 if (ret != 1 || args.readahead <= 0) {
931 vfs_mount_error(mp, "illegal readahead: %s",
936 args.flags |= NFSMNT_READAHEAD;
938 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
940 vfs_mount_error(mp, "illegal wsize");
944 ret = sscanf(opt, "%d", &args.wsize);
945 if (ret != 1 || args.wsize <= 0) {
946 vfs_mount_error(mp, "illegal wsize: %s",
951 args.flags |= NFSMNT_WSIZE;
953 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
955 vfs_mount_error(mp, "illegal rsize");
959 ret = sscanf(opt, "%d", &args.rsize);
960 if (ret != 1 || args.rsize <= 0) {
961 vfs_mount_error(mp, "illegal wsize: %s",
966 args.flags |= NFSMNT_RSIZE;
968 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
970 vfs_mount_error(mp, "illegal retrans");
974 ret = sscanf(opt, "%d", &args.retrans);
975 if (ret != 1 || args.retrans <= 0) {
976 vfs_mount_error(mp, "illegal retrans: %s",
981 args.flags |= NFSMNT_RETRANS;
983 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
984 ret = sscanf(opt, "%d", &args.acregmin);
985 if (ret != 1 || args.acregmin < 0) {
986 vfs_mount_error(mp, "illegal acregmin: %s",
991 args.flags |= NFSMNT_ACREGMIN;
993 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
994 ret = sscanf(opt, "%d", &args.acregmax);
995 if (ret != 1 || args.acregmax < 0) {
996 vfs_mount_error(mp, "illegal acregmax: %s",
1001 args.flags |= NFSMNT_ACREGMAX;
1003 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
1004 ret = sscanf(opt, "%d", &args.acdirmin);
1005 if (ret != 1 || args.acdirmin < 0) {
1006 vfs_mount_error(mp, "illegal acdirmin: %s",
1011 args.flags |= NFSMNT_ACDIRMIN;
1013 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1014 ret = sscanf(opt, "%d", &args.acdirmax);
1015 if (ret != 1 || args.acdirmax < 0) {
1016 vfs_mount_error(mp, "illegal acdirmax: %s",
1021 args.flags |= NFSMNT_ACDIRMAX;
1023 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
1024 ret = sscanf(opt, "%d", &args.wcommitsize);
1025 if (ret != 1 || args.wcommitsize < 0) {
1026 vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
1030 args.flags |= NFSMNT_WCOMMITSIZE;
1032 if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1033 ret = sscanf(opt, "%d", &args.deadthresh);
1034 if (ret != 1 || args.deadthresh <= 0) {
1035 vfs_mount_error(mp, "illegal deadthresh: %s",
1040 args.flags |= NFSMNT_DEADTHRESH;
1042 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1043 ret = sscanf(opt, "%d", &args.timeo);
1044 if (ret != 1 || args.timeo <= 0) {
1045 vfs_mount_error(mp, "illegal timeout: %s",
1050 args.flags |= NFSMNT_TIMEO;
1052 if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1053 ret = sscanf(opt, "%d", &args.maxgrouplist);
1054 if (ret != 1 || args.maxgrouplist <= 0) {
1055 vfs_mount_error(mp, "illegal maxgroups: %s",
1060 args.flags |= NFSMNT_MAXGRPS;
1062 if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
1063 ret = sscanf(opt, "%d", &nametimeo);
1064 if (ret != 1 || nametimeo < 0) {
1065 vfs_mount_error(mp, "illegal nametimeo: %s", opt);
1070 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1072 ret = sscanf(opt, "%d", &negnametimeo);
1073 if (ret != 1 || negnametimeo < 0) {
1074 vfs_mount_error(mp, "illegal negnametimeo: %s",
1080 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1081 &args.addrlen) == 0) {
1083 if (args.addrlen > SOCK_MAXADDRLEN) {
1084 error = ENAMETOOLONG;
1087 nam = malloc(args.addrlen, M_SONAME,
1089 bcopy(args.addr, nam, args.addrlen);
1090 nam->sa_len = args.addrlen;
1092 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1093 &args.fhsize) == 0) {
1096 if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1098 has_hostname_opt = 1;
1100 if (args.hostname == NULL) {
1101 vfs_mount_error(mp, "Invalid hostname");
1105 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1106 vfs_mount_error(mp, "Bad file handle");
1111 if (mp->mnt_flag & MNT_UPDATE) {
1112 struct nfsmount *nmp = VFSTONFS(mp);
1120 * If a change from TCP->UDP is done and there are thread(s)
1121 * that have I/O RPC(s) in progress with a tranfer size
1122 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1123 * hung, retrying the RPC(s) forever. Usually these threads
1124 * will be seen doing an uninterruptible sleep on wait channel
1125 * "newnfsreq" (truncated to "newnfsre" by procstat).
1127 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1128 tprintf(curthread->td_proc, LOG_WARNING,
1129 "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1132 * When doing an update, we can't change from or to
1133 * v3, switch lockd strategies or change cookie translation
1135 args.flags = (args.flags &
1136 ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1138 (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1139 nfs_decode_args(mp, nmp, &args, NULL);
1144 * Make the nfs_ip_paranoia sysctl serve as the default connection
1145 * or no-connection mode for those protocols that support
1146 * no-connection mode (the flag will be cleared later for protocols
1147 * that do not support no-connection mode). This will allow a client
1148 * to receive replies from a different IP then the request was
1149 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1152 if (nfs_ip_paranoia == 0)
1153 args.flags |= NFSMNT_NOCONN;
1155 if (has_nfs_args_opt) {
1157 * In the 'nfs_args' case, the pointers in the args
1158 * structure are in userland - we copy them in here.
1161 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1168 if (!has_hostname_opt) {
1169 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1173 bzero(&hst[len], MNAMELEN - len);
1174 args.hostname = hst;
1176 if (!has_addr_opt) {
1177 /* sockargs() call must be after above copyin() calls */
1178 error = getsockaddr(&nam, (caddr_t)args.addr,
1184 } else if (has_addr_opt == 0) {
1185 vfs_mount_error(mp, "No server address");
1189 error = mountnfs(&args, mp, nam, args.hostname, &vp,
1190 curthread->td_ucred, nametimeo, negnametimeo);
1194 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1205 * It seems a bit dumb to copyinstr() the host and path here and then
1206 * bcopy() them in mountnfs(), but I wanted to detect errors before
1207 * doing the sockargs() call because sockargs() allocates an mbuf and
1208 * an error after that means that I have to release the mbuf.
1212 nfs_cmount(struct mntarg *ma, void *data, int flags)
1215 struct nfs_args args;
1217 error = copyin(data, &args, sizeof (struct nfs_args));
1221 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1223 error = kernel_mount(ma, flags);
1228 * Common code for mount and mountroot
1231 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1232 char *hst, struct vnode **vpp, struct ucred *cred, int nametimeo,
1235 struct nfsmount *nmp;
1240 if (mp->mnt_flag & MNT_UPDATE) {
1242 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1243 free(nam, M_SONAME);
1246 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1247 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1248 TAILQ_INIT(&nmp->nm_bufq);
1250 nmp->nm_getinfo = nfs_getnlminfo;
1251 nmp->nm_vinvalbuf = nfs_vinvalbuf;
1254 nmp->nm_mountp = mp;
1255 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
1258 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1259 * high, depending on whether we end up with negative offsets in
1260 * the client or server somewhere. 2GB-1 may be safer.
1262 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
1263 * that we can handle until we find out otherwise.
1265 if ((argp->flags & NFSMNT_NFSV3) == 0)
1266 nmp->nm_maxfilesize = 0xffffffffLL;
1268 nmp->nm_maxfilesize = OFF_MAX;
1270 nmp->nm_timeo = NFS_TIMEO;
1271 nmp->nm_retry = NFS_RETRANS;
1272 if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1273 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1275 nmp->nm_wsize = NFS_WSIZE;
1276 nmp->nm_rsize = NFS_RSIZE;
1278 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1279 nmp->nm_readdirsize = NFS_READDIRSIZE;
1280 nmp->nm_numgrps = NFS_MAXGRPS;
1281 nmp->nm_readahead = NFS_DEFRAHEAD;
1282 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1283 nmp->nm_nametimeo = nametimeo;
1284 nmp->nm_negnametimeo = negnametimeo;
1285 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1286 if (nmp->nm_tprintf_delay < 0)
1287 nmp->nm_tprintf_delay = 0;
1288 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1289 if (nmp->nm_tprintf_initial_delay < 0)
1290 nmp->nm_tprintf_initial_delay = 0;
1291 nmp->nm_fhsize = argp->fhsize;
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_rpcops = &nfs_rpcops;
1300 nfs_decode_args(mp, nmp, argp, hst);
1303 * For Connection based sockets (TCP,...) defer the connect until
1304 * the first request, in case the server is not responding.
1306 if (nmp->nm_sotype == SOCK_DGRAM &&
1307 (error = nfs_connect(nmp)))
1311 * This is silly, but it has to be set so that vinifod() works.
1312 * We do not want to do an nfs_statfs() here since we can get
1313 * stuck on a dead server and we are holding a lock on the mount
1316 mtx_lock(&nmp->nm_mtx);
1317 mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1318 mtx_unlock(&nmp->nm_mtx);
1320 * A reference count is needed on the nfsnode representing the
1321 * remote root. If this object is not persistent, then backward
1322 * traversals of the mount point (i.e. "..") will not work if
1323 * the nfsnode gets flushed out of the cache. Ufs does not have
1324 * this problem, because one can identify root inodes by their
1325 * number == ROOTINO (2).
1327 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1333 * Get file attributes and transfer parameters for the
1334 * mountpoint. This has the side effect of filling in
1335 * (*vpp)->v_type with the correct value.
1337 if (argp->flags & NFSMNT_NFSV3)
1338 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1340 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1343 * Lose the lock but keep the ref.
1345 VOP_UNLOCK(*vpp, 0);
1349 nfs_disconnect(nmp);
1350 mtx_destroy(&nmp->nm_mtx);
1351 uma_zfree(nfsmount_zone, nmp);
1352 free(nam, M_SONAME);
1357 * unmount system call
1360 nfs_unmount(struct mount *mp, int mntflags)
1362 struct nfsmount *nmp;
1363 int error, flags = 0;
1365 if (mntflags & MNT_FORCE)
1366 flags |= FORCECLOSE;
1369 * Goes something like this..
1370 * - Call vflush() to clear out vnodes for this filesystem
1371 * - Close the socket
1372 * - Free up the data structures
1374 /* In the forced case, cancel any outstanding requests. */
1375 if (flags & FORCECLOSE) {
1376 error = nfs_nmcancelreqs(nmp);
1380 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1381 error = vflush(mp, 1, flags, curthread);
1386 * We are now committed to the unmount.
1388 nfs_disconnect(nmp);
1389 free(nmp->nm_nam, M_SONAME);
1391 mtx_destroy(&nmp->nm_mtx);
1392 uma_zfree(nfsmount_zone, nmp);
1398 * Return root of a filesystem
1401 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1404 struct nfsmount *nmp;
1409 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1414 * Get transfer parameters and attributes for root vnode once.
1416 mtx_lock(&nmp->nm_mtx);
1417 if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1418 (nmp->nm_flag & NFSMNT_NFSV3)) {
1419 mtx_unlock(&nmp->nm_mtx);
1420 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1422 mtx_unlock(&nmp->nm_mtx);
1423 if (vp->v_type == VNON)
1425 vp->v_vflag |= VV_ROOT;
1431 * Flush out the buffer cache
1435 nfs_sync(struct mount *mp, int waitfor)
1437 struct vnode *vp, *mvp;
1439 int error, allerror = 0;
1445 * If a forced dismount is in progress, return from here so that
1446 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1447 * calling VFS_UNMOUNT().
1449 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1455 * Force stale buffer cache information to be flushed.
1458 MNT_VNODE_FOREACH(vp, mp, mvp) {
1461 /* XXX Racy bv_cnt check. */
1462 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1463 waitfor == MNT_LAZY) {
1468 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1470 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1473 error = VOP_FSYNC(vp, waitfor, td);
1486 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1488 struct nfsmount *nmp = VFSTONFS(mp);
1492 bzero(&vq, sizeof(vq));
1495 case VFS_CTL_NOLOCKS:
1496 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1497 if (req->oldptr != NULL) {
1498 error = SYSCTL_OUT(req, &val, sizeof(val));
1502 if (req->newptr != NULL) {
1503 error = SYSCTL_IN(req, &val, sizeof(val));
1507 nmp->nm_flag |= NFSMNT_NOLOCKS;
1509 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1514 mtx_lock(&nmp->nm_mtx);
1515 if (nmp->nm_state & NFSSTA_TIMEO)
1516 vq.vq_flags |= VQ_NOTRESP;
1517 mtx_unlock(&nmp->nm_mtx);
1519 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1520 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1521 vq.vq_flags |= VQ_NOTRESPLOCK;
1523 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1526 if (req->oldptr != NULL) {
1527 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1528 sizeof(nmp->nm_tprintf_initial_delay));
1532 if (req->newptr != NULL) {
1533 error = vfs_suser(mp, req->td);
1536 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1537 sizeof(nmp->nm_tprintf_initial_delay));
1540 if (nmp->nm_tprintf_initial_delay < 0)
1541 nmp->nm_tprintf_initial_delay = 0;
1551 * Extract the information needed by the nlm from the nfs vnode.
1554 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1555 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1556 struct timeval *timeop)
1558 struct nfsmount *nmp;
1559 struct nfsnode *np = VTONFS(vp);
1561 nmp = VFSTONFS(vp->v_mount);
1563 *fhlenp = (size_t)np->n_fhsize;
1565 bcopy(np->n_fhp, fhp, np->n_fhsize);
1567 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1569 *is_v3p = NFS_ISV3(vp);
1571 *sizep = np->n_size;
1572 if (timeop != NULL) {
1573 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1574 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);