]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/nfsclient/nfs_vfsops.c
Add atf pkg-config files from the vendor branch.
[FreeBSD/FreeBSD.git] / sys / nfsclient / nfs_vfsops.c
1 /*-
2  * Copyright (c) 1989, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Macklem at The University of Guelph.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
19  *
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
30  * SUCH DAMAGE.
31  *
32  *      @(#)nfs_vfsops.c        8.12 (Berkeley) 5/20/95
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38
39 #include "opt_bootp.h"
40 #include "opt_nfsroot.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/bio.h>
46 #include <sys/buf.h>
47 #include <sys/jail.h>
48 #include <sys/limits.h>
49 #include <sys/lock.h>
50 #include <sys/malloc.h>
51 #include <sys/mbuf.h>
52 #include <sys/module.h>
53 #include <sys/mount.h>
54 #include <sys/proc.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>
62
63 #include <vm/vm.h>
64 #include <vm/vm_extern.h>
65 #include <vm/uma.h>
66
67 #include <net/if.h>
68 #include <net/if_var.h>
69 #include <net/route.h>
70 #include <net/vnet.h>
71
72 #include <netinet/in.h>
73
74 #include <rpc/rpc.h>
75
76 #include <nfs/nfsproto.h>
77 #include <nfsclient/nfs.h>
78 #include <nfsclient/nfsnode.h>
79 #include <nfsclient/nfsmount.h>
80 #include <nfs/xdr_subs.h>
81 #include <nfsclient/nfsm_subs.h>
82 #include <nfs/nfsdiskless.h>
83
84 FEATURE(nfsclient, "NFS client");
85
86 MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
87 MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
88 MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
89 MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
90 MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
91
92 uma_zone_t nfsmount_zone;
93
94 struct nfsstats nfsstats;
95
96 SYSCTL_NODE(_vfs, OID_AUTO, oldnfs, CTLFLAG_RW, 0, "Old NFS filesystem");
97 SYSCTL_STRUCT(_vfs_oldnfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
98         &nfsstats, nfsstats, "S,nfsstats");
99 static int nfs_ip_paranoia = 1;
100 SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
101     &nfs_ip_paranoia, 0,
102     "Disallow accepting replies from IPs which differ from those sent");
103 #ifdef NFS_DEBUG
104 int nfs_debug;
105 SYSCTL_INT(_vfs_oldnfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
106     "Toggle debug flag");
107 #endif
108 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
109 SYSCTL_INT(_vfs_oldnfs, NFS_TPRINTF_INITIAL_DELAY,
110     downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0,
111     "Delay before printing \"nfs server not responding\" messages");
112 /* how long between console messages "nfs server foo not responding" */
113 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
114 SYSCTL_INT(_vfs_oldnfs, NFS_TPRINTF_DELAY,
115     downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0,
116     "Delay between printing \"nfs server not responding\" messages");
117
118 static void     nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
119                     struct nfs_args *argp, const char *hostname);
120 static int      mountnfs(struct nfs_args *, struct mount *,
121                     struct sockaddr *, char *, struct vnode **,
122                     struct ucred *cred, int, int);
123 static void     nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
124                     struct sockaddr_storage *, int *, off_t *,
125                     struct timeval *);
126 static vfs_mount_t nfs_mount;
127 static vfs_cmount_t nfs_cmount;
128 static vfs_unmount_t nfs_unmount;
129 static vfs_root_t nfs_root;
130 static vfs_statfs_t nfs_statfs;
131 static vfs_sync_t nfs_sync;
132 static vfs_sysctl_t nfs_sysctl;
133
134 static int      fake_wchan;
135
136 /*
137  * nfs vfs operations.
138  */
139 static struct vfsops nfs_vfsops = {
140         .vfs_init =             nfs_init,
141         .vfs_mount =            nfs_mount,
142         .vfs_cmount =           nfs_cmount,
143         .vfs_root =             nfs_root,
144         .vfs_statfs =           nfs_statfs,
145         .vfs_sync =             nfs_sync,
146         .vfs_uninit =           nfs_uninit,
147         .vfs_unmount =          nfs_unmount,
148         .vfs_sysctl =           nfs_sysctl,
149 };
150 VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK | VFCF_SBDRY);
151
152 /* So that loader and kldload(2) can find us, wherever we are.. */
153 MODULE_VERSION(oldnfs, 1);
154 MODULE_DEPEND(oldnfs, krpc, 1, 1, 1);
155 #ifdef KGSSAPI
156 MODULE_DEPEND(oldnfs, kgssapi, 1, 1, 1);
157 #endif
158 MODULE_DEPEND(oldnfs, nfs_common, 1, 1, 1);
159 MODULE_DEPEND(oldnfs, nfslock, 1, 1, 1);
160
161 static struct nfs_rpcops nfs_rpcops = {
162         nfs_readrpc,
163         nfs_writerpc,
164         nfs_writebp,
165         nfs_readlinkrpc,
166         nfs_invaldir,
167         nfs_commit,
168 };
169
170 /*
171  * This structure is now defined in sys/nfs/nfs_diskless.c so that it
172  * can be shared by both NFS clients. It is declared here so that it
173  * will be defined for kernels built without NFS_ROOT, although it
174  * isn't used in that case.
175  */
176 #ifndef NFS_ROOT
177 struct nfs_diskless     nfs_diskless = { { { 0 } } };
178 struct nfsv3_diskless   nfsv3_diskless = { { { 0 } } };
179 int                     nfs_diskless_valid = 0;
180 #endif
181
182 SYSCTL_INT(_vfs_oldnfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
183     &nfs_diskless_valid, 0,
184     "Has the diskless struct been filled correctly");
185
186 SYSCTL_STRING(_vfs_oldnfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
187     nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
188
189 SYSCTL_OPAQUE(_vfs_oldnfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
190     &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
191     "%Ssockaddr_in", "Diskless root nfs address");
192
193
194 void            nfsargs_ntoh(struct nfs_args *);
195 static int      nfs_mountdiskless(char *,
196                     struct sockaddr_in *, struct nfs_args *,
197                     struct thread *, struct vnode **, struct mount *);
198 static void     nfs_convert_diskless(void);
199 static void     nfs_convert_oargs(struct nfs_args *args,
200                     struct onfs_args *oargs);
201
202 int
203 nfs_iosize(struct nfsmount *nmp)
204 {
205         int iosize;
206
207         /*
208          * Calculate the size used for io buffers.  Use the larger
209          * of the two sizes to minimise nfs requests but make sure
210          * that it is at least one VM page to avoid wasting buffer
211          * space.
212          */
213         iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
214         iosize = imax(iosize, PAGE_SIZE);
215         return (iosize);
216 }
217
218 static void
219 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
220 {
221
222         args->version = NFS_ARGSVERSION;
223         args->addr = oargs->addr;
224         args->addrlen = oargs->addrlen;
225         args->sotype = oargs->sotype;
226         args->proto = oargs->proto;
227         args->fh = oargs->fh;
228         args->fhsize = oargs->fhsize;
229         args->flags = oargs->flags;
230         args->wsize = oargs->wsize;
231         args->rsize = oargs->rsize;
232         args->readdirsize = oargs->readdirsize;
233         args->timeo = oargs->timeo;
234         args->retrans = oargs->retrans;
235         args->maxgrouplist = oargs->maxgrouplist;
236         args->readahead = oargs->readahead;
237         args->deadthresh = oargs->deadthresh;
238         args->hostname = oargs->hostname;
239 }
240
241 static void
242 nfs_convert_diskless(void)
243 {
244
245         bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
246                 sizeof(struct ifaliasreq));
247         bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
248                 sizeof(struct sockaddr_in));
249         nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
250         if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
251                 nfsv3_diskless.root_fhsize = NFSX_V3FH;
252                 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
253         } else {
254                 nfsv3_diskless.root_fhsize = NFSX_V2FH;
255                 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
256         }
257         bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
258                 sizeof(struct sockaddr_in));
259         bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
260         nfsv3_diskless.root_time = nfs_diskless.root_time;
261         bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
262                 MAXHOSTNAMELEN);
263         nfs_diskless_valid = 3;
264 }
265
266 /*
267  * nfs statfs call
268  */
269 static int
270 nfs_statfs(struct mount *mp, struct statfs *sbp)
271 {
272         struct vnode *vp;
273         struct thread *td;
274         struct nfs_statfs *sfp;
275         caddr_t bpos, dpos;
276         struct nfsmount *nmp = VFSTONFS(mp);
277         int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
278         struct mbuf *mreq, *mrep, *md, *mb;
279         struct nfsnode *np;
280         u_quad_t tquad;
281
282         td = curthread;
283 #ifndef nolint
284         sfp = NULL;
285 #endif
286         error = vfs_busy(mp, MBF_NOWAIT);
287         if (error)
288                 return (error);
289         error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
290         if (error) {
291                 vfs_unbusy(mp);
292                 return (error);
293         }
294         vp = NFSTOV(np);
295         mtx_lock(&nmp->nm_mtx);
296         if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
297                 mtx_unlock(&nmp->nm_mtx);               
298                 (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
299         } else
300                 mtx_unlock(&nmp->nm_mtx);
301         nfsstats.rpccnt[NFSPROC_FSSTAT]++;
302         mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
303         mb = mreq;
304         bpos = mtod(mb, caddr_t);
305         nfsm_fhtom(vp, v3);
306         nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
307         if (v3)
308                 nfsm_postop_attr(vp, retattr);
309         if (error) {
310                 if (mrep != NULL)
311                         m_freem(mrep);
312                 goto nfsmout;
313         }
314         sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
315         mtx_lock(&nmp->nm_mtx);
316         sbp->f_iosize = nfs_iosize(nmp);
317         mtx_unlock(&nmp->nm_mtx);
318         if (v3) {
319                 sbp->f_bsize = NFS_FABLKSIZE;
320                 tquad = fxdr_hyper(&sfp->sf_tbytes);
321                 sbp->f_blocks = tquad / NFS_FABLKSIZE;
322                 tquad = fxdr_hyper(&sfp->sf_fbytes);
323                 sbp->f_bfree = tquad / NFS_FABLKSIZE;
324                 tquad = fxdr_hyper(&sfp->sf_abytes);
325                 sbp->f_bavail = tquad / NFS_FABLKSIZE;
326                 sbp->f_files = (fxdr_unsigned(int32_t,
327                     sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
328                 sbp->f_ffree = (fxdr_unsigned(int32_t,
329                     sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
330         } else {
331                 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
332                 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
333                 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
334                 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
335                 sbp->f_files = 0;
336                 sbp->f_ffree = 0;
337         }
338         m_freem(mrep);
339 nfsmout:
340         vput(vp);
341         vfs_unbusy(mp);
342         return (error);
343 }
344
345 /*
346  * nfs version 3 fsinfo rpc call
347  */
348 int
349 nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
350     struct thread *td)
351 {
352         struct nfsv3_fsinfo *fsp;
353         u_int32_t pref, max;
354         caddr_t bpos, dpos;
355         int error = 0, retattr;
356         struct mbuf *mreq, *mrep, *md, *mb;
357         u_int64_t maxfsize;
358         
359         nfsstats.rpccnt[NFSPROC_FSINFO]++;
360         mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0);
361         mb = mreq;
362         bpos = mtod(mb, caddr_t);
363         nfsm_fhtom(vp, 1);
364         nfsm_request(vp, NFSPROC_FSINFO, td, cred);
365         nfsm_postop_attr(vp, retattr);
366         if (!error) {
367                 fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
368                 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
369                 mtx_lock(&nmp->nm_mtx);
370                 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
371                         nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
372                                 ~(NFS_FABLKSIZE - 1);
373                 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
374                 if (max < nmp->nm_wsize && max > 0) {
375                         nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
376                         if (nmp->nm_wsize == 0)
377                                 nmp->nm_wsize = max;
378                 }
379                 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
380                 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
381                         nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
382                                 ~(NFS_FABLKSIZE - 1);
383                 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
384                 if (max < nmp->nm_rsize && max > 0) {
385                         nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
386                         if (nmp->nm_rsize == 0)
387                                 nmp->nm_rsize = max;
388                 }
389                 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
390                 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
391                         nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
392                                 ~(NFS_DIRBLKSIZ - 1);
393                 if (max < nmp->nm_readdirsize && max > 0) {
394                         nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
395                         if (nmp->nm_readdirsize == 0)
396                                 nmp->nm_readdirsize = max;
397                 }
398                 maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
399                 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
400                         nmp->nm_maxfilesize = maxfsize;
401                 nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
402                 nmp->nm_state |= NFSSTA_GOTFSINFO;
403                 mtx_unlock(&nmp->nm_mtx);
404         }
405         m_freem(mrep);
406 nfsmout:
407         return (error);
408 }
409
410 /*
411  * Mount a remote root fs via. nfs. This depends on the info in the
412  * nfs_diskless structure that has been filled in properly by some primary
413  * bootstrap.
414  * It goes something like this:
415  * - do enough of "ifconfig" by calling ifioctl() so that the system
416  *   can talk to the server
417  * - If nfs_diskless.mygateway is filled in, use that address as
418  *   a default gateway.
419  * - build the rootfs mount point and call mountnfs() to do the rest.
420  *
421  * It is assumed to be safe to read, modify, and write the nfsv3_diskless
422  * structure, as well as other global NFS client variables here, as
423  * nfs_mountroot() will be called once in the boot before any other NFS
424  * client activity occurs.
425  */
426 int
427 nfs_mountroot(struct mount *mp)
428 {
429         struct thread *td = curthread;
430         struct nfsv3_diskless *nd = &nfsv3_diskless;
431         struct socket *so;
432         struct vnode *vp;
433         struct ifreq ir;
434         int error;
435         u_long l;
436         char buf[128];
437         char *cp;
438
439
440 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
441         bootpc_init();          /* use bootp to get nfs_diskless filled in */
442 #elif defined(NFS_ROOT)
443         nfs_setup_diskless();
444 #endif
445
446         if (nfs_diskless_valid == 0) {
447                 return (-1);
448         }
449         if (nfs_diskless_valid == 1)
450                 nfs_convert_diskless();
451
452         /*
453          * XXX splnet, so networks will receive...
454          */
455         splnet();
456
457         /*
458          * Do enough of ifconfig(8) so that the critical net interface can
459          * talk to the server.
460          */
461         error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
462             td->td_ucred, td);
463         if (error)
464                 panic("nfs_mountroot: socreate(%04x): %d",
465                         nd->myif.ifra_addr.sa_family, error);
466
467 #if 0 /* XXX Bad idea */
468         /*
469          * We might not have been told the right interface, so we pass
470          * over the first ten interfaces of the same kind, until we get
471          * one of them configured.
472          */
473
474         for (i = strlen(nd->myif.ifra_name) - 1;
475                 nd->myif.ifra_name[i] >= '0' &&
476                 nd->myif.ifra_name[i] <= '9';
477                 nd->myif.ifra_name[i] ++) {
478                 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
479                 if(!error)
480                         break;
481         }
482 #endif
483
484         error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
485         if (error)
486                 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
487
488         if ((cp = getenv("boot.netif.mtu")) != NULL) {
489                 ir.ifr_mtu = strtol(cp, NULL, 10);
490                 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
491                 freeenv(cp);
492                 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
493                 if (error)
494                         printf("nfs_mountroot: SIOCSIFMTU: %d", error);
495         }
496         soclose(so);
497
498         /*
499          * If the gateway field is filled in, set it as the default route.
500          * Note that pxeboot will set a default route of 0 if the route
501          * is not set by the DHCP server.  Check also for a value of 0
502          * to avoid panicking inappropriately in that situation.
503          */
504         if (nd->mygateway.sin_len != 0 &&
505             nd->mygateway.sin_addr.s_addr != 0) {
506                 struct sockaddr_in mask, sin;
507
508                 bzero((caddr_t)&mask, sizeof(mask));
509                 sin = mask;
510                 sin.sin_family = AF_INET;
511                 sin.sin_len = sizeof(sin);
512                 /* XXX MRT use table 0 for this sort of thing */
513                 CURVNET_SET(TD_TO_VNET(td));
514                 error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
515                     (struct sockaddr *)&nd->mygateway,
516                     (struct sockaddr *)&mask,
517                     RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
518                 CURVNET_RESTORE();
519                 if (error)
520                         panic("nfs_mountroot: RTM_ADD: %d", error);
521         }
522
523         /*
524          * Create the rootfs mount point.
525          */
526         nd->root_args.fh = nd->root_fh;
527         nd->root_args.fhsize = nd->root_fhsize;
528         l = ntohl(nd->root_saddr.sin_addr.s_addr);
529         snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
530                 (l >> 24) & 0xff, (l >> 16) & 0xff,
531                 (l >>  8) & 0xff, (l >>  0) & 0xff, nd->root_hostnam);
532         printf("NFS ROOT: %s\n", buf);
533         nd->root_args.hostname = buf;
534         if ((error = nfs_mountdiskless(buf,
535             &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
536                 return (error);
537         }
538
539         /*
540          * This is not really an nfs issue, but it is much easier to
541          * set hostname here and then let the "/etc/rc.xxx" files
542          * mount the right /var based upon its preset value.
543          */
544         mtx_lock(&prison0.pr_mtx);
545         strlcpy(prison0.pr_hostname, nd->my_hostnam,
546             sizeof (prison0.pr_hostname));
547         mtx_unlock(&prison0.pr_mtx);
548         inittodr(ntohl(nd->root_time));
549         return (0);
550 }
551
552 /*
553  * Internal version of mount system call for diskless setup.
554  */
555 static int
556 nfs_mountdiskless(char *path,
557     struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
558     struct vnode **vpp, struct mount *mp)
559 {
560         struct sockaddr *nam;
561         int error;
562
563         nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
564         if ((error = mountnfs(args, mp, nam, path, vpp, td->td_ucred,
565             NFS_DEFAULT_NAMETIMEO, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
566                 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
567                 return (error);
568         }
569         return (0);
570 }
571
572 static int
573 nfs_sec_name_to_num(char *sec)
574 {
575         if (!strcmp(sec, "krb5"))
576                 return (RPCSEC_GSS_KRB5);
577         if (!strcmp(sec, "krb5i"))
578                 return (RPCSEC_GSS_KRB5I);
579         if (!strcmp(sec, "krb5p"))
580                 return (RPCSEC_GSS_KRB5P);
581         if (!strcmp(sec, "sys"))
582                 return (AUTH_SYS);
583         /*
584          * Userland should validate the string but we will try and
585          * cope with unexpected values.
586          */
587         return (AUTH_SYS);
588 }
589
590 static void
591 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
592         const char *hostname)
593 {
594         int s;
595         int adjsock;
596         int maxio;
597         char *p;
598         char *secname;
599         char *principal;
600
601         s = splnet();
602
603         /*
604          * Set read-only flag if requested; otherwise, clear it if this is
605          * an update.  If this is not an update, then either the read-only
606          * flag is already clear, or this is a root mount and it was set
607          * intentionally at some previous point.
608          */
609         if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
610                 MNT_ILOCK(mp);
611                 mp->mnt_flag |= MNT_RDONLY;
612                 MNT_IUNLOCK(mp);
613         } else if (mp->mnt_flag & MNT_UPDATE) {
614                 MNT_ILOCK(mp);
615                 mp->mnt_flag &= ~MNT_RDONLY;
616                 MNT_IUNLOCK(mp);
617         }
618
619         /*
620          * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
621          * no sense in that context.  Also, set up appropriate retransmit
622          * and soft timeout behavior.
623          */
624         if (argp->sotype == SOCK_STREAM) {
625                 nmp->nm_flag &= ~NFSMNT_NOCONN;
626                 nmp->nm_flag |= NFSMNT_DUMBTIMR;
627                 nmp->nm_timeo = NFS_MAXTIMEO;
628                 nmp->nm_retry = NFS_RETRANS_TCP;
629         }
630
631         /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
632         if ((argp->flags & NFSMNT_NFSV3) == 0)
633                 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
634
635         /* Re-bind if rsrvd port requested and wasn't on one */
636         adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
637                   && (argp->flags & NFSMNT_RESVPORT);
638         /* Also re-bind if we're switching to/from a connected UDP socket */
639         adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
640                     (argp->flags & NFSMNT_NOCONN));
641
642         /* Update flags atomically.  Don't change the lock bits. */
643         nmp->nm_flag = argp->flags | nmp->nm_flag;
644         splx(s);
645
646         if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
647                 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
648                 if (nmp->nm_timeo < NFS_MINTIMEO)
649                         nmp->nm_timeo = NFS_MINTIMEO;
650                 else if (nmp->nm_timeo > NFS_MAXTIMEO)
651                         nmp->nm_timeo = NFS_MAXTIMEO;
652         }
653
654         if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
655                 nmp->nm_retry = argp->retrans;
656                 if (nmp->nm_retry > NFS_MAXREXMIT)
657                         nmp->nm_retry = NFS_MAXREXMIT;
658         }
659
660         if (argp->flags & NFSMNT_NFSV3) {
661                 if (argp->sotype == SOCK_DGRAM)
662                         maxio = NFS_MAXDGRAMDATA;
663                 else
664                         maxio = NFS_MAXDATA;
665         } else
666                 maxio = NFS_V2MAXDATA;
667
668         if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
669                 nmp->nm_wsize = argp->wsize;
670                 /* Round down to multiple of blocksize */
671                 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
672                 if (nmp->nm_wsize <= 0)
673                         nmp->nm_wsize = NFS_FABLKSIZE;
674         }
675         if (nmp->nm_wsize > maxio)
676                 nmp->nm_wsize = maxio;
677         if (nmp->nm_wsize > MAXBSIZE)
678                 nmp->nm_wsize = MAXBSIZE;
679
680         if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
681                 nmp->nm_rsize = argp->rsize;
682                 /* Round down to multiple of blocksize */
683                 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
684                 if (nmp->nm_rsize <= 0)
685                         nmp->nm_rsize = NFS_FABLKSIZE;
686         }
687         if (nmp->nm_rsize > maxio)
688                 nmp->nm_rsize = maxio;
689         if (nmp->nm_rsize > MAXBSIZE)
690                 nmp->nm_rsize = MAXBSIZE;
691
692         if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
693                 nmp->nm_readdirsize = argp->readdirsize;
694         }
695         if (nmp->nm_readdirsize > maxio)
696                 nmp->nm_readdirsize = maxio;
697         if (nmp->nm_readdirsize > nmp->nm_rsize)
698                 nmp->nm_readdirsize = nmp->nm_rsize;
699
700         if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
701                 nmp->nm_acregmin = argp->acregmin;
702         else
703                 nmp->nm_acregmin = NFS_MINATTRTIMO;
704         if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
705                 nmp->nm_acregmax = argp->acregmax;
706         else
707                 nmp->nm_acregmax = NFS_MAXATTRTIMO;
708         if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
709                 nmp->nm_acdirmin = argp->acdirmin;
710         else
711                 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
712         if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
713                 nmp->nm_acdirmax = argp->acdirmax;
714         else
715                 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
716         if (nmp->nm_acdirmin > nmp->nm_acdirmax)
717                 nmp->nm_acdirmin = nmp->nm_acdirmax;
718         if (nmp->nm_acregmin > nmp->nm_acregmax)
719                 nmp->nm_acregmin = nmp->nm_acregmax;
720
721         if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
722                 if (argp->maxgrouplist <= NFS_MAXGRPS)
723                         nmp->nm_numgrps = argp->maxgrouplist;
724                 else
725                         nmp->nm_numgrps = NFS_MAXGRPS;
726         }
727         if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
728                 if (argp->readahead <= NFS_MAXRAHEAD)
729                         nmp->nm_readahead = argp->readahead;
730                 else
731                         nmp->nm_readahead = NFS_MAXRAHEAD;
732         }
733         if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
734                 if (argp->wcommitsize < nmp->nm_wsize)
735                         nmp->nm_wcommitsize = nmp->nm_wsize;
736                 else
737                         nmp->nm_wcommitsize = argp->wcommitsize;
738         }
739         if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
740                 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
741                         nmp->nm_deadthresh = argp->deadthresh;
742                 else
743                         nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
744         }
745
746         adjsock |= ((nmp->nm_sotype != argp->sotype) ||
747                     (nmp->nm_soproto != argp->proto));
748         nmp->nm_sotype = argp->sotype;
749         nmp->nm_soproto = argp->proto;
750
751         if (nmp->nm_client && adjsock) {
752                 nfs_safedisconnect(nmp);
753                 if (nmp->nm_sotype == SOCK_DGRAM)
754                         while (nfs_connect(nmp)) {
755                                 printf("nfs_args: retrying connect\n");
756                                 (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
757                         }
758         }
759
760         if (hostname) {
761                 strlcpy(nmp->nm_hostname, hostname,
762                     sizeof(nmp->nm_hostname));
763                 p = strchr(nmp->nm_hostname, ':');
764                 if (p)
765                         *p = '\0';
766         }
767
768         if (vfs_getopt(mp->mnt_optnew, "sec",
769                 (void **) &secname, NULL) == 0) {
770                 nmp->nm_secflavor = nfs_sec_name_to_num(secname);
771         } else {
772                 nmp->nm_secflavor = AUTH_SYS;
773         }
774
775         if (vfs_getopt(mp->mnt_optnew, "principal",
776                 (void **) &principal, NULL) == 0) {
777                 strlcpy(nmp->nm_principal, principal,
778                     sizeof(nmp->nm_principal));
779         } else {
780                 snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
781                     "nfs@%s", nmp->nm_hostname);
782         }
783 }
784
785 static const char *nfs_opts[] = { "from", "nfs_args",
786     "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
787     "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
788     "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
789     "readahead", "readdirsize", "soft", "hard", "mntudp", "tcp", "udp",
790     "wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin",
791     "acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3",
792     "sec", "maxgroups", "principal", "negnametimeo", "nocto", "wcommitsize",
793     "nametimeo",
794     NULL };
795
796 /*
797  * VFS Operations.
798  *
799  * mount system call
800  * It seems a bit dumb to copyinstr() the host and path here and then
801  * bcopy() them in mountnfs(), but I wanted to detect errors before
802  * doing the sockargs() call because sockargs() allocates an mbuf and
803  * an error after that means that I have to release the mbuf.
804  */
805 /* ARGSUSED */
806 static int
807 nfs_mount(struct mount *mp)
808 {
809         struct nfs_args args = {
810             .version = NFS_ARGSVERSION,
811             .addr = NULL,
812             .addrlen = sizeof (struct sockaddr_in),
813             .sotype = SOCK_STREAM,
814             .proto = 0,
815             .fh = NULL,
816             .fhsize = 0,
817             .flags = NFSMNT_RESVPORT,
818             .wsize = NFS_WSIZE,
819             .rsize = NFS_RSIZE,
820             .readdirsize = NFS_READDIRSIZE,
821             .timeo = 10,
822             .retrans = NFS_RETRANS,
823             .maxgrouplist = NFS_MAXGRPS,
824             .readahead = NFS_DEFRAHEAD,
825             .wcommitsize = 0,                   /* was: NQ_DEFLEASE */
826             .deadthresh = NFS_MAXDEADTHRESH,    /* was: NQ_DEADTHRESH */
827             .hostname = NULL,
828             /* args version 4 */
829             .acregmin = NFS_MINATTRTIMO,
830             .acregmax = NFS_MAXATTRTIMO,
831             .acdirmin = NFS_MINDIRATTRTIMO,
832             .acdirmax = NFS_MAXDIRATTRTIMO,
833         };
834         int error, ret, has_nfs_args_opt;
835         int has_addr_opt, has_fh_opt, has_hostname_opt;
836         struct sockaddr *nam;
837         struct vnode *vp;
838         char hst[MNAMELEN];
839         size_t len;
840         u_char nfh[NFSX_V3FHMAX];
841         char *opt;
842         int nametimeo = NFS_DEFAULT_NAMETIMEO;
843         int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
844
845         has_nfs_args_opt = 0;
846         has_addr_opt = 0;
847         has_fh_opt = 0;
848         has_hostname_opt = 0;
849
850         if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
851                 error = EINVAL;
852                 goto out;
853         }
854
855         if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
856                 error = nfs_mountroot(mp);
857                 goto out;
858         }
859
860         /*
861          * The old mount_nfs program passed the struct nfs_args
862          * from userspace to kernel.  The new mount_nfs program
863          * passes string options via nmount() from userspace to kernel
864          * and we populate the struct nfs_args in the kernel.
865          */
866         if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
867                 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
868                     sizeof args);
869                 if (error)
870                         goto out;
871
872                 if (args.version != NFS_ARGSVERSION) {
873                         error = EPROGMISMATCH;
874                         goto out;
875                 }
876                 has_nfs_args_opt = 1;
877         }
878
879         if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
880                 args.flags |= NFSMNT_DUMBTIMR;
881         if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
882                 args.flags |= NFSMNT_NOCONN;
883         if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
884                 args.flags |= NFSMNT_NOCONN;
885         if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
886                 args.flags |= NFSMNT_NOLOCKD;
887         if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
888                 args.flags &= ~NFSMNT_NOLOCKD;
889         if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
890                 args.flags |= NFSMNT_INT;
891         if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
892                 args.flags |= NFSMNT_RDIRPLUS;
893         if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
894                 args.flags |= NFSMNT_RESVPORT;
895         if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
896                 args.flags &= ~NFSMNT_RESVPORT;
897         if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
898                 args.flags |= NFSMNT_SOFT;
899         if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
900                 args.flags &= ~NFSMNT_SOFT;
901         if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
902                 args.sotype = SOCK_DGRAM;
903         if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
904                 args.sotype = SOCK_DGRAM;
905         if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
906                 args.sotype = SOCK_STREAM;
907         if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
908                 args.flags |= NFSMNT_NFSV3;
909         if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
910                 args.flags |= NFSMNT_NOCTO;
911         if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
912                 if (opt == NULL) { 
913                         vfs_mount_error(mp, "illegal readdirsize");
914                         error = EINVAL;
915                         goto out;
916                 }
917                 ret = sscanf(opt, "%d", &args.readdirsize);
918                 if (ret != 1 || args.readdirsize <= 0) {
919                         vfs_mount_error(mp, "illegal readdirsize: %s",
920                             opt);
921                         error = EINVAL;
922                         goto out;
923                 }
924                 args.flags |= NFSMNT_READDIRSIZE;
925         }
926         if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
927                 if (opt == NULL) { 
928                         vfs_mount_error(mp, "illegal readahead");
929                         error = EINVAL;
930                         goto out;
931                 }
932                 ret = sscanf(opt, "%d", &args.readahead);
933                 if (ret != 1 || args.readahead <= 0) {
934                         vfs_mount_error(mp, "illegal readahead: %s",
935                             opt);
936                         error = EINVAL;
937                         goto out;
938                 }
939                 args.flags |= NFSMNT_READAHEAD;
940         }
941         if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
942                 if (opt == NULL) { 
943                         vfs_mount_error(mp, "illegal wsize");
944                         error = EINVAL;
945                         goto out;
946                 }
947                 ret = sscanf(opt, "%d", &args.wsize);
948                 if (ret != 1 || args.wsize <= 0) {
949                         vfs_mount_error(mp, "illegal wsize: %s",
950                             opt);
951                         error = EINVAL;
952                         goto out;
953                 }
954                 args.flags |= NFSMNT_WSIZE;
955         }
956         if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
957                 if (opt == NULL) { 
958                         vfs_mount_error(mp, "illegal rsize");
959                         error = EINVAL;
960                         goto out;
961                 }
962                 ret = sscanf(opt, "%d", &args.rsize);
963                 if (ret != 1 || args.rsize <= 0) {
964                         vfs_mount_error(mp, "illegal wsize: %s",
965                             opt);
966                         error = EINVAL;
967                         goto out;
968                 }
969                 args.flags |= NFSMNT_RSIZE;
970         }
971         if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
972                 if (opt == NULL) { 
973                         vfs_mount_error(mp, "illegal retrans");
974                         error = EINVAL;
975                         goto out;
976                 }
977                 ret = sscanf(opt, "%d", &args.retrans);
978                 if (ret != 1 || args.retrans <= 0) {
979                         vfs_mount_error(mp, "illegal retrans: %s",
980                             opt);
981                         error = EINVAL;
982                         goto out;
983                 }
984                 args.flags |= NFSMNT_RETRANS;
985         }
986         if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
987                 ret = sscanf(opt, "%d", &args.acregmin);
988                 if (ret != 1 || args.acregmin < 0) {
989                         vfs_mount_error(mp, "illegal acregmin: %s",
990                             opt);
991                         error = EINVAL;
992                         goto out;
993                 }
994                 args.flags |= NFSMNT_ACREGMIN;
995         }
996         if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
997                 ret = sscanf(opt, "%d", &args.acregmax);
998                 if (ret != 1 || args.acregmax < 0) {
999                         vfs_mount_error(mp, "illegal acregmax: %s",
1000                             opt);
1001                         error = EINVAL;
1002                         goto out;
1003                 }
1004                 args.flags |= NFSMNT_ACREGMAX;
1005         }
1006         if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
1007                 ret = sscanf(opt, "%d", &args.acdirmin);
1008                 if (ret != 1 || args.acdirmin < 0) {
1009                         vfs_mount_error(mp, "illegal acdirmin: %s",
1010                             opt);
1011                         error = EINVAL;
1012                         goto out;
1013                 }
1014                 args.flags |= NFSMNT_ACDIRMIN;
1015         }
1016         if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1017                 ret = sscanf(opt, "%d", &args.acdirmax);
1018                 if (ret != 1 || args.acdirmax < 0) {
1019                         vfs_mount_error(mp, "illegal acdirmax: %s",
1020                             opt);
1021                         error = EINVAL;
1022                         goto out;
1023                 }
1024                 args.flags |= NFSMNT_ACDIRMAX;
1025         }
1026         if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
1027                 ret = sscanf(opt, "%d", &args.wcommitsize);
1028                 if (ret != 1 || args.wcommitsize < 0) {
1029                         vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
1030                         error = EINVAL;
1031                         goto out;
1032                 }
1033                 args.flags |= NFSMNT_WCOMMITSIZE;
1034         }
1035         if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1036                 ret = sscanf(opt, "%d", &args.deadthresh);
1037                 if (ret != 1 || args.deadthresh <= 0) {
1038                         vfs_mount_error(mp, "illegal deadthresh: %s",
1039                             opt);
1040                         error = EINVAL;
1041                         goto out;
1042                 }
1043                 args.flags |= NFSMNT_DEADTHRESH;
1044         }
1045         if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1046                 ret = sscanf(opt, "%d", &args.timeo);
1047                 if (ret != 1 || args.timeo <= 0) {
1048                         vfs_mount_error(mp, "illegal timeout: %s",
1049                             opt);
1050                         error = EINVAL;
1051                         goto out;
1052                 }
1053                 args.flags |= NFSMNT_TIMEO;
1054         }
1055         if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1056                 ret = sscanf(opt, "%d", &args.maxgrouplist);
1057                 if (ret != 1 || args.maxgrouplist <= 0) {
1058                         vfs_mount_error(mp, "illegal maxgroups: %s",
1059                             opt);
1060                         error = EINVAL;
1061                         goto out;
1062                 }
1063                 args.flags |= NFSMNT_MAXGRPS;
1064         }
1065         if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
1066                 ret = sscanf(opt, "%d", &nametimeo);
1067                 if (ret != 1 || nametimeo < 0) {
1068                         vfs_mount_error(mp, "illegal nametimeo: %s", opt);
1069                         error = EINVAL;
1070                         goto out;
1071                 }
1072         }
1073         if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1074             == 0) {
1075                 ret = sscanf(opt, "%d", &negnametimeo);
1076                 if (ret != 1 || negnametimeo < 0) {
1077                         vfs_mount_error(mp, "illegal negnametimeo: %s",
1078                             opt);
1079                         error = EINVAL;
1080                         goto out;
1081                 }
1082         }
1083         if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1084                 &args.addrlen) == 0) {
1085                 has_addr_opt = 1;
1086                 if (args.addrlen > SOCK_MAXADDRLEN) {
1087                         error = ENAMETOOLONG;
1088                         goto out;
1089                 }
1090                 nam = malloc(args.addrlen, M_SONAME,
1091                     M_WAITOK);
1092                 bcopy(args.addr, nam, args.addrlen);
1093                 nam->sa_len = args.addrlen;
1094         }
1095         if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1096                 &args.fhsize) == 0) {
1097                 has_fh_opt = 1;
1098         }
1099         if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1100                 NULL) == 0) {
1101                 has_hostname_opt = 1;
1102         }
1103         if (args.hostname == NULL) {
1104                 vfs_mount_error(mp, "Invalid hostname");
1105                 error = EINVAL;
1106                 goto out;
1107         }
1108         if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1109                 vfs_mount_error(mp, "Bad file handle");
1110                 error = EINVAL;
1111                 goto out;
1112         }
1113
1114         if (mp->mnt_flag & MNT_UPDATE) {
1115                 struct nfsmount *nmp = VFSTONFS(mp);
1116
1117                 if (nmp == NULL) {
1118                         error = EIO;
1119                         goto out;
1120                 }
1121
1122                 /*
1123                  * If a change from TCP->UDP is done and there are thread(s)
1124                  * that have I/O RPC(s) in progress with a tranfer size
1125                  * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1126                  * hung, retrying the RPC(s) forever. Usually these threads
1127                  * will be seen doing an uninterruptible sleep on wait channel
1128                  * "newnfsreq" (truncated to "newnfsre" by procstat).
1129                  */
1130                 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1131                         tprintf(curthread->td_proc, LOG_WARNING,
1132         "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1133
1134                 /*
1135                  * When doing an update, we can't change from or to
1136                  * v3, switch lockd strategies or change cookie translation
1137                  */
1138                 args.flags = (args.flags &
1139                     ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1140                     (nmp->nm_flag &
1141                         (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1142                 nfs_decode_args(mp, nmp, &args, NULL);
1143                 goto out;
1144         }
1145
1146         /*
1147          * Make the nfs_ip_paranoia sysctl serve as the default connection
1148          * or no-connection mode for those protocols that support 
1149          * no-connection mode (the flag will be cleared later for protocols
1150          * that do not support no-connection mode).  This will allow a client
1151          * to receive replies from a different IP then the request was
1152          * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
1153          * not 0.
1154          */
1155         if (nfs_ip_paranoia == 0)
1156                 args.flags |= NFSMNT_NOCONN;
1157
1158         if (has_nfs_args_opt) {
1159                 /*
1160                  * In the 'nfs_args' case, the pointers in the args
1161                  * structure are in userland - we copy them in here.
1162                  */
1163                 if (!has_fh_opt) {
1164                         error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1165                             args.fhsize);
1166                         if (error) {
1167                                 goto out;
1168                         }
1169                         args.fh = nfh;
1170                 }
1171                 if (!has_hostname_opt) {
1172                         error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1173                         if (error) {
1174                                 goto out;
1175                         }
1176                         bzero(&hst[len], MNAMELEN - len);
1177                         args.hostname = hst;
1178                 }
1179                 if (!has_addr_opt) {
1180                         /* sockargs() call must be after above copyin() calls */
1181                         error = getsockaddr(&nam, (caddr_t)args.addr,
1182                             args.addrlen);
1183                         if (error) {
1184                                 goto out;
1185                         }
1186                 }
1187         } else if (has_addr_opt == 0) {
1188                 vfs_mount_error(mp, "No server address");
1189                 error = EINVAL;
1190                 goto out;
1191         }
1192         error = mountnfs(&args, mp, nam, args.hostname, &vp,
1193             curthread->td_ucred, nametimeo, negnametimeo);
1194 out:
1195         if (!error) {
1196                 MNT_ILOCK(mp);
1197                 mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
1198                 MNT_IUNLOCK(mp);
1199         }
1200         return (error);
1201 }
1202
1203
1204 /*
1205  * VFS Operations.
1206  *
1207  * mount system call
1208  * It seems a bit dumb to copyinstr() the host and path here and then
1209  * bcopy() them in mountnfs(), but I wanted to detect errors before
1210  * doing the sockargs() call because sockargs() allocates an mbuf and
1211  * an error after that means that I have to release the mbuf.
1212  */
1213 /* ARGSUSED */
1214 static int
1215 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1216 {
1217         int error;
1218         struct nfs_args args;
1219
1220         error = copyin(data, &args, sizeof (struct nfs_args));
1221         if (error)
1222                 return error;
1223
1224         ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1225
1226         error = kernel_mount(ma, flags);
1227         return (error);
1228 }
1229
1230 /*
1231  * Common code for mount and mountroot
1232  */
1233 static int
1234 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1235     char *hst, struct vnode **vpp, struct ucred *cred, int nametimeo,
1236     int negnametimeo)
1237 {
1238         struct nfsmount *nmp;
1239         struct nfsnode *np;
1240         int error;
1241         struct vattr attrs;
1242
1243         if (mp->mnt_flag & MNT_UPDATE) {
1244                 nmp = VFSTONFS(mp);
1245                 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1246                 free(nam, M_SONAME);
1247                 return (0);
1248         } else {
1249                 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1250                 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1251                 TAILQ_INIT(&nmp->nm_bufq);
1252                 mp->mnt_data = nmp;
1253                 nmp->nm_getinfo = nfs_getnlminfo;
1254                 nmp->nm_vinvalbuf = nfs_vinvalbuf;
1255         }
1256         vfs_getnewfsid(mp);
1257         nmp->nm_mountp = mp;
1258         mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);                 
1259
1260         /*
1261          * V2 can only handle 32 bit filesizes.  A 4GB-1 limit may be too
1262          * high, depending on whether we end up with negative offsets in
1263          * the client or server somewhere.  2GB-1 may be safer.
1264          *
1265          * For V3, nfs_fsinfo will adjust this as necessary.  Assume maximum
1266          * that we can handle until we find out otherwise.
1267          */
1268         if ((argp->flags & NFSMNT_NFSV3) == 0)
1269                 nmp->nm_maxfilesize = 0xffffffffLL;
1270         else
1271                 nmp->nm_maxfilesize = OFF_MAX;
1272
1273         nmp->nm_timeo = NFS_TIMEO;
1274         nmp->nm_retry = NFS_RETRANS;
1275         if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1276                 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1277         } else {
1278                 nmp->nm_wsize = NFS_WSIZE;
1279                 nmp->nm_rsize = NFS_RSIZE;
1280         }
1281         nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1282         nmp->nm_readdirsize = NFS_READDIRSIZE;
1283         nmp->nm_numgrps = NFS_MAXGRPS;
1284         nmp->nm_readahead = NFS_DEFRAHEAD;
1285         nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1286         nmp->nm_nametimeo = nametimeo;
1287         nmp->nm_negnametimeo = negnametimeo;
1288         nmp->nm_tprintf_delay = nfs_tprintf_delay;
1289         if (nmp->nm_tprintf_delay < 0)
1290                 nmp->nm_tprintf_delay = 0;
1291         nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1292         if (nmp->nm_tprintf_initial_delay < 0)
1293                 nmp->nm_tprintf_initial_delay = 0;
1294         nmp->nm_fhsize = argp->fhsize;
1295         bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1296         bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1297         nmp->nm_nam = nam;
1298         /* Set up the sockets and per-host congestion */
1299         nmp->nm_sotype = argp->sotype;
1300         nmp->nm_soproto = argp->proto;
1301         nmp->nm_rpcops = &nfs_rpcops;
1302
1303         nfs_decode_args(mp, nmp, argp, hst);
1304
1305         /*
1306          * For Connection based sockets (TCP,...) defer the connect until
1307          * the first request, in case the server is not responding.
1308          */
1309         if (nmp->nm_sotype == SOCK_DGRAM &&
1310                 (error = nfs_connect(nmp)))
1311                 goto bad;
1312
1313         /*
1314          * This is silly, but it has to be set so that vinifod() works.
1315          * We do not want to do an nfs_statfs() here since we can get
1316          * stuck on a dead server and we are holding a lock on the mount
1317          * point.
1318          */
1319         mtx_lock(&nmp->nm_mtx);
1320         mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1321         mtx_unlock(&nmp->nm_mtx);
1322         /*
1323          * A reference count is needed on the nfsnode representing the
1324          * remote root.  If this object is not persistent, then backward
1325          * traversals of the mount point (i.e. "..") will not work if
1326          * the nfsnode gets flushed out of the cache. Ufs does not have
1327          * this problem, because one can identify root inodes by their
1328          * number == ROOTINO (2).
1329          */
1330         error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1331         if (error)
1332                 goto bad;
1333         *vpp = NFSTOV(np);
1334
1335         /*
1336          * Get file attributes and transfer parameters for the
1337          * mountpoint.  This has the side effect of filling in
1338          * (*vpp)->v_type with the correct value.
1339          */
1340         if (argp->flags & NFSMNT_NFSV3)
1341                 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1342         else
1343                 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1344
1345         /*
1346          * Lose the lock but keep the ref.
1347          */
1348         VOP_UNLOCK(*vpp, 0);
1349
1350         return (0);
1351 bad:
1352         nfs_disconnect(nmp);
1353         mtx_destroy(&nmp->nm_mtx);
1354         uma_zfree(nfsmount_zone, nmp);
1355         free(nam, M_SONAME);
1356         return (error);
1357 }
1358
1359 /*
1360  * unmount system call
1361  */
1362 static int
1363 nfs_unmount(struct mount *mp, int mntflags)
1364 {
1365         struct nfsmount *nmp;
1366         int error, flags = 0, i;
1367
1368         if (mntflags & MNT_FORCE)
1369                 flags |= FORCECLOSE;
1370         nmp = VFSTONFS(mp);
1371         /*
1372          * Goes something like this..
1373          * - Call vflush() to clear out vnodes for this filesystem
1374          * - Close the socket
1375          * - Free up the data structures
1376          */
1377         /* In the forced case, cancel any outstanding requests. */
1378         if (flags & FORCECLOSE) {
1379                 error = nfs_nmcancelreqs(nmp);
1380                 if (error)
1381                         goto out;
1382         }
1383         /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1384         error = vflush(mp, 1, flags, curthread);
1385         if (error)
1386                 goto out;
1387
1388         /*
1389          * We are now committed to the unmount.
1390          */
1391         /* Make sure no nfsiods are assigned to this mount. */
1392         mtx_lock(&nfs_iod_mtx);
1393         for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1394                 if (nfs_iodmount[i] == nmp) {
1395                         nfs_iodwant[i] = NFSIOD_AVAILABLE;
1396                         nfs_iodmount[i] = NULL;
1397                 }
1398         mtx_unlock(&nfs_iod_mtx);
1399         nfs_disconnect(nmp);
1400         free(nmp->nm_nam, M_SONAME);
1401
1402         mtx_destroy(&nmp->nm_mtx);
1403         uma_zfree(nfsmount_zone, nmp);
1404 out:
1405         return (error);
1406 }
1407
1408 /*
1409  * Return root of a filesystem
1410  */
1411 static int
1412 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1413 {
1414         struct vnode *vp;
1415         struct nfsmount *nmp;
1416         struct nfsnode *np;
1417         int error;
1418
1419         nmp = VFSTONFS(mp);
1420         error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1421         if (error)
1422                 return error;
1423         vp = NFSTOV(np);
1424         /*
1425          * Get transfer parameters and attributes for root vnode once.
1426          */
1427         mtx_lock(&nmp->nm_mtx);
1428         if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1429             (nmp->nm_flag & NFSMNT_NFSV3)) {
1430                 mtx_unlock(&nmp->nm_mtx);
1431                 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1432         } else 
1433                 mtx_unlock(&nmp->nm_mtx);
1434         if (vp->v_type == VNON)
1435             vp->v_type = VDIR;
1436         vp->v_vflag |= VV_ROOT;
1437         *vpp = vp;
1438         return (0);
1439 }
1440
1441 /*
1442  * Flush out the buffer cache
1443  */
1444 /* ARGSUSED */
1445 static int
1446 nfs_sync(struct mount *mp, int waitfor)
1447 {
1448         struct vnode *vp, *mvp;
1449         struct thread *td;
1450         int error, allerror = 0;
1451
1452         td = curthread;
1453
1454         MNT_ILOCK(mp);
1455         /*
1456          * If a forced dismount is in progress, return from here so that
1457          * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1458          * calling VFS_UNMOUNT().
1459          */
1460         if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1461                 MNT_IUNLOCK(mp);
1462                 return (EBADF);
1463         }
1464         MNT_IUNLOCK(mp);
1465
1466         /*
1467          * Force stale buffer cache information to be flushed.
1468          */
1469 loop:
1470         MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1471                 /* XXX Racy bv_cnt check. */
1472                 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1473                     waitfor == MNT_LAZY) {
1474                         VI_UNLOCK(vp);
1475                         continue;
1476                 }
1477                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1478                         MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1479                         goto loop;
1480                 }
1481                 error = VOP_FSYNC(vp, waitfor, td);
1482                 if (error)
1483                         allerror = error;
1484                 VOP_UNLOCK(vp, 0);
1485                 vrele(vp);
1486         }
1487         return (allerror);
1488 }
1489
1490 static int
1491 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1492 {
1493         struct nfsmount *nmp = VFSTONFS(mp);
1494         struct vfsquery vq;
1495         int error;
1496
1497         bzero(&vq, sizeof(vq));
1498         switch (op) {
1499 #if 0
1500         case VFS_CTL_NOLOCKS:
1501                 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1502                 if (req->oldptr != NULL) {
1503                         error = SYSCTL_OUT(req, &val, sizeof(val));
1504                         if (error)
1505                                 return (error);
1506                 }
1507                 if (req->newptr != NULL) {
1508                         error = SYSCTL_IN(req, &val, sizeof(val));
1509                         if (error)
1510                                 return (error);
1511                         if (val)
1512                                 nmp->nm_flag |= NFSMNT_NOLOCKS;
1513                         else
1514                                 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1515                 }
1516                 break;
1517 #endif
1518         case VFS_CTL_QUERY:
1519                 mtx_lock(&nmp->nm_mtx);
1520                 if (nmp->nm_state & NFSSTA_TIMEO)
1521                         vq.vq_flags |= VQ_NOTRESP;
1522                 mtx_unlock(&nmp->nm_mtx);
1523 #if 0
1524                 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1525                     (nmp->nm_state & NFSSTA_LOCKTIMEO))
1526                         vq.vq_flags |= VQ_NOTRESPLOCK;
1527 #endif
1528                 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1529                 break;
1530         case VFS_CTL_TIMEO:
1531                 if (req->oldptr != NULL) {
1532                         error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1533                             sizeof(nmp->nm_tprintf_initial_delay));
1534                         if (error)
1535                                 return (error);
1536                 }
1537                 if (req->newptr != NULL) {
1538                         error = vfs_suser(mp, req->td);
1539                         if (error)
1540                                 return (error);
1541                         error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1542                             sizeof(nmp->nm_tprintf_initial_delay));
1543                         if (error)
1544                                 return (error);
1545                         if (nmp->nm_tprintf_initial_delay < 0)
1546                                 nmp->nm_tprintf_initial_delay = 0;
1547                 }
1548                 break;
1549         default:
1550                 return (ENOTSUP);
1551         }
1552         return (0);
1553 }
1554
1555 /*
1556  * Extract the information needed by the nlm from the nfs vnode.
1557  */
1558 static void
1559 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1560     struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1561     struct timeval *timeop)
1562 {
1563         struct nfsmount *nmp;
1564         struct nfsnode *np = VTONFS(vp);
1565
1566         nmp = VFSTONFS(vp->v_mount);
1567         if (fhlenp != NULL)
1568                 *fhlenp = (size_t)np->n_fhsize;
1569         if (fhp != NULL)
1570                 bcopy(np->n_fhp, fhp, np->n_fhsize);
1571         if (sp != NULL)
1572                 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1573         if (is_v3p != NULL)
1574                 *is_v3p = NFS_ISV3(vp);
1575         if (sizep != NULL)
1576                 *sizep = np->n_size;
1577         if (timeop != NULL) {
1578                 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1579                 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1580         }
1581 }
1582