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);
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);
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,
562 td->td_ucred, 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",
796 * It seems a bit dumb to copyinstr() the host and path here and then
797 * bcopy() them in mountnfs(), but I wanted to detect errors before
798 * doing the sockargs() call because sockargs() allocates an mbuf and
799 * an error after that means that I have to release the mbuf.
803 nfs_mount(struct mount *mp)
805 struct nfs_args args = {
806 .version = NFS_ARGSVERSION,
808 .addrlen = sizeof (struct sockaddr_in),
809 .sotype = SOCK_STREAM,
813 .flags = NFSMNT_RESVPORT,
816 .readdirsize = NFS_READDIRSIZE,
818 .retrans = NFS_RETRANS,
819 .maxgrouplist = NFS_MAXGRPS,
820 .readahead = NFS_DEFRAHEAD,
821 .wcommitsize = 0, /* was: NQ_DEFLEASE */
822 .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */
825 .acregmin = NFS_MINATTRTIMO,
826 .acregmax = NFS_MAXATTRTIMO,
827 .acdirmin = NFS_MINDIRATTRTIMO,
828 .acdirmax = NFS_MAXDIRATTRTIMO,
830 int error, ret, has_nfs_args_opt;
831 int has_addr_opt, has_fh_opt, has_hostname_opt;
832 struct sockaddr *nam;
836 u_char nfh[NFSX_V3FHMAX];
838 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
840 has_nfs_args_opt = 0;
843 has_hostname_opt = 0;
845 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
850 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
851 error = nfs_mountroot(mp);
856 * The old mount_nfs program passed the struct nfs_args
857 * from userspace to kernel. The new mount_nfs program
858 * passes string options via nmount() from userspace to kernel
859 * and we populate the struct nfs_args in the kernel.
861 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
862 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
867 if (args.version != NFS_ARGSVERSION) {
868 error = EPROGMISMATCH;
871 has_nfs_args_opt = 1;
874 if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
875 args.flags |= NFSMNT_DUMBTIMR;
876 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
877 args.flags |= NFSMNT_NOCONN;
878 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
879 args.flags |= NFSMNT_NOCONN;
880 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
881 args.flags |= NFSMNT_NOLOCKD;
882 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
883 args.flags &= ~NFSMNT_NOLOCKD;
884 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
885 args.flags |= NFSMNT_INT;
886 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
887 args.flags |= NFSMNT_RDIRPLUS;
888 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
889 args.flags |= NFSMNT_RESVPORT;
890 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
891 args.flags &= ~NFSMNT_RESVPORT;
892 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
893 args.flags |= NFSMNT_SOFT;
894 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
895 args.flags &= ~NFSMNT_SOFT;
896 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
897 args.sotype = SOCK_DGRAM;
898 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
899 args.sotype = SOCK_DGRAM;
900 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
901 args.sotype = SOCK_STREAM;
902 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
903 args.flags |= NFSMNT_NFSV3;
904 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
905 args.flags |= NFSMNT_NOCTO;
906 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
908 vfs_mount_error(mp, "illegal readdirsize");
912 ret = sscanf(opt, "%d", &args.readdirsize);
913 if (ret != 1 || args.readdirsize <= 0) {
914 vfs_mount_error(mp, "illegal readdirsize: %s",
919 args.flags |= NFSMNT_READDIRSIZE;
921 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
923 vfs_mount_error(mp, "illegal readahead");
927 ret = sscanf(opt, "%d", &args.readahead);
928 if (ret != 1 || args.readahead <= 0) {
929 vfs_mount_error(mp, "illegal readahead: %s",
934 args.flags |= NFSMNT_READAHEAD;
936 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
938 vfs_mount_error(mp, "illegal wsize");
942 ret = sscanf(opt, "%d", &args.wsize);
943 if (ret != 1 || args.wsize <= 0) {
944 vfs_mount_error(mp, "illegal wsize: %s",
949 args.flags |= NFSMNT_WSIZE;
951 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
953 vfs_mount_error(mp, "illegal rsize");
957 ret = sscanf(opt, "%d", &args.rsize);
958 if (ret != 1 || args.rsize <= 0) {
959 vfs_mount_error(mp, "illegal wsize: %s",
964 args.flags |= NFSMNT_RSIZE;
966 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
968 vfs_mount_error(mp, "illegal retrans");
972 ret = sscanf(opt, "%d", &args.retrans);
973 if (ret != 1 || args.retrans <= 0) {
974 vfs_mount_error(mp, "illegal retrans: %s",
979 args.flags |= NFSMNT_RETRANS;
981 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
982 ret = sscanf(opt, "%d", &args.acregmin);
983 if (ret != 1 || args.acregmin < 0) {
984 vfs_mount_error(mp, "illegal acregmin: %s",
989 args.flags |= NFSMNT_ACREGMIN;
991 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
992 ret = sscanf(opt, "%d", &args.acregmax);
993 if (ret != 1 || args.acregmax < 0) {
994 vfs_mount_error(mp, "illegal acregmax: %s",
999 args.flags |= NFSMNT_ACREGMAX;
1001 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
1002 ret = sscanf(opt, "%d", &args.acdirmin);
1003 if (ret != 1 || args.acdirmin < 0) {
1004 vfs_mount_error(mp, "illegal acdirmin: %s",
1009 args.flags |= NFSMNT_ACDIRMIN;
1011 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1012 ret = sscanf(opt, "%d", &args.acdirmax);
1013 if (ret != 1 || args.acdirmax < 0) {
1014 vfs_mount_error(mp, "illegal acdirmax: %s",
1019 args.flags |= NFSMNT_ACDIRMAX;
1021 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
1022 ret = sscanf(opt, "%d", &args.wcommitsize);
1023 if (ret != 1 || args.wcommitsize < 0) {
1024 vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
1028 args.flags |= NFSMNT_WCOMMITSIZE;
1030 if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1031 ret = sscanf(opt, "%d", &args.deadthresh);
1032 if (ret != 1 || args.deadthresh <= 0) {
1033 vfs_mount_error(mp, "illegal deadthresh: %s",
1038 args.flags |= NFSMNT_DEADTHRESH;
1040 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1041 ret = sscanf(opt, "%d", &args.timeo);
1042 if (ret != 1 || args.timeo <= 0) {
1043 vfs_mount_error(mp, "illegal timeout: %s",
1048 args.flags |= NFSMNT_TIMEO;
1050 if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1051 ret = sscanf(opt, "%d", &args.maxgrouplist);
1052 if (ret != 1 || args.maxgrouplist <= 0) {
1053 vfs_mount_error(mp, "illegal maxgroups: %s",
1058 args.flags |= NFSMNT_MAXGRPS;
1060 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1062 ret = sscanf(opt, "%d", &negnametimeo);
1063 if (ret != 1 || negnametimeo < 0) {
1064 vfs_mount_error(mp, "illegal negnametimeo: %s",
1070 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1071 &args.addrlen) == 0) {
1073 if (args.addrlen > SOCK_MAXADDRLEN) {
1074 error = ENAMETOOLONG;
1077 nam = malloc(args.addrlen, M_SONAME,
1079 bcopy(args.addr, nam, args.addrlen);
1080 nam->sa_len = args.addrlen;
1082 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1083 &args.fhsize) == 0) {
1086 if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1088 has_hostname_opt = 1;
1090 if (args.hostname == NULL) {
1091 vfs_mount_error(mp, "Invalid hostname");
1095 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1096 vfs_mount_error(mp, "Bad file handle");
1101 if (mp->mnt_flag & MNT_UPDATE) {
1102 struct nfsmount *nmp = VFSTONFS(mp);
1110 * If a change from TCP->UDP is done and there are thread(s)
1111 * that have I/O RPC(s) in progress with a tranfer size
1112 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1113 * hung, retrying the RPC(s) forever. Usually these threads
1114 * will be seen doing an uninterruptible sleep on wait channel
1115 * "newnfsreq" (truncated to "newnfsre" by procstat).
1117 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1118 tprintf(curthread->td_proc, LOG_WARNING,
1119 "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1122 * When doing an update, we can't change from or to
1123 * v3, switch lockd strategies or change cookie translation
1125 args.flags = (args.flags &
1126 ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1128 (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1129 nfs_decode_args(mp, nmp, &args, NULL);
1134 * Make the nfs_ip_paranoia sysctl serve as the default connection
1135 * or no-connection mode for those protocols that support
1136 * no-connection mode (the flag will be cleared later for protocols
1137 * that do not support no-connection mode). This will allow a client
1138 * to receive replies from a different IP then the request was
1139 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1142 if (nfs_ip_paranoia == 0)
1143 args.flags |= NFSMNT_NOCONN;
1145 if (has_nfs_args_opt) {
1147 * In the 'nfs_args' case, the pointers in the args
1148 * structure are in userland - we copy them in here.
1151 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1158 if (!has_hostname_opt) {
1159 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1163 bzero(&hst[len], MNAMELEN - len);
1164 args.hostname = hst;
1166 if (!has_addr_opt) {
1167 /* sockargs() call must be after above copyin() calls */
1168 error = getsockaddr(&nam, (caddr_t)args.addr,
1174 } else if (has_addr_opt == 0) {
1175 vfs_mount_error(mp, "No server address");
1179 error = mountnfs(&args, mp, nam, args.hostname, &vp,
1180 curthread->td_ucred, negnametimeo);
1184 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1195 * It seems a bit dumb to copyinstr() the host and path here and then
1196 * bcopy() them in mountnfs(), but I wanted to detect errors before
1197 * doing the sockargs() call because sockargs() allocates an mbuf and
1198 * an error after that means that I have to release the mbuf.
1202 nfs_cmount(struct mntarg *ma, void *data, int flags)
1205 struct nfs_args args;
1207 error = copyin(data, &args, sizeof (struct nfs_args));
1211 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1213 error = kernel_mount(ma, flags);
1218 * Common code for mount and mountroot
1221 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1222 char *hst, struct vnode **vpp, struct ucred *cred, int negnametimeo)
1224 struct nfsmount *nmp;
1229 if (mp->mnt_flag & MNT_UPDATE) {
1231 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1232 free(nam, M_SONAME);
1235 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1236 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1237 TAILQ_INIT(&nmp->nm_bufq);
1239 nmp->nm_getinfo = nfs_getnlminfo;
1240 nmp->nm_vinvalbuf = nfs_vinvalbuf;
1243 nmp->nm_mountp = mp;
1244 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
1247 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1248 * high, depending on whether we end up with negative offsets in
1249 * the client or server somewhere. 2GB-1 may be safer.
1251 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
1252 * that we can handle until we find out otherwise.
1254 if ((argp->flags & NFSMNT_NFSV3) == 0)
1255 nmp->nm_maxfilesize = 0xffffffffLL;
1257 nmp->nm_maxfilesize = OFF_MAX;
1259 nmp->nm_timeo = NFS_TIMEO;
1260 nmp->nm_retry = NFS_RETRANS;
1261 if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1262 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1264 nmp->nm_wsize = NFS_WSIZE;
1265 nmp->nm_rsize = NFS_RSIZE;
1267 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1268 nmp->nm_readdirsize = NFS_READDIRSIZE;
1269 nmp->nm_numgrps = NFS_MAXGRPS;
1270 nmp->nm_readahead = NFS_DEFRAHEAD;
1271 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1272 nmp->nm_negnametimeo = negnametimeo;
1273 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1274 if (nmp->nm_tprintf_delay < 0)
1275 nmp->nm_tprintf_delay = 0;
1276 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1277 if (nmp->nm_tprintf_initial_delay < 0)
1278 nmp->nm_tprintf_initial_delay = 0;
1279 nmp->nm_fhsize = argp->fhsize;
1280 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1281 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1283 /* Set up the sockets and per-host congestion */
1284 nmp->nm_sotype = argp->sotype;
1285 nmp->nm_soproto = argp->proto;
1286 nmp->nm_rpcops = &nfs_rpcops;
1288 nfs_decode_args(mp, nmp, argp, hst);
1291 * For Connection based sockets (TCP,...) defer the connect until
1292 * the first request, in case the server is not responding.
1294 if (nmp->nm_sotype == SOCK_DGRAM &&
1295 (error = nfs_connect(nmp)))
1299 * This is silly, but it has to be set so that vinifod() works.
1300 * We do not want to do an nfs_statfs() here since we can get
1301 * stuck on a dead server and we are holding a lock on the mount
1304 mtx_lock(&nmp->nm_mtx);
1305 mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1306 mtx_unlock(&nmp->nm_mtx);
1308 * A reference count is needed on the nfsnode representing the
1309 * remote root. If this object is not persistent, then backward
1310 * traversals of the mount point (i.e. "..") will not work if
1311 * the nfsnode gets flushed out of the cache. Ufs does not have
1312 * this problem, because one can identify root inodes by their
1313 * number == ROOTINO (2).
1315 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1321 * Get file attributes and transfer parameters for the
1322 * mountpoint. This has the side effect of filling in
1323 * (*vpp)->v_type with the correct value.
1325 if (argp->flags & NFSMNT_NFSV3)
1326 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1328 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1331 * Lose the lock but keep the ref.
1333 VOP_UNLOCK(*vpp, 0);
1337 nfs_disconnect(nmp);
1338 mtx_destroy(&nmp->nm_mtx);
1339 uma_zfree(nfsmount_zone, nmp);
1340 free(nam, M_SONAME);
1345 * unmount system call
1348 nfs_unmount(struct mount *mp, int mntflags)
1350 struct nfsmount *nmp;
1351 int error, flags = 0;
1353 if (mntflags & MNT_FORCE)
1354 flags |= FORCECLOSE;
1357 * Goes something like this..
1358 * - Call vflush() to clear out vnodes for this filesystem
1359 * - Close the socket
1360 * - Free up the data structures
1362 /* In the forced case, cancel any outstanding requests. */
1363 if (flags & FORCECLOSE) {
1364 error = nfs_nmcancelreqs(nmp);
1368 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1369 error = vflush(mp, 1, flags, curthread);
1374 * We are now committed to the unmount.
1376 nfs_disconnect(nmp);
1377 free(nmp->nm_nam, M_SONAME);
1379 mtx_destroy(&nmp->nm_mtx);
1380 uma_zfree(nfsmount_zone, nmp);
1386 * Return root of a filesystem
1389 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1392 struct nfsmount *nmp;
1397 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1402 * Get transfer parameters and attributes for root vnode once.
1404 mtx_lock(&nmp->nm_mtx);
1405 if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1406 (nmp->nm_flag & NFSMNT_NFSV3)) {
1407 mtx_unlock(&nmp->nm_mtx);
1408 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1410 mtx_unlock(&nmp->nm_mtx);
1411 if (vp->v_type == VNON)
1413 vp->v_vflag |= VV_ROOT;
1419 * Flush out the buffer cache
1423 nfs_sync(struct mount *mp, int waitfor)
1425 struct vnode *vp, *mvp;
1427 int error, allerror = 0;
1433 * If a forced dismount is in progress, return from here so that
1434 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1435 * calling VFS_UNMOUNT().
1437 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1443 * Force stale buffer cache information to be flushed.
1446 MNT_VNODE_FOREACH(vp, mp, mvp) {
1449 /* XXX Racy bv_cnt check. */
1450 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1451 waitfor == MNT_LAZY) {
1456 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1458 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1461 error = VOP_FSYNC(vp, waitfor, td);
1474 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1476 struct nfsmount *nmp = VFSTONFS(mp);
1480 bzero(&vq, sizeof(vq));
1483 case VFS_CTL_NOLOCKS:
1484 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1485 if (req->oldptr != NULL) {
1486 error = SYSCTL_OUT(req, &val, sizeof(val));
1490 if (req->newptr != NULL) {
1491 error = SYSCTL_IN(req, &val, sizeof(val));
1495 nmp->nm_flag |= NFSMNT_NOLOCKS;
1497 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1502 mtx_lock(&nmp->nm_mtx);
1503 if (nmp->nm_state & NFSSTA_TIMEO)
1504 vq.vq_flags |= VQ_NOTRESP;
1505 mtx_unlock(&nmp->nm_mtx);
1507 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1508 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1509 vq.vq_flags |= VQ_NOTRESPLOCK;
1511 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1514 if (req->oldptr != NULL) {
1515 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1516 sizeof(nmp->nm_tprintf_initial_delay));
1520 if (req->newptr != NULL) {
1521 error = vfs_suser(mp, req->td);
1524 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1525 sizeof(nmp->nm_tprintf_initial_delay));
1528 if (nmp->nm_tprintf_initial_delay < 0)
1529 nmp->nm_tprintf_initial_delay = 0;
1539 * Extract the information needed by the nlm from the nfs vnode.
1542 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1543 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1544 struct timeval *timeop)
1546 struct nfsmount *nmp;
1547 struct nfsnode *np = VTONFS(vp);
1549 nmp = VFSTONFS(vp->v_mount);
1551 *fhlenp = (size_t)np->n_fhsize;
1553 bcopy(np->n_fhp, fhp, np->n_fhsize);
1555 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1557 *is_v3p = NFS_ISV3(vp);
1559 *sizep = np->n_size;
1560 if (timeop != NULL) {
1561 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1562 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);