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