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