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