nfs_clvfsops.c revision 1.1.1.1.10.2 1 1.1.1.1.10.2 tls /* $NetBSD: nfs_clvfsops.c,v 1.1.1.1.10.2 2014/08/20 00:04:26 tls Exp $ */
2 1.1.1.1.10.2 tls /*-
3 1.1.1.1.10.2 tls * Copyright (c) 1989, 1993, 1995
4 1.1.1.1.10.2 tls * The Regents of the University of California. All rights reserved.
5 1.1.1.1.10.2 tls *
6 1.1.1.1.10.2 tls * This code is derived from software contributed to Berkeley by
7 1.1.1.1.10.2 tls * Rick Macklem at The University of Guelph.
8 1.1.1.1.10.2 tls *
9 1.1.1.1.10.2 tls * Redistribution and use in source and binary forms, with or without
10 1.1.1.1.10.2 tls * modification, are permitted provided that the following conditions
11 1.1.1.1.10.2 tls * are met:
12 1.1.1.1.10.2 tls * 1. Redistributions of source code must retain the above copyright
13 1.1.1.1.10.2 tls * notice, this list of conditions and the following disclaimer.
14 1.1.1.1.10.2 tls * 2. Redistributions in binary form must reproduce the above copyright
15 1.1.1.1.10.2 tls * notice, this list of conditions and the following disclaimer in the
16 1.1.1.1.10.2 tls * documentation and/or other materials provided with the distribution.
17 1.1.1.1.10.2 tls * 4. Neither the name of the University nor the names of its contributors
18 1.1.1.1.10.2 tls * may be used to endorse or promote products derived from this software
19 1.1.1.1.10.2 tls * without specific prior written permission.
20 1.1.1.1.10.2 tls *
21 1.1.1.1.10.2 tls * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.1.1.1.10.2 tls * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.1.1.1.10.2 tls * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1.1.1.10.2 tls * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.1.1.1.10.2 tls * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1.1.1.10.2 tls * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1.1.1.10.2 tls * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1.1.1.10.2 tls * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1.1.1.10.2 tls * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1.1.1.10.2 tls * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1.1.1.10.2 tls * SUCH DAMAGE.
32 1.1.1.1.10.2 tls *
33 1.1.1.1.10.2 tls * from nfs_vfsops.c 8.12 (Berkeley) 5/20/95
34 1.1.1.1.10.2 tls */
35 1.1.1.1.10.2 tls
36 1.1.1.1.10.2 tls #include <sys/cdefs.h>
37 1.1.1.1.10.2 tls /* __FBSDID("FreeBSD: head/sys/fs/nfsclient/nfs_clvfsops.c 255136 2013-09-01 23:02:59Z rmacklem "); */
38 1.1.1.1.10.2 tls __RCSID("$NetBSD: nfs_clvfsops.c,v 1.1.1.1.10.2 2014/08/20 00:04:26 tls Exp $");
39 1.1.1.1.10.2 tls
40 1.1.1.1.10.2 tls
41 1.1.1.1.10.2 tls #include "opt_bootp.h"
42 1.1.1.1.10.2 tls #include "opt_nfsroot.h"
43 1.1.1.1.10.2 tls
44 1.1.1.1.10.2 tls #include <sys/param.h>
45 1.1.1.1.10.2 tls #include <sys/systm.h>
46 1.1.1.1.10.2 tls #include <sys/kernel.h>
47 1.1.1.1.10.2 tls #include <sys/bio.h>
48 1.1.1.1.10.2 tls #include <sys/buf.h>
49 1.1.1.1.10.2 tls #include <sys/clock.h>
50 1.1.1.1.10.2 tls #include <sys/jail.h>
51 1.1.1.1.10.2 tls #include <sys/limits.h>
52 1.1.1.1.10.2 tls #include <sys/lock.h>
53 1.1.1.1.10.2 tls #include <sys/malloc.h>
54 1.1.1.1.10.2 tls #include <sys/mbuf.h>
55 1.1.1.1.10.2 tls #include <sys/module.h>
56 1.1.1.1.10.2 tls #include <sys/mount.h>
57 1.1.1.1.10.2 tls #include <sys/proc.h>
58 1.1.1.1.10.2 tls #include <sys/socket.h>
59 1.1.1.1.10.2 tls #include <sys/socketvar.h>
60 1.1.1.1.10.2 tls #include <sys/sockio.h>
61 1.1.1.1.10.2 tls #include <sys/sysctl.h>
62 1.1.1.1.10.2 tls #include <sys/vnode.h>
63 1.1.1.1.10.2 tls #include <sys/signalvar.h>
64 1.1.1.1.10.2 tls
65 1.1.1.1.10.2 tls #include <vm/vm.h>
66 1.1.1.1.10.2 tls #include <vm/vm_extern.h>
67 1.1.1.1.10.2 tls #include <vm/uma.h>
68 1.1.1.1.10.2 tls
69 1.1.1.1.10.2 tls #include <net/if.h>
70 1.1.1.1.10.2 tls #include <net/route.h>
71 1.1.1.1.10.2 tls #include <netinet/in.h>
72 1.1.1.1.10.2 tls
73 1.1.1.1.10.2 tls #include <fs/nfs/nfsport.h>
74 1.1.1.1.10.2 tls #include <fs/nfsclient/nfsnode.h>
75 1.1.1.1.10.2 tls #include <fs/nfsclient/nfsmount.h>
76 1.1.1.1.10.2 tls #include <fs/nfsclient/nfs.h>
77 1.1.1.1.10.2 tls #include <nfs/nfsdiskless.h>
78 1.1.1.1.10.2 tls
79 1.1.1.1.10.2 tls FEATURE(nfscl, "NFSv4 client");
80 1.1.1.1.10.2 tls
81 1.1.1.1.10.2 tls extern int nfscl_ticks;
82 1.1.1.1.10.2 tls extern struct timeval nfsboottime;
83 1.1.1.1.10.2 tls extern struct nfsstats newnfsstats;
84 1.1.1.1.10.2 tls extern int nfsrv_useacl;
85 1.1.1.1.10.2 tls extern int nfscl_debuglevel;
86 1.1.1.1.10.2 tls extern enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON];
87 1.1.1.1.10.2 tls extern struct nfsmount *ncl_iodmount[NFS_MAXASYNCDAEMON];
88 1.1.1.1.10.2 tls extern struct mtx ncl_iod_mutex;
89 1.1.1.1.10.2 tls NFSCLSTATEMUTEX;
90 1.1.1.1.10.2 tls
91 1.1.1.1.10.2 tls MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
92 1.1.1.1.10.2 tls MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
93 1.1.1.1.10.2 tls
94 1.1.1.1.10.2 tls SYSCTL_DECL(_vfs_nfs);
95 1.1.1.1.10.2 tls static int nfs_ip_paranoia = 1;
96 1.1.1.1.10.2 tls SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
97 1.1.1.1.10.2 tls &nfs_ip_paranoia, 0, "");
98 1.1.1.1.10.2 tls static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
99 1.1.1.1.10.2 tls SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
100 1.1.1.1.10.2 tls downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
101 1.1.1.1.10.2 tls /* how long between console messages "nfs server foo not responding" */
102 1.1.1.1.10.2 tls static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
103 1.1.1.1.10.2 tls SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
104 1.1.1.1.10.2 tls downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
105 1.1.1.1.10.2 tls
106 1.1.1.1.10.2 tls static int nfs_mountroot(struct mount *);
107 1.1.1.1.10.2 tls static void nfs_sec_name(char *, int *);
108 1.1.1.1.10.2 tls static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
109 1.1.1.1.10.2 tls struct nfs_args *argp, const char *, struct ucred *,
110 1.1.1.1.10.2 tls struct thread *);
111 1.1.1.1.10.2 tls static int mountnfs(struct nfs_args *, struct mount *,
112 1.1.1.1.10.2 tls struct sockaddr *, char *, u_char *, int, u_char *, int,
113 1.1.1.1.10.2 tls u_char *, int, struct vnode **, struct ucred *,
114 1.1.1.1.10.2 tls struct thread *, int, int, int);
115 1.1.1.1.10.2 tls static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
116 1.1.1.1.10.2 tls struct sockaddr_storage *, int *, off_t *,
117 1.1.1.1.10.2 tls struct timeval *);
118 1.1.1.1.10.2 tls static vfs_mount_t nfs_mount;
119 1.1.1.1.10.2 tls static vfs_cmount_t nfs_cmount;
120 1.1.1.1.10.2 tls static vfs_unmount_t nfs_unmount;
121 1.1.1.1.10.2 tls static vfs_root_t nfs_root;
122 1.1.1.1.10.2 tls static vfs_statfs_t nfs_statfs;
123 1.1.1.1.10.2 tls static vfs_sync_t nfs_sync;
124 1.1.1.1.10.2 tls static vfs_sysctl_t nfs_sysctl;
125 1.1.1.1.10.2 tls static vfs_purge_t nfs_purge;
126 1.1.1.1.10.2 tls
127 1.1.1.1.10.2 tls /*
128 1.1.1.1.10.2 tls * nfs vfs operations.
129 1.1.1.1.10.2 tls */
130 1.1.1.1.10.2 tls static struct vfsops nfs_vfsops = {
131 1.1.1.1.10.2 tls .vfs_init = ncl_init,
132 1.1.1.1.10.2 tls .vfs_mount = nfs_mount,
133 1.1.1.1.10.2 tls .vfs_cmount = nfs_cmount,
134 1.1.1.1.10.2 tls .vfs_root = nfs_root,
135 1.1.1.1.10.2 tls .vfs_statfs = nfs_statfs,
136 1.1.1.1.10.2 tls .vfs_sync = nfs_sync,
137 1.1.1.1.10.2 tls .vfs_uninit = ncl_uninit,
138 1.1.1.1.10.2 tls .vfs_unmount = nfs_unmount,
139 1.1.1.1.10.2 tls .vfs_sysctl = nfs_sysctl,
140 1.1.1.1.10.2 tls .vfs_purge = nfs_purge,
141 1.1.1.1.10.2 tls };
142 1.1.1.1.10.2 tls VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY);
143 1.1.1.1.10.2 tls
144 1.1.1.1.10.2 tls /* So that loader and kldload(2) can find us, wherever we are.. */
145 1.1.1.1.10.2 tls MODULE_VERSION(nfs, 1);
146 1.1.1.1.10.2 tls MODULE_DEPEND(nfs, nfscommon, 1, 1, 1);
147 1.1.1.1.10.2 tls MODULE_DEPEND(nfs, krpc, 1, 1, 1);
148 1.1.1.1.10.2 tls MODULE_DEPEND(nfs, nfssvc, 1, 1, 1);
149 1.1.1.1.10.2 tls MODULE_DEPEND(nfs, nfslock, 1, 1, 1);
150 1.1.1.1.10.2 tls
151 1.1.1.1.10.2 tls /*
152 1.1.1.1.10.2 tls * This structure is now defined in sys/nfs/nfs_diskless.c so that it
153 1.1.1.1.10.2 tls * can be shared by both NFS clients. It is declared here so that it
154 1.1.1.1.10.2 tls * will be defined for kernels built without NFS_ROOT, although it
155 1.1.1.1.10.2 tls * isn't used in that case.
156 1.1.1.1.10.2 tls */
157 1.1.1.1.10.2 tls #if !defined(NFS_ROOT) && !defined(NFSCLIENT)
158 1.1.1.1.10.2 tls struct nfs_diskless nfs_diskless = { { { 0 } } };
159 1.1.1.1.10.2 tls struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
160 1.1.1.1.10.2 tls int nfs_diskless_valid = 0;
161 1.1.1.1.10.2 tls #endif
162 1.1.1.1.10.2 tls
163 1.1.1.1.10.2 tls SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
164 1.1.1.1.10.2 tls &nfs_diskless_valid, 0,
165 1.1.1.1.10.2 tls "Has the diskless struct been filled correctly");
166 1.1.1.1.10.2 tls
167 1.1.1.1.10.2 tls SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
168 1.1.1.1.10.2 tls nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
169 1.1.1.1.10.2 tls
170 1.1.1.1.10.2 tls SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
171 1.1.1.1.10.2 tls &nfsv3_diskless.root_saddr, sizeof(nfsv3_diskless.root_saddr),
172 1.1.1.1.10.2 tls "%Ssockaddr_in", "Diskless root nfs address");
173 1.1.1.1.10.2 tls
174 1.1.1.1.10.2 tls
175 1.1.1.1.10.2 tls void newnfsargs_ntoh(struct nfs_args *);
176 1.1.1.1.10.2 tls static int nfs_mountdiskless(char *,
177 1.1.1.1.10.2 tls struct sockaddr_in *, struct nfs_args *,
178 1.1.1.1.10.2 tls struct thread *, struct vnode **, struct mount *);
179 1.1.1.1.10.2 tls static void nfs_convert_diskless(void);
180 1.1.1.1.10.2 tls static void nfs_convert_oargs(struct nfs_args *args,
181 1.1.1.1.10.2 tls struct onfs_args *oargs);
182 1.1.1.1.10.2 tls
183 1.1.1.1.10.2 tls int
184 1.1.1.1.10.2 tls newnfs_iosize(struct nfsmount *nmp)
185 1.1.1.1.10.2 tls {
186 1.1.1.1.10.2 tls int iosize, maxio;
187 1.1.1.1.10.2 tls
188 1.1.1.1.10.2 tls /* First, set the upper limit for iosize */
189 1.1.1.1.10.2 tls if (nmp->nm_flag & NFSMNT_NFSV4) {
190 1.1.1.1.10.2 tls maxio = NFS_MAXBSIZE;
191 1.1.1.1.10.2 tls } else if (nmp->nm_flag & NFSMNT_NFSV3) {
192 1.1.1.1.10.2 tls if (nmp->nm_sotype == SOCK_DGRAM)
193 1.1.1.1.10.2 tls maxio = NFS_MAXDGRAMDATA;
194 1.1.1.1.10.2 tls else
195 1.1.1.1.10.2 tls maxio = NFS_MAXBSIZE;
196 1.1.1.1.10.2 tls } else {
197 1.1.1.1.10.2 tls maxio = NFS_V2MAXDATA;
198 1.1.1.1.10.2 tls }
199 1.1.1.1.10.2 tls if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
200 1.1.1.1.10.2 tls nmp->nm_rsize = maxio;
201 1.1.1.1.10.2 tls if (nmp->nm_rsize > MAXBSIZE)
202 1.1.1.1.10.2 tls nmp->nm_rsize = MAXBSIZE;
203 1.1.1.1.10.2 tls if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
204 1.1.1.1.10.2 tls nmp->nm_readdirsize = maxio;
205 1.1.1.1.10.2 tls if (nmp->nm_readdirsize > nmp->nm_rsize)
206 1.1.1.1.10.2 tls nmp->nm_readdirsize = nmp->nm_rsize;
207 1.1.1.1.10.2 tls if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
208 1.1.1.1.10.2 tls nmp->nm_wsize = maxio;
209 1.1.1.1.10.2 tls if (nmp->nm_wsize > MAXBSIZE)
210 1.1.1.1.10.2 tls nmp->nm_wsize = MAXBSIZE;
211 1.1.1.1.10.2 tls
212 1.1.1.1.10.2 tls /*
213 1.1.1.1.10.2 tls * Calculate the size used for io buffers. Use the larger
214 1.1.1.1.10.2 tls * of the two sizes to minimise nfs requests but make sure
215 1.1.1.1.10.2 tls * that it is at least one VM page to avoid wasting buffer
216 1.1.1.1.10.2 tls * space.
217 1.1.1.1.10.2 tls */
218 1.1.1.1.10.2 tls iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
219 1.1.1.1.10.2 tls iosize = imax(iosize, PAGE_SIZE);
220 1.1.1.1.10.2 tls nmp->nm_mountp->mnt_stat.f_iosize = iosize;
221 1.1.1.1.10.2 tls return (iosize);
222 1.1.1.1.10.2 tls }
223 1.1.1.1.10.2 tls
224 1.1.1.1.10.2 tls static void
225 1.1.1.1.10.2 tls nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
226 1.1.1.1.10.2 tls {
227 1.1.1.1.10.2 tls
228 1.1.1.1.10.2 tls args->version = NFS_ARGSVERSION;
229 1.1.1.1.10.2 tls args->addr = oargs->addr;
230 1.1.1.1.10.2 tls args->addrlen = oargs->addrlen;
231 1.1.1.1.10.2 tls args->sotype = oargs->sotype;
232 1.1.1.1.10.2 tls args->proto = oargs->proto;
233 1.1.1.1.10.2 tls args->fh = oargs->fh;
234 1.1.1.1.10.2 tls args->fhsize = oargs->fhsize;
235 1.1.1.1.10.2 tls args->flags = oargs->flags;
236 1.1.1.1.10.2 tls args->wsize = oargs->wsize;
237 1.1.1.1.10.2 tls args->rsize = oargs->rsize;
238 1.1.1.1.10.2 tls args->readdirsize = oargs->readdirsize;
239 1.1.1.1.10.2 tls args->timeo = oargs->timeo;
240 1.1.1.1.10.2 tls args->retrans = oargs->retrans;
241 1.1.1.1.10.2 tls args->readahead = oargs->readahead;
242 1.1.1.1.10.2 tls args->hostname = oargs->hostname;
243 1.1.1.1.10.2 tls }
244 1.1.1.1.10.2 tls
245 1.1.1.1.10.2 tls static void
246 1.1.1.1.10.2 tls nfs_convert_diskless(void)
247 1.1.1.1.10.2 tls {
248 1.1.1.1.10.2 tls
249 1.1.1.1.10.2 tls bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
250 1.1.1.1.10.2 tls sizeof(struct ifaliasreq));
251 1.1.1.1.10.2 tls bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
252 1.1.1.1.10.2 tls sizeof(struct sockaddr_in));
253 1.1.1.1.10.2 tls nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
254 1.1.1.1.10.2 tls if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
255 1.1.1.1.10.2 tls nfsv3_diskless.root_fhsize = NFSX_MYFH;
256 1.1.1.1.10.2 tls bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_MYFH);
257 1.1.1.1.10.2 tls } else {
258 1.1.1.1.10.2 tls nfsv3_diskless.root_fhsize = NFSX_V2FH;
259 1.1.1.1.10.2 tls bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
260 1.1.1.1.10.2 tls }
261 1.1.1.1.10.2 tls bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
262 1.1.1.1.10.2 tls sizeof(struct sockaddr_in));
263 1.1.1.1.10.2 tls bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
264 1.1.1.1.10.2 tls nfsv3_diskless.root_time = nfs_diskless.root_time;
265 1.1.1.1.10.2 tls bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
266 1.1.1.1.10.2 tls MAXHOSTNAMELEN);
267 1.1.1.1.10.2 tls nfs_diskless_valid = 3;
268 1.1.1.1.10.2 tls }
269 1.1.1.1.10.2 tls
270 1.1.1.1.10.2 tls /*
271 1.1.1.1.10.2 tls * nfs statfs call
272 1.1.1.1.10.2 tls */
273 1.1.1.1.10.2 tls static int
274 1.1.1.1.10.2 tls nfs_statfs(struct mount *mp, struct statfs *sbp)
275 1.1.1.1.10.2 tls {
276 1.1.1.1.10.2 tls struct vnode *vp;
277 1.1.1.1.10.2 tls struct thread *td;
278 1.1.1.1.10.2 tls struct nfsmount *nmp = VFSTONFS(mp);
279 1.1.1.1.10.2 tls struct nfsvattr nfsva;
280 1.1.1.1.10.2 tls struct nfsfsinfo fs;
281 1.1.1.1.10.2 tls struct nfsstatfs sb;
282 1.1.1.1.10.2 tls int error = 0, attrflag, gotfsinfo = 0, ret;
283 1.1.1.1.10.2 tls struct nfsnode *np;
284 1.1.1.1.10.2 tls
285 1.1.1.1.10.2 tls td = curthread;
286 1.1.1.1.10.2 tls
287 1.1.1.1.10.2 tls error = vfs_busy(mp, MBF_NOWAIT);
288 1.1.1.1.10.2 tls if (error)
289 1.1.1.1.10.2 tls return (error);
290 1.1.1.1.10.2 tls error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
291 1.1.1.1.10.2 tls if (error) {
292 1.1.1.1.10.2 tls vfs_unbusy(mp);
293 1.1.1.1.10.2 tls return (error);
294 1.1.1.1.10.2 tls }
295 1.1.1.1.10.2 tls vp = NFSTOV(np);
296 1.1.1.1.10.2 tls mtx_lock(&nmp->nm_mtx);
297 1.1.1.1.10.2 tls if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
298 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
299 1.1.1.1.10.2 tls error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
300 1.1.1.1.10.2 tls &attrflag, NULL);
301 1.1.1.1.10.2 tls if (!error)
302 1.1.1.1.10.2 tls gotfsinfo = 1;
303 1.1.1.1.10.2 tls } else
304 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
305 1.1.1.1.10.2 tls if (!error)
306 1.1.1.1.10.2 tls error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
307 1.1.1.1.10.2 tls &attrflag, NULL);
308 1.1.1.1.10.2 tls if (error != 0)
309 1.1.1.1.10.2 tls NFSCL_DEBUG(2, "statfs=%d\n", error);
310 1.1.1.1.10.2 tls if (attrflag == 0) {
311 1.1.1.1.10.2 tls ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
312 1.1.1.1.10.2 tls td->td_ucred, td, &nfsva, NULL, NULL);
313 1.1.1.1.10.2 tls if (ret) {
314 1.1.1.1.10.2 tls /*
315 1.1.1.1.10.2 tls * Just set default values to get things going.
316 1.1.1.1.10.2 tls */
317 1.1.1.1.10.2 tls NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
318 1.1.1.1.10.2 tls nfsva.na_vattr.va_type = VDIR;
319 1.1.1.1.10.2 tls nfsva.na_vattr.va_mode = 0777;
320 1.1.1.1.10.2 tls nfsva.na_vattr.va_nlink = 100;
321 1.1.1.1.10.2 tls nfsva.na_vattr.va_uid = (uid_t)0;
322 1.1.1.1.10.2 tls nfsva.na_vattr.va_gid = (gid_t)0;
323 1.1.1.1.10.2 tls nfsva.na_vattr.va_fileid = 2;
324 1.1.1.1.10.2 tls nfsva.na_vattr.va_gen = 1;
325 1.1.1.1.10.2 tls nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
326 1.1.1.1.10.2 tls nfsva.na_vattr.va_size = 512 * 1024;
327 1.1.1.1.10.2 tls }
328 1.1.1.1.10.2 tls }
329 1.1.1.1.10.2 tls (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
330 1.1.1.1.10.2 tls if (!error) {
331 1.1.1.1.10.2 tls mtx_lock(&nmp->nm_mtx);
332 1.1.1.1.10.2 tls if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
333 1.1.1.1.10.2 tls nfscl_loadfsinfo(nmp, &fs);
334 1.1.1.1.10.2 tls nfscl_loadsbinfo(nmp, &sb, sbp);
335 1.1.1.1.10.2 tls sbp->f_iosize = newnfs_iosize(nmp);
336 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
337 1.1.1.1.10.2 tls if (sbp != &mp->mnt_stat) {
338 1.1.1.1.10.2 tls bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
339 1.1.1.1.10.2 tls bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
340 1.1.1.1.10.2 tls }
341 1.1.1.1.10.2 tls strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
342 1.1.1.1.10.2 tls } else if (NFS_ISV4(vp)) {
343 1.1.1.1.10.2 tls error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
344 1.1.1.1.10.2 tls }
345 1.1.1.1.10.2 tls vput(vp);
346 1.1.1.1.10.2 tls vfs_unbusy(mp);
347 1.1.1.1.10.2 tls return (error);
348 1.1.1.1.10.2 tls }
349 1.1.1.1.10.2 tls
350 1.1.1.1.10.2 tls /*
351 1.1.1.1.10.2 tls * nfs version 3 fsinfo rpc call
352 1.1.1.1.10.2 tls */
353 1.1.1.1.10.2 tls int
354 1.1.1.1.10.2 tls ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
355 1.1.1.1.10.2 tls struct thread *td)
356 1.1.1.1.10.2 tls {
357 1.1.1.1.10.2 tls struct nfsfsinfo fs;
358 1.1.1.1.10.2 tls struct nfsvattr nfsva;
359 1.1.1.1.10.2 tls int error, attrflag;
360 1.1.1.1.10.2 tls
361 1.1.1.1.10.2 tls error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
362 1.1.1.1.10.2 tls if (!error) {
363 1.1.1.1.10.2 tls if (attrflag)
364 1.1.1.1.10.2 tls (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
365 1.1.1.1.10.2 tls 1);
366 1.1.1.1.10.2 tls mtx_lock(&nmp->nm_mtx);
367 1.1.1.1.10.2 tls nfscl_loadfsinfo(nmp, &fs);
368 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
369 1.1.1.1.10.2 tls }
370 1.1.1.1.10.2 tls return (error);
371 1.1.1.1.10.2 tls }
372 1.1.1.1.10.2 tls
373 1.1.1.1.10.2 tls /*
374 1.1.1.1.10.2 tls * Mount a remote root fs via. nfs. This depends on the info in the
375 1.1.1.1.10.2 tls * nfs_diskless structure that has been filled in properly by some primary
376 1.1.1.1.10.2 tls * bootstrap.
377 1.1.1.1.10.2 tls * It goes something like this:
378 1.1.1.1.10.2 tls * - do enough of "ifconfig" by calling ifioctl() so that the system
379 1.1.1.1.10.2 tls * can talk to the server
380 1.1.1.1.10.2 tls * - If nfs_diskless.mygateway is filled in, use that address as
381 1.1.1.1.10.2 tls * a default gateway.
382 1.1.1.1.10.2 tls * - build the rootfs mount point and call mountnfs() to do the rest.
383 1.1.1.1.10.2 tls *
384 1.1.1.1.10.2 tls * It is assumed to be safe to read, modify, and write the nfsv3_diskless
385 1.1.1.1.10.2 tls * structure, as well as other global NFS client variables here, as
386 1.1.1.1.10.2 tls * nfs_mountroot() will be called once in the boot before any other NFS
387 1.1.1.1.10.2 tls * client activity occurs.
388 1.1.1.1.10.2 tls */
389 1.1.1.1.10.2 tls static int
390 1.1.1.1.10.2 tls nfs_mountroot(struct mount *mp)
391 1.1.1.1.10.2 tls {
392 1.1.1.1.10.2 tls struct thread *td = curthread;
393 1.1.1.1.10.2 tls struct nfsv3_diskless *nd = &nfsv3_diskless;
394 1.1.1.1.10.2 tls struct socket *so;
395 1.1.1.1.10.2 tls struct vnode *vp;
396 1.1.1.1.10.2 tls struct ifreq ir;
397 1.1.1.1.10.2 tls int error;
398 1.1.1.1.10.2 tls u_long l;
399 1.1.1.1.10.2 tls char buf[128];
400 1.1.1.1.10.2 tls char *cp;
401 1.1.1.1.10.2 tls
402 1.1.1.1.10.2 tls #if defined(BOOTP_NFSROOT) && defined(BOOTP)
403 1.1.1.1.10.2 tls bootpc_init(); /* use bootp to get nfs_diskless filled in */
404 1.1.1.1.10.2 tls #elif defined(NFS_ROOT)
405 1.1.1.1.10.2 tls nfs_setup_diskless();
406 1.1.1.1.10.2 tls #endif
407 1.1.1.1.10.2 tls
408 1.1.1.1.10.2 tls if (nfs_diskless_valid == 0)
409 1.1.1.1.10.2 tls return (-1);
410 1.1.1.1.10.2 tls if (nfs_diskless_valid == 1)
411 1.1.1.1.10.2 tls nfs_convert_diskless();
412 1.1.1.1.10.2 tls
413 1.1.1.1.10.2 tls /*
414 1.1.1.1.10.2 tls * XXX splnet, so networks will receive...
415 1.1.1.1.10.2 tls */
416 1.1.1.1.10.2 tls splnet();
417 1.1.1.1.10.2 tls
418 1.1.1.1.10.2 tls /*
419 1.1.1.1.10.2 tls * Do enough of ifconfig(8) so that the critical net interface can
420 1.1.1.1.10.2 tls * talk to the server.
421 1.1.1.1.10.2 tls */
422 1.1.1.1.10.2 tls error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
423 1.1.1.1.10.2 tls td->td_ucred, td);
424 1.1.1.1.10.2 tls if (error)
425 1.1.1.1.10.2 tls panic("nfs_mountroot: socreate(%04x): %d",
426 1.1.1.1.10.2 tls nd->myif.ifra_addr.sa_family, error);
427 1.1.1.1.10.2 tls
428 1.1.1.1.10.2 tls #if 0 /* XXX Bad idea */
429 1.1.1.1.10.2 tls /*
430 1.1.1.1.10.2 tls * We might not have been told the right interface, so we pass
431 1.1.1.1.10.2 tls * over the first ten interfaces of the same kind, until we get
432 1.1.1.1.10.2 tls * one of them configured.
433 1.1.1.1.10.2 tls */
434 1.1.1.1.10.2 tls
435 1.1.1.1.10.2 tls for (i = strlen(nd->myif.ifra_name) - 1;
436 1.1.1.1.10.2 tls nd->myif.ifra_name[i] >= '0' &&
437 1.1.1.1.10.2 tls nd->myif.ifra_name[i] <= '9';
438 1.1.1.1.10.2 tls nd->myif.ifra_name[i] ++) {
439 1.1.1.1.10.2 tls error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
440 1.1.1.1.10.2 tls if(!error)
441 1.1.1.1.10.2 tls break;
442 1.1.1.1.10.2 tls }
443 1.1.1.1.10.2 tls #endif
444 1.1.1.1.10.2 tls error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
445 1.1.1.1.10.2 tls if (error)
446 1.1.1.1.10.2 tls panic("nfs_mountroot: SIOCAIFADDR: %d", error);
447 1.1.1.1.10.2 tls if ((cp = getenv("boot.netif.mtu")) != NULL) {
448 1.1.1.1.10.2 tls ir.ifr_mtu = strtol(cp, NULL, 10);
449 1.1.1.1.10.2 tls bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
450 1.1.1.1.10.2 tls freeenv(cp);
451 1.1.1.1.10.2 tls error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
452 1.1.1.1.10.2 tls if (error)
453 1.1.1.1.10.2 tls printf("nfs_mountroot: SIOCSIFMTU: %d", error);
454 1.1.1.1.10.2 tls }
455 1.1.1.1.10.2 tls soclose(so);
456 1.1.1.1.10.2 tls
457 1.1.1.1.10.2 tls /*
458 1.1.1.1.10.2 tls * If the gateway field is filled in, set it as the default route.
459 1.1.1.1.10.2 tls * Note that pxeboot will set a default route of 0 if the route
460 1.1.1.1.10.2 tls * is not set by the DHCP server. Check also for a value of 0
461 1.1.1.1.10.2 tls * to avoid panicking inappropriately in that situation.
462 1.1.1.1.10.2 tls */
463 1.1.1.1.10.2 tls if (nd->mygateway.sin_len != 0 &&
464 1.1.1.1.10.2 tls nd->mygateway.sin_addr.s_addr != 0) {
465 1.1.1.1.10.2 tls struct sockaddr_in mask, sin;
466 1.1.1.1.10.2 tls
467 1.1.1.1.10.2 tls bzero((caddr_t)&mask, sizeof(mask));
468 1.1.1.1.10.2 tls sin = mask;
469 1.1.1.1.10.2 tls sin.sin_family = AF_INET;
470 1.1.1.1.10.2 tls sin.sin_len = sizeof(sin);
471 1.1.1.1.10.2 tls /* XXX MRT use table 0 for this sort of thing */
472 1.1.1.1.10.2 tls CURVNET_SET(TD_TO_VNET(td));
473 1.1.1.1.10.2 tls error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
474 1.1.1.1.10.2 tls (struct sockaddr *)&nd->mygateway,
475 1.1.1.1.10.2 tls (struct sockaddr *)&mask,
476 1.1.1.1.10.2 tls RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
477 1.1.1.1.10.2 tls CURVNET_RESTORE();
478 1.1.1.1.10.2 tls if (error)
479 1.1.1.1.10.2 tls panic("nfs_mountroot: RTM_ADD: %d", error);
480 1.1.1.1.10.2 tls }
481 1.1.1.1.10.2 tls
482 1.1.1.1.10.2 tls /*
483 1.1.1.1.10.2 tls * Create the rootfs mount point.
484 1.1.1.1.10.2 tls */
485 1.1.1.1.10.2 tls nd->root_args.fh = nd->root_fh;
486 1.1.1.1.10.2 tls nd->root_args.fhsize = nd->root_fhsize;
487 1.1.1.1.10.2 tls l = ntohl(nd->root_saddr.sin_addr.s_addr);
488 1.1.1.1.10.2 tls snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
489 1.1.1.1.10.2 tls (l >> 24) & 0xff, (l >> 16) & 0xff,
490 1.1.1.1.10.2 tls (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
491 1.1.1.1.10.2 tls printf("NFS ROOT: %s\n", buf);
492 1.1.1.1.10.2 tls nd->root_args.hostname = buf;
493 1.1.1.1.10.2 tls if ((error = nfs_mountdiskless(buf,
494 1.1.1.1.10.2 tls &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
495 1.1.1.1.10.2 tls return (error);
496 1.1.1.1.10.2 tls }
497 1.1.1.1.10.2 tls
498 1.1.1.1.10.2 tls /*
499 1.1.1.1.10.2 tls * This is not really an nfs issue, but it is much easier to
500 1.1.1.1.10.2 tls * set hostname here and then let the "/etc/rc.xxx" files
501 1.1.1.1.10.2 tls * mount the right /var based upon its preset value.
502 1.1.1.1.10.2 tls */
503 1.1.1.1.10.2 tls mtx_lock(&prison0.pr_mtx);
504 1.1.1.1.10.2 tls strlcpy(prison0.pr_hostname, nd->my_hostnam,
505 1.1.1.1.10.2 tls sizeof(prison0.pr_hostname));
506 1.1.1.1.10.2 tls mtx_unlock(&prison0.pr_mtx);
507 1.1.1.1.10.2 tls inittodr(ntohl(nd->root_time));
508 1.1.1.1.10.2 tls return (0);
509 1.1.1.1.10.2 tls }
510 1.1.1.1.10.2 tls
511 1.1.1.1.10.2 tls /*
512 1.1.1.1.10.2 tls * Internal version of mount system call for diskless setup.
513 1.1.1.1.10.2 tls */
514 1.1.1.1.10.2 tls static int
515 1.1.1.1.10.2 tls nfs_mountdiskless(char *path,
516 1.1.1.1.10.2 tls struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
517 1.1.1.1.10.2 tls struct vnode **vpp, struct mount *mp)
518 1.1.1.1.10.2 tls {
519 1.1.1.1.10.2 tls struct sockaddr *nam;
520 1.1.1.1.10.2 tls int dirlen, error;
521 1.1.1.1.10.2 tls char *dirpath;
522 1.1.1.1.10.2 tls
523 1.1.1.1.10.2 tls /*
524 1.1.1.1.10.2 tls * Find the directory path in "path", which also has the server's
525 1.1.1.1.10.2 tls * name/ip address in it.
526 1.1.1.1.10.2 tls */
527 1.1.1.1.10.2 tls dirpath = strchr(path, ':');
528 1.1.1.1.10.2 tls if (dirpath != NULL)
529 1.1.1.1.10.2 tls dirlen = strlen(++dirpath);
530 1.1.1.1.10.2 tls else
531 1.1.1.1.10.2 tls dirlen = 0;
532 1.1.1.1.10.2 tls nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
533 1.1.1.1.10.2 tls if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
534 1.1.1.1.10.2 tls NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
535 1.1.1.1.10.2 tls NFS_DEFAULT_NEGNAMETIMEO, 0)) != 0) {
536 1.1.1.1.10.2 tls printf("nfs_mountroot: mount %s on /: %d\n", path, error);
537 1.1.1.1.10.2 tls return (error);
538 1.1.1.1.10.2 tls }
539 1.1.1.1.10.2 tls return (0);
540 1.1.1.1.10.2 tls }
541 1.1.1.1.10.2 tls
542 1.1.1.1.10.2 tls static void
543 1.1.1.1.10.2 tls nfs_sec_name(char *sec, int *flagsp)
544 1.1.1.1.10.2 tls {
545 1.1.1.1.10.2 tls if (!strcmp(sec, "krb5"))
546 1.1.1.1.10.2 tls *flagsp |= NFSMNT_KERB;
547 1.1.1.1.10.2 tls else if (!strcmp(sec, "krb5i"))
548 1.1.1.1.10.2 tls *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
549 1.1.1.1.10.2 tls else if (!strcmp(sec, "krb5p"))
550 1.1.1.1.10.2 tls *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
551 1.1.1.1.10.2 tls }
552 1.1.1.1.10.2 tls
553 1.1.1.1.10.2 tls static void
554 1.1.1.1.10.2 tls nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
555 1.1.1.1.10.2 tls const char *hostname, struct ucred *cred, struct thread *td)
556 1.1.1.1.10.2 tls {
557 1.1.1.1.10.2 tls int s;
558 1.1.1.1.10.2 tls int adjsock;
559 1.1.1.1.10.2 tls char *p;
560 1.1.1.1.10.2 tls
561 1.1.1.1.10.2 tls s = splnet();
562 1.1.1.1.10.2 tls
563 1.1.1.1.10.2 tls /*
564 1.1.1.1.10.2 tls * Set read-only flag if requested; otherwise, clear it if this is
565 1.1.1.1.10.2 tls * an update. If this is not an update, then either the read-only
566 1.1.1.1.10.2 tls * flag is already clear, or this is a root mount and it was set
567 1.1.1.1.10.2 tls * intentionally at some previous point.
568 1.1.1.1.10.2 tls */
569 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
570 1.1.1.1.10.2 tls MNT_ILOCK(mp);
571 1.1.1.1.10.2 tls mp->mnt_flag |= MNT_RDONLY;
572 1.1.1.1.10.2 tls MNT_IUNLOCK(mp);
573 1.1.1.1.10.2 tls } else if (mp->mnt_flag & MNT_UPDATE) {
574 1.1.1.1.10.2 tls MNT_ILOCK(mp);
575 1.1.1.1.10.2 tls mp->mnt_flag &= ~MNT_RDONLY;
576 1.1.1.1.10.2 tls MNT_IUNLOCK(mp);
577 1.1.1.1.10.2 tls }
578 1.1.1.1.10.2 tls
579 1.1.1.1.10.2 tls /*
580 1.1.1.1.10.2 tls * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
581 1.1.1.1.10.2 tls * no sense in that context. Also, set up appropriate retransmit
582 1.1.1.1.10.2 tls * and soft timeout behavior.
583 1.1.1.1.10.2 tls */
584 1.1.1.1.10.2 tls if (argp->sotype == SOCK_STREAM) {
585 1.1.1.1.10.2 tls nmp->nm_flag &= ~NFSMNT_NOCONN;
586 1.1.1.1.10.2 tls nmp->nm_timeo = NFS_MAXTIMEO;
587 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_NFSV4) != 0)
588 1.1.1.1.10.2 tls nmp->nm_retry = INT_MAX;
589 1.1.1.1.10.2 tls else
590 1.1.1.1.10.2 tls nmp->nm_retry = NFS_RETRANS_TCP;
591 1.1.1.1.10.2 tls }
592 1.1.1.1.10.2 tls
593 1.1.1.1.10.2 tls /* Also clear RDIRPLUS if NFSv2, it crashes some servers */
594 1.1.1.1.10.2 tls if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
595 1.1.1.1.10.2 tls argp->flags &= ~NFSMNT_RDIRPLUS;
596 1.1.1.1.10.2 tls nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
597 1.1.1.1.10.2 tls }
598 1.1.1.1.10.2 tls
599 1.1.1.1.10.2 tls /* Re-bind if rsrvd port requested and wasn't on one */
600 1.1.1.1.10.2 tls adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
601 1.1.1.1.10.2 tls && (argp->flags & NFSMNT_RESVPORT);
602 1.1.1.1.10.2 tls /* Also re-bind if we're switching to/from a connected UDP socket */
603 1.1.1.1.10.2 tls adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
604 1.1.1.1.10.2 tls (argp->flags & NFSMNT_NOCONN));
605 1.1.1.1.10.2 tls
606 1.1.1.1.10.2 tls /* Update flags atomically. Don't change the lock bits. */
607 1.1.1.1.10.2 tls nmp->nm_flag = argp->flags | nmp->nm_flag;
608 1.1.1.1.10.2 tls splx(s);
609 1.1.1.1.10.2 tls
610 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
611 1.1.1.1.10.2 tls nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
612 1.1.1.1.10.2 tls if (nmp->nm_timeo < NFS_MINTIMEO)
613 1.1.1.1.10.2 tls nmp->nm_timeo = NFS_MINTIMEO;
614 1.1.1.1.10.2 tls else if (nmp->nm_timeo > NFS_MAXTIMEO)
615 1.1.1.1.10.2 tls nmp->nm_timeo = NFS_MAXTIMEO;
616 1.1.1.1.10.2 tls }
617 1.1.1.1.10.2 tls
618 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
619 1.1.1.1.10.2 tls nmp->nm_retry = argp->retrans;
620 1.1.1.1.10.2 tls if (nmp->nm_retry > NFS_MAXREXMIT)
621 1.1.1.1.10.2 tls nmp->nm_retry = NFS_MAXREXMIT;
622 1.1.1.1.10.2 tls }
623 1.1.1.1.10.2 tls
624 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
625 1.1.1.1.10.2 tls nmp->nm_wsize = argp->wsize;
626 1.1.1.1.10.2 tls /* Round down to multiple of blocksize */
627 1.1.1.1.10.2 tls nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
628 1.1.1.1.10.2 tls if (nmp->nm_wsize <= 0)
629 1.1.1.1.10.2 tls nmp->nm_wsize = NFS_FABLKSIZE;
630 1.1.1.1.10.2 tls }
631 1.1.1.1.10.2 tls
632 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
633 1.1.1.1.10.2 tls nmp->nm_rsize = argp->rsize;
634 1.1.1.1.10.2 tls /* Round down to multiple of blocksize */
635 1.1.1.1.10.2 tls nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
636 1.1.1.1.10.2 tls if (nmp->nm_rsize <= 0)
637 1.1.1.1.10.2 tls nmp->nm_rsize = NFS_FABLKSIZE;
638 1.1.1.1.10.2 tls }
639 1.1.1.1.10.2 tls
640 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
641 1.1.1.1.10.2 tls nmp->nm_readdirsize = argp->readdirsize;
642 1.1.1.1.10.2 tls }
643 1.1.1.1.10.2 tls
644 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
645 1.1.1.1.10.2 tls nmp->nm_acregmin = argp->acregmin;
646 1.1.1.1.10.2 tls else
647 1.1.1.1.10.2 tls nmp->nm_acregmin = NFS_MINATTRTIMO;
648 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
649 1.1.1.1.10.2 tls nmp->nm_acregmax = argp->acregmax;
650 1.1.1.1.10.2 tls else
651 1.1.1.1.10.2 tls nmp->nm_acregmax = NFS_MAXATTRTIMO;
652 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
653 1.1.1.1.10.2 tls nmp->nm_acdirmin = argp->acdirmin;
654 1.1.1.1.10.2 tls else
655 1.1.1.1.10.2 tls nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
656 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
657 1.1.1.1.10.2 tls nmp->nm_acdirmax = argp->acdirmax;
658 1.1.1.1.10.2 tls else
659 1.1.1.1.10.2 tls nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
660 1.1.1.1.10.2 tls if (nmp->nm_acdirmin > nmp->nm_acdirmax)
661 1.1.1.1.10.2 tls nmp->nm_acdirmin = nmp->nm_acdirmax;
662 1.1.1.1.10.2 tls if (nmp->nm_acregmin > nmp->nm_acregmax)
663 1.1.1.1.10.2 tls nmp->nm_acregmin = nmp->nm_acregmax;
664 1.1.1.1.10.2 tls
665 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
666 1.1.1.1.10.2 tls if (argp->readahead <= NFS_MAXRAHEAD)
667 1.1.1.1.10.2 tls nmp->nm_readahead = argp->readahead;
668 1.1.1.1.10.2 tls else
669 1.1.1.1.10.2 tls nmp->nm_readahead = NFS_MAXRAHEAD;
670 1.1.1.1.10.2 tls }
671 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
672 1.1.1.1.10.2 tls if (argp->wcommitsize < nmp->nm_wsize)
673 1.1.1.1.10.2 tls nmp->nm_wcommitsize = nmp->nm_wsize;
674 1.1.1.1.10.2 tls else
675 1.1.1.1.10.2 tls nmp->nm_wcommitsize = argp->wcommitsize;
676 1.1.1.1.10.2 tls }
677 1.1.1.1.10.2 tls
678 1.1.1.1.10.2 tls adjsock |= ((nmp->nm_sotype != argp->sotype) ||
679 1.1.1.1.10.2 tls (nmp->nm_soproto != argp->proto));
680 1.1.1.1.10.2 tls
681 1.1.1.1.10.2 tls if (nmp->nm_client != NULL && adjsock) {
682 1.1.1.1.10.2 tls int haslock = 0, error = 0;
683 1.1.1.1.10.2 tls
684 1.1.1.1.10.2 tls if (nmp->nm_sotype == SOCK_STREAM) {
685 1.1.1.1.10.2 tls error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
686 1.1.1.1.10.2 tls if (!error)
687 1.1.1.1.10.2 tls haslock = 1;
688 1.1.1.1.10.2 tls }
689 1.1.1.1.10.2 tls if (!error) {
690 1.1.1.1.10.2 tls newnfs_disconnect(&nmp->nm_sockreq);
691 1.1.1.1.10.2 tls if (haslock)
692 1.1.1.1.10.2 tls newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
693 1.1.1.1.10.2 tls nmp->nm_sotype = argp->sotype;
694 1.1.1.1.10.2 tls nmp->nm_soproto = argp->proto;
695 1.1.1.1.10.2 tls if (nmp->nm_sotype == SOCK_DGRAM)
696 1.1.1.1.10.2 tls while (newnfs_connect(nmp, &nmp->nm_sockreq,
697 1.1.1.1.10.2 tls cred, td, 0)) {
698 1.1.1.1.10.2 tls printf("newnfs_args: retrying connect\n");
699 1.1.1.1.10.2 tls (void) nfs_catnap(PSOCK, 0, "newnfscon");
700 1.1.1.1.10.2 tls }
701 1.1.1.1.10.2 tls }
702 1.1.1.1.10.2 tls } else {
703 1.1.1.1.10.2 tls nmp->nm_sotype = argp->sotype;
704 1.1.1.1.10.2 tls nmp->nm_soproto = argp->proto;
705 1.1.1.1.10.2 tls }
706 1.1.1.1.10.2 tls
707 1.1.1.1.10.2 tls if (hostname != NULL) {
708 1.1.1.1.10.2 tls strlcpy(nmp->nm_hostname, hostname,
709 1.1.1.1.10.2 tls sizeof(nmp->nm_hostname));
710 1.1.1.1.10.2 tls p = strchr(nmp->nm_hostname, ':');
711 1.1.1.1.10.2 tls if (p != NULL)
712 1.1.1.1.10.2 tls *p = '\0';
713 1.1.1.1.10.2 tls }
714 1.1.1.1.10.2 tls }
715 1.1.1.1.10.2 tls
716 1.1.1.1.10.2 tls static const char *nfs_opts[] = { "from", "nfs_args",
717 1.1.1.1.10.2 tls "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
718 1.1.1.1.10.2 tls "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
719 1.1.1.1.10.2 tls "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
720 1.1.1.1.10.2 tls "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
721 1.1.1.1.10.2 tls "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport",
722 1.1.1.1.10.2 tls "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
723 1.1.1.1.10.2 tls "principal", "nfsv4", "gssname", "allgssname", "dirpath", "minorversion",
724 1.1.1.1.10.2 tls "nametimeo", "negnametimeo", "nocto", "pnfs", "wcommitsize",
725 1.1.1.1.10.2 tls NULL };
726 1.1.1.1.10.2 tls
727 1.1.1.1.10.2 tls /*
728 1.1.1.1.10.2 tls * VFS Operations.
729 1.1.1.1.10.2 tls *
730 1.1.1.1.10.2 tls * mount system call
731 1.1.1.1.10.2 tls * It seems a bit dumb to copyinstr() the host and path here and then
732 1.1.1.1.10.2 tls * bcopy() them in mountnfs(), but I wanted to detect errors before
733 1.1.1.1.10.2 tls * doing the sockargs() call because sockargs() allocates an mbuf and
734 1.1.1.1.10.2 tls * an error after that means that I have to release the mbuf.
735 1.1.1.1.10.2 tls */
736 1.1.1.1.10.2 tls /* ARGSUSED */
737 1.1.1.1.10.2 tls static int
738 1.1.1.1.10.2 tls nfs_mount(struct mount *mp)
739 1.1.1.1.10.2 tls {
740 1.1.1.1.10.2 tls struct nfs_args args = {
741 1.1.1.1.10.2 tls .version = NFS_ARGSVERSION,
742 1.1.1.1.10.2 tls .addr = NULL,
743 1.1.1.1.10.2 tls .addrlen = sizeof (struct sockaddr_in),
744 1.1.1.1.10.2 tls .sotype = SOCK_STREAM,
745 1.1.1.1.10.2 tls .proto = 0,
746 1.1.1.1.10.2 tls .fh = NULL,
747 1.1.1.1.10.2 tls .fhsize = 0,
748 1.1.1.1.10.2 tls .flags = NFSMNT_RESVPORT,
749 1.1.1.1.10.2 tls .wsize = NFS_WSIZE,
750 1.1.1.1.10.2 tls .rsize = NFS_RSIZE,
751 1.1.1.1.10.2 tls .readdirsize = NFS_READDIRSIZE,
752 1.1.1.1.10.2 tls .timeo = 10,
753 1.1.1.1.10.2 tls .retrans = NFS_RETRANS,
754 1.1.1.1.10.2 tls .readahead = NFS_DEFRAHEAD,
755 1.1.1.1.10.2 tls .wcommitsize = 0, /* was: NQ_DEFLEASE */
756 1.1.1.1.10.2 tls .hostname = NULL,
757 1.1.1.1.10.2 tls .acregmin = NFS_MINATTRTIMO,
758 1.1.1.1.10.2 tls .acregmax = NFS_MAXATTRTIMO,
759 1.1.1.1.10.2 tls .acdirmin = NFS_MINDIRATTRTIMO,
760 1.1.1.1.10.2 tls .acdirmax = NFS_MAXDIRATTRTIMO,
761 1.1.1.1.10.2 tls };
762 1.1.1.1.10.2 tls int error = 0, ret, len;
763 1.1.1.1.10.2 tls struct sockaddr *nam = NULL;
764 1.1.1.1.10.2 tls struct vnode *vp;
765 1.1.1.1.10.2 tls struct thread *td;
766 1.1.1.1.10.2 tls char hst[MNAMELEN];
767 1.1.1.1.10.2 tls u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
768 1.1.1.1.10.2 tls char *opt, *name, *secname;
769 1.1.1.1.10.2 tls int nametimeo = NFS_DEFAULT_NAMETIMEO;
770 1.1.1.1.10.2 tls int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
771 1.1.1.1.10.2 tls int minvers = 0;
772 1.1.1.1.10.2 tls int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen;
773 1.1.1.1.10.2 tls size_t hstlen;
774 1.1.1.1.10.2 tls
775 1.1.1.1.10.2 tls has_nfs_args_opt = 0;
776 1.1.1.1.10.2 tls if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
777 1.1.1.1.10.2 tls error = EINVAL;
778 1.1.1.1.10.2 tls goto out;
779 1.1.1.1.10.2 tls }
780 1.1.1.1.10.2 tls
781 1.1.1.1.10.2 tls td = curthread;
782 1.1.1.1.10.2 tls if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
783 1.1.1.1.10.2 tls error = nfs_mountroot(mp);
784 1.1.1.1.10.2 tls goto out;
785 1.1.1.1.10.2 tls }
786 1.1.1.1.10.2 tls
787 1.1.1.1.10.2 tls nfscl_init();
788 1.1.1.1.10.2 tls
789 1.1.1.1.10.2 tls /*
790 1.1.1.1.10.2 tls * The old mount_nfs program passed the struct nfs_args
791 1.1.1.1.10.2 tls * from userspace to kernel. The new mount_nfs program
792 1.1.1.1.10.2 tls * passes string options via nmount() from userspace to kernel
793 1.1.1.1.10.2 tls * and we populate the struct nfs_args in the kernel.
794 1.1.1.1.10.2 tls */
795 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
796 1.1.1.1.10.2 tls error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
797 1.1.1.1.10.2 tls sizeof(args));
798 1.1.1.1.10.2 tls if (error != 0)
799 1.1.1.1.10.2 tls goto out;
800 1.1.1.1.10.2 tls
801 1.1.1.1.10.2 tls if (args.version != NFS_ARGSVERSION) {
802 1.1.1.1.10.2 tls error = EPROGMISMATCH;
803 1.1.1.1.10.2 tls goto out;
804 1.1.1.1.10.2 tls }
805 1.1.1.1.10.2 tls has_nfs_args_opt = 1;
806 1.1.1.1.10.2 tls }
807 1.1.1.1.10.2 tls
808 1.1.1.1.10.2 tls /* Handle the new style options. */
809 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
810 1.1.1.1.10.2 tls args.flags |= NFSMNT_NOCONN;
811 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
812 1.1.1.1.10.2 tls args.flags |= NFSMNT_NOCONN;
813 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
814 1.1.1.1.10.2 tls args.flags |= NFSMNT_NOLOCKD;
815 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
816 1.1.1.1.10.2 tls args.flags &= ~NFSMNT_NOLOCKD;
817 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
818 1.1.1.1.10.2 tls args.flags |= NFSMNT_INT;
819 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
820 1.1.1.1.10.2 tls args.flags |= NFSMNT_RDIRPLUS;
821 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
822 1.1.1.1.10.2 tls args.flags |= NFSMNT_RESVPORT;
823 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
824 1.1.1.1.10.2 tls args.flags &= ~NFSMNT_RESVPORT;
825 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
826 1.1.1.1.10.2 tls args.flags |= NFSMNT_SOFT;
827 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
828 1.1.1.1.10.2 tls args.flags &= ~NFSMNT_SOFT;
829 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
830 1.1.1.1.10.2 tls args.sotype = SOCK_DGRAM;
831 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
832 1.1.1.1.10.2 tls args.sotype = SOCK_DGRAM;
833 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
834 1.1.1.1.10.2 tls args.sotype = SOCK_STREAM;
835 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
836 1.1.1.1.10.2 tls args.flags |= NFSMNT_NFSV3;
837 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
838 1.1.1.1.10.2 tls args.flags |= NFSMNT_NFSV4;
839 1.1.1.1.10.2 tls args.sotype = SOCK_STREAM;
840 1.1.1.1.10.2 tls }
841 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
842 1.1.1.1.10.2 tls args.flags |= NFSMNT_ALLGSSNAME;
843 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
844 1.1.1.1.10.2 tls args.flags |= NFSMNT_NOCTO;
845 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "pnfs", NULL, NULL) == 0)
846 1.1.1.1.10.2 tls args.flags |= NFSMNT_PNFS;
847 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
848 1.1.1.1.10.2 tls if (opt == NULL) {
849 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal readdirsize");
850 1.1.1.1.10.2 tls error = EINVAL;
851 1.1.1.1.10.2 tls goto out;
852 1.1.1.1.10.2 tls }
853 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.readdirsize);
854 1.1.1.1.10.2 tls if (ret != 1 || args.readdirsize <= 0) {
855 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal readdirsize: %s",
856 1.1.1.1.10.2 tls opt);
857 1.1.1.1.10.2 tls error = EINVAL;
858 1.1.1.1.10.2 tls goto out;
859 1.1.1.1.10.2 tls }
860 1.1.1.1.10.2 tls args.flags |= NFSMNT_READDIRSIZE;
861 1.1.1.1.10.2 tls }
862 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
863 1.1.1.1.10.2 tls if (opt == NULL) {
864 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal readahead");
865 1.1.1.1.10.2 tls error = EINVAL;
866 1.1.1.1.10.2 tls goto out;
867 1.1.1.1.10.2 tls }
868 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.readahead);
869 1.1.1.1.10.2 tls if (ret != 1 || args.readahead <= 0) {
870 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal readahead: %s",
871 1.1.1.1.10.2 tls opt);
872 1.1.1.1.10.2 tls error = EINVAL;
873 1.1.1.1.10.2 tls goto out;
874 1.1.1.1.10.2 tls }
875 1.1.1.1.10.2 tls args.flags |= NFSMNT_READAHEAD;
876 1.1.1.1.10.2 tls }
877 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
878 1.1.1.1.10.2 tls if (opt == NULL) {
879 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal wsize");
880 1.1.1.1.10.2 tls error = EINVAL;
881 1.1.1.1.10.2 tls goto out;
882 1.1.1.1.10.2 tls }
883 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.wsize);
884 1.1.1.1.10.2 tls if (ret != 1 || args.wsize <= 0) {
885 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal wsize: %s",
886 1.1.1.1.10.2 tls opt);
887 1.1.1.1.10.2 tls error = EINVAL;
888 1.1.1.1.10.2 tls goto out;
889 1.1.1.1.10.2 tls }
890 1.1.1.1.10.2 tls args.flags |= NFSMNT_WSIZE;
891 1.1.1.1.10.2 tls }
892 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
893 1.1.1.1.10.2 tls if (opt == NULL) {
894 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal rsize");
895 1.1.1.1.10.2 tls error = EINVAL;
896 1.1.1.1.10.2 tls goto out;
897 1.1.1.1.10.2 tls }
898 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.rsize);
899 1.1.1.1.10.2 tls if (ret != 1 || args.rsize <= 0) {
900 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal wsize: %s",
901 1.1.1.1.10.2 tls opt);
902 1.1.1.1.10.2 tls error = EINVAL;
903 1.1.1.1.10.2 tls goto out;
904 1.1.1.1.10.2 tls }
905 1.1.1.1.10.2 tls args.flags |= NFSMNT_RSIZE;
906 1.1.1.1.10.2 tls }
907 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
908 1.1.1.1.10.2 tls if (opt == NULL) {
909 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal retrans");
910 1.1.1.1.10.2 tls error = EINVAL;
911 1.1.1.1.10.2 tls goto out;
912 1.1.1.1.10.2 tls }
913 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.retrans);
914 1.1.1.1.10.2 tls if (ret != 1 || args.retrans <= 0) {
915 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal retrans: %s",
916 1.1.1.1.10.2 tls opt);
917 1.1.1.1.10.2 tls error = EINVAL;
918 1.1.1.1.10.2 tls goto out;
919 1.1.1.1.10.2 tls }
920 1.1.1.1.10.2 tls args.flags |= NFSMNT_RETRANS;
921 1.1.1.1.10.2 tls }
922 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
923 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.acregmin);
924 1.1.1.1.10.2 tls if (ret != 1 || args.acregmin < 0) {
925 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal acregmin: %s",
926 1.1.1.1.10.2 tls opt);
927 1.1.1.1.10.2 tls error = EINVAL;
928 1.1.1.1.10.2 tls goto out;
929 1.1.1.1.10.2 tls }
930 1.1.1.1.10.2 tls args.flags |= NFSMNT_ACREGMIN;
931 1.1.1.1.10.2 tls }
932 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
933 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.acregmax);
934 1.1.1.1.10.2 tls if (ret != 1 || args.acregmax < 0) {
935 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal acregmax: %s",
936 1.1.1.1.10.2 tls opt);
937 1.1.1.1.10.2 tls error = EINVAL;
938 1.1.1.1.10.2 tls goto out;
939 1.1.1.1.10.2 tls }
940 1.1.1.1.10.2 tls args.flags |= NFSMNT_ACREGMAX;
941 1.1.1.1.10.2 tls }
942 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
943 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.acdirmin);
944 1.1.1.1.10.2 tls if (ret != 1 || args.acdirmin < 0) {
945 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal acdirmin: %s",
946 1.1.1.1.10.2 tls opt);
947 1.1.1.1.10.2 tls error = EINVAL;
948 1.1.1.1.10.2 tls goto out;
949 1.1.1.1.10.2 tls }
950 1.1.1.1.10.2 tls args.flags |= NFSMNT_ACDIRMIN;
951 1.1.1.1.10.2 tls }
952 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
953 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.acdirmax);
954 1.1.1.1.10.2 tls if (ret != 1 || args.acdirmax < 0) {
955 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal acdirmax: %s",
956 1.1.1.1.10.2 tls opt);
957 1.1.1.1.10.2 tls error = EINVAL;
958 1.1.1.1.10.2 tls goto out;
959 1.1.1.1.10.2 tls }
960 1.1.1.1.10.2 tls args.flags |= NFSMNT_ACDIRMAX;
961 1.1.1.1.10.2 tls }
962 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
963 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.wcommitsize);
964 1.1.1.1.10.2 tls if (ret != 1 || args.wcommitsize < 0) {
965 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
966 1.1.1.1.10.2 tls error = EINVAL;
967 1.1.1.1.10.2 tls goto out;
968 1.1.1.1.10.2 tls }
969 1.1.1.1.10.2 tls args.flags |= NFSMNT_WCOMMITSIZE;
970 1.1.1.1.10.2 tls }
971 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
972 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &args.timeo);
973 1.1.1.1.10.2 tls if (ret != 1 || args.timeo <= 0) {
974 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal timeout: %s",
975 1.1.1.1.10.2 tls opt);
976 1.1.1.1.10.2 tls error = EINVAL;
977 1.1.1.1.10.2 tls goto out;
978 1.1.1.1.10.2 tls }
979 1.1.1.1.10.2 tls args.flags |= NFSMNT_TIMEO;
980 1.1.1.1.10.2 tls }
981 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
982 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &nametimeo);
983 1.1.1.1.10.2 tls if (ret != 1 || nametimeo < 0) {
984 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal nametimeo: %s", opt);
985 1.1.1.1.10.2 tls error = EINVAL;
986 1.1.1.1.10.2 tls goto out;
987 1.1.1.1.10.2 tls }
988 1.1.1.1.10.2 tls }
989 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
990 1.1.1.1.10.2 tls == 0) {
991 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &negnametimeo);
992 1.1.1.1.10.2 tls if (ret != 1 || negnametimeo < 0) {
993 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal negnametimeo: %s",
994 1.1.1.1.10.2 tls opt);
995 1.1.1.1.10.2 tls error = EINVAL;
996 1.1.1.1.10.2 tls goto out;
997 1.1.1.1.10.2 tls }
998 1.1.1.1.10.2 tls }
999 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "minorversion", (void **)&opt, NULL) ==
1000 1.1.1.1.10.2 tls 0) {
1001 1.1.1.1.10.2 tls ret = sscanf(opt, "%d", &minvers);
1002 1.1.1.1.10.2 tls if (ret != 1 || minvers < 0 || minvers > 1 ||
1003 1.1.1.1.10.2 tls (args.flags & NFSMNT_NFSV4) == 0) {
1004 1.1.1.1.10.2 tls vfs_mount_error(mp, "illegal minorversion: %s", opt);
1005 1.1.1.1.10.2 tls error = EINVAL;
1006 1.1.1.1.10.2 tls goto out;
1007 1.1.1.1.10.2 tls }
1008 1.1.1.1.10.2 tls }
1009 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "sec",
1010 1.1.1.1.10.2 tls (void **) &secname, NULL) == 0)
1011 1.1.1.1.10.2 tls nfs_sec_name(secname, &args.flags);
1012 1.1.1.1.10.2 tls
1013 1.1.1.1.10.2 tls if (mp->mnt_flag & MNT_UPDATE) {
1014 1.1.1.1.10.2 tls struct nfsmount *nmp = VFSTONFS(mp);
1015 1.1.1.1.10.2 tls
1016 1.1.1.1.10.2 tls if (nmp == NULL) {
1017 1.1.1.1.10.2 tls error = EIO;
1018 1.1.1.1.10.2 tls goto out;
1019 1.1.1.1.10.2 tls }
1020 1.1.1.1.10.2 tls
1021 1.1.1.1.10.2 tls /*
1022 1.1.1.1.10.2 tls * If a change from TCP->UDP is done and there are thread(s)
1023 1.1.1.1.10.2 tls * that have I/O RPC(s) in progress with a tranfer size
1024 1.1.1.1.10.2 tls * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1025 1.1.1.1.10.2 tls * hung, retrying the RPC(s) forever. Usually these threads
1026 1.1.1.1.10.2 tls * will be seen doing an uninterruptible sleep on wait channel
1027 1.1.1.1.10.2 tls * "newnfsreq" (truncated to "newnfsre" by procstat).
1028 1.1.1.1.10.2 tls */
1029 1.1.1.1.10.2 tls if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1030 1.1.1.1.10.2 tls tprintf(td->td_proc, LOG_WARNING,
1031 1.1.1.1.10.2 tls "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1032 1.1.1.1.10.2 tls
1033 1.1.1.1.10.2 tls /*
1034 1.1.1.1.10.2 tls * When doing an update, we can't change version,
1035 1.1.1.1.10.2 tls * security, switch lockd strategies or change cookie
1036 1.1.1.1.10.2 tls * translation
1037 1.1.1.1.10.2 tls */
1038 1.1.1.1.10.2 tls args.flags = (args.flags &
1039 1.1.1.1.10.2 tls ~(NFSMNT_NFSV3 |
1040 1.1.1.1.10.2 tls NFSMNT_NFSV4 |
1041 1.1.1.1.10.2 tls NFSMNT_KERB |
1042 1.1.1.1.10.2 tls NFSMNT_INTEGRITY |
1043 1.1.1.1.10.2 tls NFSMNT_PRIVACY |
1044 1.1.1.1.10.2 tls NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1045 1.1.1.1.10.2 tls (nmp->nm_flag &
1046 1.1.1.1.10.2 tls (NFSMNT_NFSV3 |
1047 1.1.1.1.10.2 tls NFSMNT_NFSV4 |
1048 1.1.1.1.10.2 tls NFSMNT_KERB |
1049 1.1.1.1.10.2 tls NFSMNT_INTEGRITY |
1050 1.1.1.1.10.2 tls NFSMNT_PRIVACY |
1051 1.1.1.1.10.2 tls NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1052 1.1.1.1.10.2 tls nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1053 1.1.1.1.10.2 tls goto out;
1054 1.1.1.1.10.2 tls }
1055 1.1.1.1.10.2 tls
1056 1.1.1.1.10.2 tls /*
1057 1.1.1.1.10.2 tls * Make the nfs_ip_paranoia sysctl serve as the default connection
1058 1.1.1.1.10.2 tls * or no-connection mode for those protocols that support
1059 1.1.1.1.10.2 tls * no-connection mode (the flag will be cleared later for protocols
1060 1.1.1.1.10.2 tls * that do not support no-connection mode). This will allow a client
1061 1.1.1.1.10.2 tls * to receive replies from a different IP then the request was
1062 1.1.1.1.10.2 tls * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1063 1.1.1.1.10.2 tls * not 0.
1064 1.1.1.1.10.2 tls */
1065 1.1.1.1.10.2 tls if (nfs_ip_paranoia == 0)
1066 1.1.1.1.10.2 tls args.flags |= NFSMNT_NOCONN;
1067 1.1.1.1.10.2 tls
1068 1.1.1.1.10.2 tls if (has_nfs_args_opt != 0) {
1069 1.1.1.1.10.2 tls /*
1070 1.1.1.1.10.2 tls * In the 'nfs_args' case, the pointers in the args
1071 1.1.1.1.10.2 tls * structure are in userland - we copy them in here.
1072 1.1.1.1.10.2 tls */
1073 1.1.1.1.10.2 tls if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1074 1.1.1.1.10.2 tls vfs_mount_error(mp, "Bad file handle");
1075 1.1.1.1.10.2 tls error = EINVAL;
1076 1.1.1.1.10.2 tls goto out;
1077 1.1.1.1.10.2 tls }
1078 1.1.1.1.10.2 tls error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1079 1.1.1.1.10.2 tls args.fhsize);
1080 1.1.1.1.10.2 tls if (error != 0)
1081 1.1.1.1.10.2 tls goto out;
1082 1.1.1.1.10.2 tls error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1083 1.1.1.1.10.2 tls if (error != 0)
1084 1.1.1.1.10.2 tls goto out;
1085 1.1.1.1.10.2 tls bzero(&hst[hstlen], MNAMELEN - hstlen);
1086 1.1.1.1.10.2 tls args.hostname = hst;
1087 1.1.1.1.10.2 tls /* sockargs() call must be after above copyin() calls */
1088 1.1.1.1.10.2 tls error = getsockaddr(&nam, (caddr_t)args.addr,
1089 1.1.1.1.10.2 tls args.addrlen);
1090 1.1.1.1.10.2 tls if (error != 0)
1091 1.1.1.1.10.2 tls goto out;
1092 1.1.1.1.10.2 tls } else {
1093 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1094 1.1.1.1.10.2 tls &args.fhsize) == 0) {
1095 1.1.1.1.10.2 tls if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1096 1.1.1.1.10.2 tls vfs_mount_error(mp, "Bad file handle");
1097 1.1.1.1.10.2 tls error = EINVAL;
1098 1.1.1.1.10.2 tls goto out;
1099 1.1.1.1.10.2 tls }
1100 1.1.1.1.10.2 tls bcopy(args.fh, nfh, args.fhsize);
1101 1.1.1.1.10.2 tls } else {
1102 1.1.1.1.10.2 tls args.fhsize = 0;
1103 1.1.1.1.10.2 tls }
1104 1.1.1.1.10.2 tls (void) vfs_getopt(mp->mnt_optnew, "hostname",
1105 1.1.1.1.10.2 tls (void **)&args.hostname, &len);
1106 1.1.1.1.10.2 tls if (args.hostname == NULL) {
1107 1.1.1.1.10.2 tls vfs_mount_error(mp, "Invalid hostname");
1108 1.1.1.1.10.2 tls error = EINVAL;
1109 1.1.1.1.10.2 tls goto out;
1110 1.1.1.1.10.2 tls }
1111 1.1.1.1.10.2 tls bcopy(args.hostname, hst, MNAMELEN);
1112 1.1.1.1.10.2 tls hst[MNAMELEN - 1] = '\0';
1113 1.1.1.1.10.2 tls }
1114 1.1.1.1.10.2 tls
1115 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1116 1.1.1.1.10.2 tls strlcpy(srvkrbname, name, sizeof (srvkrbname));
1117 1.1.1.1.10.2 tls else
1118 1.1.1.1.10.2 tls snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1119 1.1.1.1.10.2 tls srvkrbnamelen = strlen(srvkrbname);
1120 1.1.1.1.10.2 tls
1121 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1122 1.1.1.1.10.2 tls strlcpy(krbname, name, sizeof (krbname));
1123 1.1.1.1.10.2 tls else
1124 1.1.1.1.10.2 tls krbname[0] = '\0';
1125 1.1.1.1.10.2 tls krbnamelen = strlen(krbname);
1126 1.1.1.1.10.2 tls
1127 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0)
1128 1.1.1.1.10.2 tls strlcpy(dirpath, name, sizeof (dirpath));
1129 1.1.1.1.10.2 tls else
1130 1.1.1.1.10.2 tls dirpath[0] = '\0';
1131 1.1.1.1.10.2 tls dirlen = strlen(dirpath);
1132 1.1.1.1.10.2 tls
1133 1.1.1.1.10.2 tls if (has_nfs_args_opt == 0) {
1134 1.1.1.1.10.2 tls if (vfs_getopt(mp->mnt_optnew, "addr",
1135 1.1.1.1.10.2 tls (void **)&args.addr, &args.addrlen) == 0) {
1136 1.1.1.1.10.2 tls if (args.addrlen > SOCK_MAXADDRLEN) {
1137 1.1.1.1.10.2 tls error = ENAMETOOLONG;
1138 1.1.1.1.10.2 tls goto out;
1139 1.1.1.1.10.2 tls }
1140 1.1.1.1.10.2 tls nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1141 1.1.1.1.10.2 tls bcopy(args.addr, nam, args.addrlen);
1142 1.1.1.1.10.2 tls nam->sa_len = args.addrlen;
1143 1.1.1.1.10.2 tls } else {
1144 1.1.1.1.10.2 tls vfs_mount_error(mp, "No server address");
1145 1.1.1.1.10.2 tls error = EINVAL;
1146 1.1.1.1.10.2 tls goto out;
1147 1.1.1.1.10.2 tls }
1148 1.1.1.1.10.2 tls }
1149 1.1.1.1.10.2 tls
1150 1.1.1.1.10.2 tls args.fh = nfh;
1151 1.1.1.1.10.2 tls error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1152 1.1.1.1.10.2 tls dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1153 1.1.1.1.10.2 tls nametimeo, negnametimeo, minvers);
1154 1.1.1.1.10.2 tls out:
1155 1.1.1.1.10.2 tls if (!error) {
1156 1.1.1.1.10.2 tls MNT_ILOCK(mp);
1157 1.1.1.1.10.2 tls mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF;
1158 1.1.1.1.10.2 tls MNT_IUNLOCK(mp);
1159 1.1.1.1.10.2 tls }
1160 1.1.1.1.10.2 tls return (error);
1161 1.1.1.1.10.2 tls }
1162 1.1.1.1.10.2 tls
1163 1.1.1.1.10.2 tls
1164 1.1.1.1.10.2 tls /*
1165 1.1.1.1.10.2 tls * VFS Operations.
1166 1.1.1.1.10.2 tls *
1167 1.1.1.1.10.2 tls * mount system call
1168 1.1.1.1.10.2 tls * It seems a bit dumb to copyinstr() the host and path here and then
1169 1.1.1.1.10.2 tls * bcopy() them in mountnfs(), but I wanted to detect errors before
1170 1.1.1.1.10.2 tls * doing the sockargs() call because sockargs() allocates an mbuf and
1171 1.1.1.1.10.2 tls * an error after that means that I have to release the mbuf.
1172 1.1.1.1.10.2 tls */
1173 1.1.1.1.10.2 tls /* ARGSUSED */
1174 1.1.1.1.10.2 tls static int
1175 1.1.1.1.10.2 tls nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1176 1.1.1.1.10.2 tls {
1177 1.1.1.1.10.2 tls int error;
1178 1.1.1.1.10.2 tls struct nfs_args args;
1179 1.1.1.1.10.2 tls
1180 1.1.1.1.10.2 tls error = copyin(data, &args, sizeof (struct nfs_args));
1181 1.1.1.1.10.2 tls if (error)
1182 1.1.1.1.10.2 tls return error;
1183 1.1.1.1.10.2 tls
1184 1.1.1.1.10.2 tls ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1185 1.1.1.1.10.2 tls
1186 1.1.1.1.10.2 tls error = kernel_mount(ma, flags);
1187 1.1.1.1.10.2 tls return (error);
1188 1.1.1.1.10.2 tls }
1189 1.1.1.1.10.2 tls
1190 1.1.1.1.10.2 tls /*
1191 1.1.1.1.10.2 tls * Common code for mount and mountroot
1192 1.1.1.1.10.2 tls */
1193 1.1.1.1.10.2 tls static int
1194 1.1.1.1.10.2 tls mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1195 1.1.1.1.10.2 tls char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1196 1.1.1.1.10.2 tls u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1197 1.1.1.1.10.2 tls struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
1198 1.1.1.1.10.2 tls int minvers)
1199 1.1.1.1.10.2 tls {
1200 1.1.1.1.10.2 tls struct nfsmount *nmp;
1201 1.1.1.1.10.2 tls struct nfsnode *np;
1202 1.1.1.1.10.2 tls int error, trycnt, ret;
1203 1.1.1.1.10.2 tls struct nfsvattr nfsva;
1204 1.1.1.1.10.2 tls struct nfsclclient *clp;
1205 1.1.1.1.10.2 tls struct nfsclds *dsp, *tdsp;
1206 1.1.1.1.10.2 tls uint32_t lease;
1207 1.1.1.1.10.2 tls static u_int64_t clval = 0;
1208 1.1.1.1.10.2 tls
1209 1.1.1.1.10.2 tls NFSCL_DEBUG(3, "in mnt\n");
1210 1.1.1.1.10.2 tls clp = NULL;
1211 1.1.1.1.10.2 tls if (mp->mnt_flag & MNT_UPDATE) {
1212 1.1.1.1.10.2 tls nmp = VFSTONFS(mp);
1213 1.1.1.1.10.2 tls printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1214 1.1.1.1.10.2 tls FREE(nam, M_SONAME);
1215 1.1.1.1.10.2 tls return (0);
1216 1.1.1.1.10.2 tls } else {
1217 1.1.1.1.10.2 tls MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) +
1218 1.1.1.1.10.2 tls krbnamelen + dirlen + srvkrbnamelen + 2,
1219 1.1.1.1.10.2 tls M_NEWNFSMNT, M_WAITOK | M_ZERO);
1220 1.1.1.1.10.2 tls TAILQ_INIT(&nmp->nm_bufq);
1221 1.1.1.1.10.2 tls if (clval == 0)
1222 1.1.1.1.10.2 tls clval = (u_int64_t)nfsboottime.tv_sec;
1223 1.1.1.1.10.2 tls nmp->nm_clval = clval++;
1224 1.1.1.1.10.2 tls nmp->nm_krbnamelen = krbnamelen;
1225 1.1.1.1.10.2 tls nmp->nm_dirpathlen = dirlen;
1226 1.1.1.1.10.2 tls nmp->nm_srvkrbnamelen = srvkrbnamelen;
1227 1.1.1.1.10.2 tls if (td->td_ucred->cr_uid != (uid_t)0) {
1228 1.1.1.1.10.2 tls /*
1229 1.1.1.1.10.2 tls * nm_uid is used to get KerberosV credentials for
1230 1.1.1.1.10.2 tls * the nfsv4 state handling operations if there is
1231 1.1.1.1.10.2 tls * no host based principal set. Use the uid of
1232 1.1.1.1.10.2 tls * this user if not root, since they are doing the
1233 1.1.1.1.10.2 tls * mount. I don't think setting this for root will
1234 1.1.1.1.10.2 tls * work, since root normally does not have user
1235 1.1.1.1.10.2 tls * credentials in a credentials cache.
1236 1.1.1.1.10.2 tls */
1237 1.1.1.1.10.2 tls nmp->nm_uid = td->td_ucred->cr_uid;
1238 1.1.1.1.10.2 tls } else {
1239 1.1.1.1.10.2 tls /*
1240 1.1.1.1.10.2 tls * Just set to -1, so it won't be used.
1241 1.1.1.1.10.2 tls */
1242 1.1.1.1.10.2 tls nmp->nm_uid = (uid_t)-1;
1243 1.1.1.1.10.2 tls }
1244 1.1.1.1.10.2 tls
1245 1.1.1.1.10.2 tls /* Copy and null terminate all the names */
1246 1.1.1.1.10.2 tls if (nmp->nm_krbnamelen > 0) {
1247 1.1.1.1.10.2 tls bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1248 1.1.1.1.10.2 tls nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1249 1.1.1.1.10.2 tls }
1250 1.1.1.1.10.2 tls if (nmp->nm_dirpathlen > 0) {
1251 1.1.1.1.10.2 tls bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1252 1.1.1.1.10.2 tls nmp->nm_dirpathlen);
1253 1.1.1.1.10.2 tls nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1254 1.1.1.1.10.2 tls + 1] = '\0';
1255 1.1.1.1.10.2 tls }
1256 1.1.1.1.10.2 tls if (nmp->nm_srvkrbnamelen > 0) {
1257 1.1.1.1.10.2 tls bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1258 1.1.1.1.10.2 tls nmp->nm_srvkrbnamelen);
1259 1.1.1.1.10.2 tls nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1260 1.1.1.1.10.2 tls + nmp->nm_srvkrbnamelen + 2] = '\0';
1261 1.1.1.1.10.2 tls }
1262 1.1.1.1.10.2 tls nmp->nm_sockreq.nr_cred = crhold(cred);
1263 1.1.1.1.10.2 tls mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1264 1.1.1.1.10.2 tls mp->mnt_data = nmp;
1265 1.1.1.1.10.2 tls nmp->nm_getinfo = nfs_getnlminfo;
1266 1.1.1.1.10.2 tls nmp->nm_vinvalbuf = ncl_vinvalbuf;
1267 1.1.1.1.10.2 tls }
1268 1.1.1.1.10.2 tls vfs_getnewfsid(mp);
1269 1.1.1.1.10.2 tls nmp->nm_mountp = mp;
1270 1.1.1.1.10.2 tls mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1271 1.1.1.1.10.2 tls
1272 1.1.1.1.10.2 tls /*
1273 1.1.1.1.10.2 tls * Since nfs_decode_args() might optionally set them, these
1274 1.1.1.1.10.2 tls * need to be set to defaults before the call, so that the
1275 1.1.1.1.10.2 tls * optional settings aren't overwritten.
1276 1.1.1.1.10.2 tls */
1277 1.1.1.1.10.2 tls nmp->nm_nametimeo = nametimeo;
1278 1.1.1.1.10.2 tls nmp->nm_negnametimeo = negnametimeo;
1279 1.1.1.1.10.2 tls nmp->nm_timeo = NFS_TIMEO;
1280 1.1.1.1.10.2 tls nmp->nm_retry = NFS_RETRANS;
1281 1.1.1.1.10.2 tls nmp->nm_readahead = NFS_DEFRAHEAD;
1282 1.1.1.1.10.2 tls if (desiredvnodes >= 11000)
1283 1.1.1.1.10.2 tls nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1284 1.1.1.1.10.2 tls else
1285 1.1.1.1.10.2 tls nmp->nm_wcommitsize = hibufspace / 10;
1286 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_NFSV4) != 0)
1287 1.1.1.1.10.2 tls nmp->nm_minorvers = minvers;
1288 1.1.1.1.10.2 tls else
1289 1.1.1.1.10.2 tls nmp->nm_minorvers = 0;
1290 1.1.1.1.10.2 tls
1291 1.1.1.1.10.2 tls nfs_decode_args(mp, nmp, argp, hst, cred, td);
1292 1.1.1.1.10.2 tls
1293 1.1.1.1.10.2 tls /*
1294 1.1.1.1.10.2 tls * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1295 1.1.1.1.10.2 tls * high, depending on whether we end up with negative offsets in
1296 1.1.1.1.10.2 tls * the client or server somewhere. 2GB-1 may be safer.
1297 1.1.1.1.10.2 tls *
1298 1.1.1.1.10.2 tls * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum
1299 1.1.1.1.10.2 tls * that we can handle until we find out otherwise.
1300 1.1.1.1.10.2 tls */
1301 1.1.1.1.10.2 tls if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1302 1.1.1.1.10.2 tls nmp->nm_maxfilesize = 0xffffffffLL;
1303 1.1.1.1.10.2 tls else
1304 1.1.1.1.10.2 tls nmp->nm_maxfilesize = OFF_MAX;
1305 1.1.1.1.10.2 tls
1306 1.1.1.1.10.2 tls if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1307 1.1.1.1.10.2 tls nmp->nm_wsize = NFS_WSIZE;
1308 1.1.1.1.10.2 tls nmp->nm_rsize = NFS_RSIZE;
1309 1.1.1.1.10.2 tls nmp->nm_readdirsize = NFS_READDIRSIZE;
1310 1.1.1.1.10.2 tls }
1311 1.1.1.1.10.2 tls nmp->nm_numgrps = NFS_MAXGRPS;
1312 1.1.1.1.10.2 tls nmp->nm_tprintf_delay = nfs_tprintf_delay;
1313 1.1.1.1.10.2 tls if (nmp->nm_tprintf_delay < 0)
1314 1.1.1.1.10.2 tls nmp->nm_tprintf_delay = 0;
1315 1.1.1.1.10.2 tls nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1316 1.1.1.1.10.2 tls if (nmp->nm_tprintf_initial_delay < 0)
1317 1.1.1.1.10.2 tls nmp->nm_tprintf_initial_delay = 0;
1318 1.1.1.1.10.2 tls nmp->nm_fhsize = argp->fhsize;
1319 1.1.1.1.10.2 tls if (nmp->nm_fhsize > 0)
1320 1.1.1.1.10.2 tls bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1321 1.1.1.1.10.2 tls bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1322 1.1.1.1.10.2 tls nmp->nm_nam = nam;
1323 1.1.1.1.10.2 tls /* Set up the sockets and per-host congestion */
1324 1.1.1.1.10.2 tls nmp->nm_sotype = argp->sotype;
1325 1.1.1.1.10.2 tls nmp->nm_soproto = argp->proto;
1326 1.1.1.1.10.2 tls nmp->nm_sockreq.nr_prog = NFS_PROG;
1327 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_NFSV4))
1328 1.1.1.1.10.2 tls nmp->nm_sockreq.nr_vers = NFS_VER4;
1329 1.1.1.1.10.2 tls else if ((argp->flags & NFSMNT_NFSV3))
1330 1.1.1.1.10.2 tls nmp->nm_sockreq.nr_vers = NFS_VER3;
1331 1.1.1.1.10.2 tls else
1332 1.1.1.1.10.2 tls nmp->nm_sockreq.nr_vers = NFS_VER2;
1333 1.1.1.1.10.2 tls
1334 1.1.1.1.10.2 tls
1335 1.1.1.1.10.2 tls if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
1336 1.1.1.1.10.2 tls goto bad;
1337 1.1.1.1.10.2 tls /* For NFSv4.1, get the clientid now. */
1338 1.1.1.1.10.2 tls if (nmp->nm_minorvers > 0) {
1339 1.1.1.1.10.2 tls NFSCL_DEBUG(3, "at getcl\n");
1340 1.1.1.1.10.2 tls error = nfscl_getcl(mp, cred, td, 0, &clp);
1341 1.1.1.1.10.2 tls NFSCL_DEBUG(3, "aft getcl=%d\n", error);
1342 1.1.1.1.10.2 tls if (error != 0)
1343 1.1.1.1.10.2 tls goto bad;
1344 1.1.1.1.10.2 tls }
1345 1.1.1.1.10.2 tls
1346 1.1.1.1.10.2 tls if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1347 1.1.1.1.10.2 tls nmp->nm_dirpathlen > 0) {
1348 1.1.1.1.10.2 tls NFSCL_DEBUG(3, "in dirp\n");
1349 1.1.1.1.10.2 tls /*
1350 1.1.1.1.10.2 tls * If the fhsize on the mount point == 0 for V4, the mount
1351 1.1.1.1.10.2 tls * path needs to be looked up.
1352 1.1.1.1.10.2 tls */
1353 1.1.1.1.10.2 tls trycnt = 3;
1354 1.1.1.1.10.2 tls do {
1355 1.1.1.1.10.2 tls error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1356 1.1.1.1.10.2 tls cred, td);
1357 1.1.1.1.10.2 tls NFSCL_DEBUG(3, "aft dirp=%d\n", error);
1358 1.1.1.1.10.2 tls if (error)
1359 1.1.1.1.10.2 tls (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1360 1.1.1.1.10.2 tls } while (error && --trycnt > 0);
1361 1.1.1.1.10.2 tls if (error) {
1362 1.1.1.1.10.2 tls error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
1363 1.1.1.1.10.2 tls goto bad;
1364 1.1.1.1.10.2 tls }
1365 1.1.1.1.10.2 tls }
1366 1.1.1.1.10.2 tls
1367 1.1.1.1.10.2 tls /*
1368 1.1.1.1.10.2 tls * A reference count is needed on the nfsnode representing the
1369 1.1.1.1.10.2 tls * remote root. If this object is not persistent, then backward
1370 1.1.1.1.10.2 tls * traversals of the mount point (i.e. "..") will not work if
1371 1.1.1.1.10.2 tls * the nfsnode gets flushed out of the cache. Ufs does not have
1372 1.1.1.1.10.2 tls * this problem, because one can identify root inodes by their
1373 1.1.1.1.10.2 tls * number == ROOTINO (2).
1374 1.1.1.1.10.2 tls */
1375 1.1.1.1.10.2 tls if (nmp->nm_fhsize > 0) {
1376 1.1.1.1.10.2 tls /*
1377 1.1.1.1.10.2 tls * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1378 1.1.1.1.10.2 tls * non-zero for the root vnode. f_iosize will be set correctly
1379 1.1.1.1.10.2 tls * by nfs_statfs() before any I/O occurs.
1380 1.1.1.1.10.2 tls */
1381 1.1.1.1.10.2 tls mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1382 1.1.1.1.10.2 tls error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1383 1.1.1.1.10.2 tls LK_EXCLUSIVE);
1384 1.1.1.1.10.2 tls if (error)
1385 1.1.1.1.10.2 tls goto bad;
1386 1.1.1.1.10.2 tls *vpp = NFSTOV(np);
1387 1.1.1.1.10.2 tls
1388 1.1.1.1.10.2 tls /*
1389 1.1.1.1.10.2 tls * Get file attributes and transfer parameters for the
1390 1.1.1.1.10.2 tls * mountpoint. This has the side effect of filling in
1391 1.1.1.1.10.2 tls * (*vpp)->v_type with the correct value.
1392 1.1.1.1.10.2 tls */
1393 1.1.1.1.10.2 tls ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1394 1.1.1.1.10.2 tls cred, td, &nfsva, NULL, &lease);
1395 1.1.1.1.10.2 tls if (ret) {
1396 1.1.1.1.10.2 tls /*
1397 1.1.1.1.10.2 tls * Just set default values to get things going.
1398 1.1.1.1.10.2 tls */
1399 1.1.1.1.10.2 tls NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1400 1.1.1.1.10.2 tls nfsva.na_vattr.va_type = VDIR;
1401 1.1.1.1.10.2 tls nfsva.na_vattr.va_mode = 0777;
1402 1.1.1.1.10.2 tls nfsva.na_vattr.va_nlink = 100;
1403 1.1.1.1.10.2 tls nfsva.na_vattr.va_uid = (uid_t)0;
1404 1.1.1.1.10.2 tls nfsva.na_vattr.va_gid = (gid_t)0;
1405 1.1.1.1.10.2 tls nfsva.na_vattr.va_fileid = 2;
1406 1.1.1.1.10.2 tls nfsva.na_vattr.va_gen = 1;
1407 1.1.1.1.10.2 tls nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1408 1.1.1.1.10.2 tls nfsva.na_vattr.va_size = 512 * 1024;
1409 1.1.1.1.10.2 tls lease = 60;
1410 1.1.1.1.10.2 tls }
1411 1.1.1.1.10.2 tls (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1412 1.1.1.1.10.2 tls if (nmp->nm_minorvers > 0) {
1413 1.1.1.1.10.2 tls NFSCL_DEBUG(3, "lease=%d\n", (int)lease);
1414 1.1.1.1.10.2 tls NFSLOCKCLSTATE();
1415 1.1.1.1.10.2 tls clp->nfsc_renew = NFSCL_RENEW(lease);
1416 1.1.1.1.10.2 tls clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
1417 1.1.1.1.10.2 tls clp->nfsc_clientidrev++;
1418 1.1.1.1.10.2 tls if (clp->nfsc_clientidrev == 0)
1419 1.1.1.1.10.2 tls clp->nfsc_clientidrev++;
1420 1.1.1.1.10.2 tls NFSUNLOCKCLSTATE();
1421 1.1.1.1.10.2 tls /*
1422 1.1.1.1.10.2 tls * Mount will succeed, so the renew thread can be
1423 1.1.1.1.10.2 tls * started now.
1424 1.1.1.1.10.2 tls */
1425 1.1.1.1.10.2 tls nfscl_start_renewthread(clp);
1426 1.1.1.1.10.2 tls nfscl_clientrelease(clp);
1427 1.1.1.1.10.2 tls }
1428 1.1.1.1.10.2 tls if (argp->flags & NFSMNT_NFSV3)
1429 1.1.1.1.10.2 tls ncl_fsinfo(nmp, *vpp, cred, td);
1430 1.1.1.1.10.2 tls
1431 1.1.1.1.10.2 tls /* Mark if the mount point supports NFSv4 ACLs. */
1432 1.1.1.1.10.2 tls if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1433 1.1.1.1.10.2 tls ret == 0 &&
1434 1.1.1.1.10.2 tls NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1435 1.1.1.1.10.2 tls MNT_ILOCK(mp);
1436 1.1.1.1.10.2 tls mp->mnt_flag |= MNT_NFS4ACLS;
1437 1.1.1.1.10.2 tls MNT_IUNLOCK(mp);
1438 1.1.1.1.10.2 tls }
1439 1.1.1.1.10.2 tls
1440 1.1.1.1.10.2 tls /*
1441 1.1.1.1.10.2 tls * Lose the lock but keep the ref.
1442 1.1.1.1.10.2 tls */
1443 1.1.1.1.10.2 tls NFSVOPUNLOCK(*vpp, 0);
1444 1.1.1.1.10.2 tls return (0);
1445 1.1.1.1.10.2 tls }
1446 1.1.1.1.10.2 tls error = EIO;
1447 1.1.1.1.10.2 tls
1448 1.1.1.1.10.2 tls bad:
1449 1.1.1.1.10.2 tls if (clp != NULL)
1450 1.1.1.1.10.2 tls nfscl_clientrelease(clp);
1451 1.1.1.1.10.2 tls newnfs_disconnect(&nmp->nm_sockreq);
1452 1.1.1.1.10.2 tls crfree(nmp->nm_sockreq.nr_cred);
1453 1.1.1.1.10.2 tls if (nmp->nm_sockreq.nr_auth != NULL)
1454 1.1.1.1.10.2 tls AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1455 1.1.1.1.10.2 tls mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1456 1.1.1.1.10.2 tls mtx_destroy(&nmp->nm_mtx);
1457 1.1.1.1.10.2 tls if (nmp->nm_clp != NULL) {
1458 1.1.1.1.10.2 tls NFSLOCKCLSTATE();
1459 1.1.1.1.10.2 tls LIST_REMOVE(nmp->nm_clp, nfsc_list);
1460 1.1.1.1.10.2 tls NFSUNLOCKCLSTATE();
1461 1.1.1.1.10.2 tls free(nmp->nm_clp, M_NFSCLCLIENT);
1462 1.1.1.1.10.2 tls }
1463 1.1.1.1.10.2 tls TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp)
1464 1.1.1.1.10.2 tls nfscl_freenfsclds(dsp);
1465 1.1.1.1.10.2 tls FREE(nmp, M_NEWNFSMNT);
1466 1.1.1.1.10.2 tls FREE(nam, M_SONAME);
1467 1.1.1.1.10.2 tls return (error);
1468 1.1.1.1.10.2 tls }
1469 1.1.1.1.10.2 tls
1470 1.1.1.1.10.2 tls /*
1471 1.1.1.1.10.2 tls * unmount system call
1472 1.1.1.1.10.2 tls */
1473 1.1.1.1.10.2 tls static int
1474 1.1.1.1.10.2 tls nfs_unmount(struct mount *mp, int mntflags)
1475 1.1.1.1.10.2 tls {
1476 1.1.1.1.10.2 tls struct thread *td;
1477 1.1.1.1.10.2 tls struct nfsmount *nmp;
1478 1.1.1.1.10.2 tls int error, flags = 0, i, trycnt = 0;
1479 1.1.1.1.10.2 tls struct nfsclds *dsp, *tdsp;
1480 1.1.1.1.10.2 tls
1481 1.1.1.1.10.2 tls td = curthread;
1482 1.1.1.1.10.2 tls
1483 1.1.1.1.10.2 tls if (mntflags & MNT_FORCE)
1484 1.1.1.1.10.2 tls flags |= FORCECLOSE;
1485 1.1.1.1.10.2 tls nmp = VFSTONFS(mp);
1486 1.1.1.1.10.2 tls /*
1487 1.1.1.1.10.2 tls * Goes something like this..
1488 1.1.1.1.10.2 tls * - Call vflush() to clear out vnodes for this filesystem
1489 1.1.1.1.10.2 tls * - Close the socket
1490 1.1.1.1.10.2 tls * - Free up the data structures
1491 1.1.1.1.10.2 tls */
1492 1.1.1.1.10.2 tls /* In the forced case, cancel any outstanding requests. */
1493 1.1.1.1.10.2 tls if (mntflags & MNT_FORCE) {
1494 1.1.1.1.10.2 tls error = newnfs_nmcancelreqs(nmp);
1495 1.1.1.1.10.2 tls if (error)
1496 1.1.1.1.10.2 tls goto out;
1497 1.1.1.1.10.2 tls /* For a forced close, get rid of the renew thread now */
1498 1.1.1.1.10.2 tls nfscl_umount(nmp, td);
1499 1.1.1.1.10.2 tls }
1500 1.1.1.1.10.2 tls /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1501 1.1.1.1.10.2 tls do {
1502 1.1.1.1.10.2 tls error = vflush(mp, 1, flags, td);
1503 1.1.1.1.10.2 tls if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1504 1.1.1.1.10.2 tls (void) nfs_catnap(PSOCK, error, "newndm");
1505 1.1.1.1.10.2 tls } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1506 1.1.1.1.10.2 tls if (error)
1507 1.1.1.1.10.2 tls goto out;
1508 1.1.1.1.10.2 tls
1509 1.1.1.1.10.2 tls /*
1510 1.1.1.1.10.2 tls * We are now committed to the unmount.
1511 1.1.1.1.10.2 tls */
1512 1.1.1.1.10.2 tls if ((mntflags & MNT_FORCE) == 0)
1513 1.1.1.1.10.2 tls nfscl_umount(nmp, td);
1514 1.1.1.1.10.2 tls /* Make sure no nfsiods are assigned to this mount. */
1515 1.1.1.1.10.2 tls mtx_lock(&ncl_iod_mutex);
1516 1.1.1.1.10.2 tls for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1517 1.1.1.1.10.2 tls if (ncl_iodmount[i] == nmp) {
1518 1.1.1.1.10.2 tls ncl_iodwant[i] = NFSIOD_AVAILABLE;
1519 1.1.1.1.10.2 tls ncl_iodmount[i] = NULL;
1520 1.1.1.1.10.2 tls }
1521 1.1.1.1.10.2 tls mtx_unlock(&ncl_iod_mutex);
1522 1.1.1.1.10.2 tls newnfs_disconnect(&nmp->nm_sockreq);
1523 1.1.1.1.10.2 tls crfree(nmp->nm_sockreq.nr_cred);
1524 1.1.1.1.10.2 tls FREE(nmp->nm_nam, M_SONAME);
1525 1.1.1.1.10.2 tls if (nmp->nm_sockreq.nr_auth != NULL)
1526 1.1.1.1.10.2 tls AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1527 1.1.1.1.10.2 tls mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1528 1.1.1.1.10.2 tls mtx_destroy(&nmp->nm_mtx);
1529 1.1.1.1.10.2 tls TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp)
1530 1.1.1.1.10.2 tls nfscl_freenfsclds(dsp);
1531 1.1.1.1.10.2 tls FREE(nmp, M_NEWNFSMNT);
1532 1.1.1.1.10.2 tls out:
1533 1.1.1.1.10.2 tls return (error);
1534 1.1.1.1.10.2 tls }
1535 1.1.1.1.10.2 tls
1536 1.1.1.1.10.2 tls /*
1537 1.1.1.1.10.2 tls * Return root of a filesystem
1538 1.1.1.1.10.2 tls */
1539 1.1.1.1.10.2 tls static int
1540 1.1.1.1.10.2 tls nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1541 1.1.1.1.10.2 tls {
1542 1.1.1.1.10.2 tls struct vnode *vp;
1543 1.1.1.1.10.2 tls struct nfsmount *nmp;
1544 1.1.1.1.10.2 tls struct nfsnode *np;
1545 1.1.1.1.10.2 tls int error;
1546 1.1.1.1.10.2 tls
1547 1.1.1.1.10.2 tls nmp = VFSTONFS(mp);
1548 1.1.1.1.10.2 tls error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1549 1.1.1.1.10.2 tls if (error)
1550 1.1.1.1.10.2 tls return error;
1551 1.1.1.1.10.2 tls vp = NFSTOV(np);
1552 1.1.1.1.10.2 tls /*
1553 1.1.1.1.10.2 tls * Get transfer parameters and attributes for root vnode once.
1554 1.1.1.1.10.2 tls */
1555 1.1.1.1.10.2 tls mtx_lock(&nmp->nm_mtx);
1556 1.1.1.1.10.2 tls if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1557 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
1558 1.1.1.1.10.2 tls ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1559 1.1.1.1.10.2 tls } else
1560 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
1561 1.1.1.1.10.2 tls if (vp->v_type == VNON)
1562 1.1.1.1.10.2 tls vp->v_type = VDIR;
1563 1.1.1.1.10.2 tls vp->v_vflag |= VV_ROOT;
1564 1.1.1.1.10.2 tls *vpp = vp;
1565 1.1.1.1.10.2 tls return (0);
1566 1.1.1.1.10.2 tls }
1567 1.1.1.1.10.2 tls
1568 1.1.1.1.10.2 tls /*
1569 1.1.1.1.10.2 tls * Flush out the buffer cache
1570 1.1.1.1.10.2 tls */
1571 1.1.1.1.10.2 tls /* ARGSUSED */
1572 1.1.1.1.10.2 tls static int
1573 1.1.1.1.10.2 tls nfs_sync(struct mount *mp, int waitfor)
1574 1.1.1.1.10.2 tls {
1575 1.1.1.1.10.2 tls struct vnode *vp, *mvp;
1576 1.1.1.1.10.2 tls struct thread *td;
1577 1.1.1.1.10.2 tls int error, allerror = 0;
1578 1.1.1.1.10.2 tls
1579 1.1.1.1.10.2 tls td = curthread;
1580 1.1.1.1.10.2 tls
1581 1.1.1.1.10.2 tls MNT_ILOCK(mp);
1582 1.1.1.1.10.2 tls /*
1583 1.1.1.1.10.2 tls * If a forced dismount is in progress, return from here so that
1584 1.1.1.1.10.2 tls * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1585 1.1.1.1.10.2 tls * calling VFS_UNMOUNT().
1586 1.1.1.1.10.2 tls */
1587 1.1.1.1.10.2 tls if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
1588 1.1.1.1.10.2 tls MNT_IUNLOCK(mp);
1589 1.1.1.1.10.2 tls return (EBADF);
1590 1.1.1.1.10.2 tls }
1591 1.1.1.1.10.2 tls MNT_IUNLOCK(mp);
1592 1.1.1.1.10.2 tls
1593 1.1.1.1.10.2 tls /*
1594 1.1.1.1.10.2 tls * Force stale buffer cache information to be flushed.
1595 1.1.1.1.10.2 tls */
1596 1.1.1.1.10.2 tls loop:
1597 1.1.1.1.10.2 tls MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1598 1.1.1.1.10.2 tls /* XXX Racy bv_cnt check. */
1599 1.1.1.1.10.2 tls if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1600 1.1.1.1.10.2 tls waitfor == MNT_LAZY) {
1601 1.1.1.1.10.2 tls VI_UNLOCK(vp);
1602 1.1.1.1.10.2 tls continue;
1603 1.1.1.1.10.2 tls }
1604 1.1.1.1.10.2 tls if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1605 1.1.1.1.10.2 tls MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1606 1.1.1.1.10.2 tls goto loop;
1607 1.1.1.1.10.2 tls }
1608 1.1.1.1.10.2 tls error = VOP_FSYNC(vp, waitfor, td);
1609 1.1.1.1.10.2 tls if (error)
1610 1.1.1.1.10.2 tls allerror = error;
1611 1.1.1.1.10.2 tls NFSVOPUNLOCK(vp, 0);
1612 1.1.1.1.10.2 tls vrele(vp);
1613 1.1.1.1.10.2 tls }
1614 1.1.1.1.10.2 tls return (allerror);
1615 1.1.1.1.10.2 tls }
1616 1.1.1.1.10.2 tls
1617 1.1.1.1.10.2 tls static int
1618 1.1.1.1.10.2 tls nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1619 1.1.1.1.10.2 tls {
1620 1.1.1.1.10.2 tls struct nfsmount *nmp = VFSTONFS(mp);
1621 1.1.1.1.10.2 tls struct vfsquery vq;
1622 1.1.1.1.10.2 tls int error;
1623 1.1.1.1.10.2 tls
1624 1.1.1.1.10.2 tls bzero(&vq, sizeof(vq));
1625 1.1.1.1.10.2 tls switch (op) {
1626 1.1.1.1.10.2 tls #if 0
1627 1.1.1.1.10.2 tls case VFS_CTL_NOLOCKS:
1628 1.1.1.1.10.2 tls val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1629 1.1.1.1.10.2 tls if (req->oldptr != NULL) {
1630 1.1.1.1.10.2 tls error = SYSCTL_OUT(req, &val, sizeof(val));
1631 1.1.1.1.10.2 tls if (error)
1632 1.1.1.1.10.2 tls return (error);
1633 1.1.1.1.10.2 tls }
1634 1.1.1.1.10.2 tls if (req->newptr != NULL) {
1635 1.1.1.1.10.2 tls error = SYSCTL_IN(req, &val, sizeof(val));
1636 1.1.1.1.10.2 tls if (error)
1637 1.1.1.1.10.2 tls return (error);
1638 1.1.1.1.10.2 tls if (val)
1639 1.1.1.1.10.2 tls nmp->nm_flag |= NFSMNT_NOLOCKS;
1640 1.1.1.1.10.2 tls else
1641 1.1.1.1.10.2 tls nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1642 1.1.1.1.10.2 tls }
1643 1.1.1.1.10.2 tls break;
1644 1.1.1.1.10.2 tls #endif
1645 1.1.1.1.10.2 tls case VFS_CTL_QUERY:
1646 1.1.1.1.10.2 tls mtx_lock(&nmp->nm_mtx);
1647 1.1.1.1.10.2 tls if (nmp->nm_state & NFSSTA_TIMEO)
1648 1.1.1.1.10.2 tls vq.vq_flags |= VQ_NOTRESP;
1649 1.1.1.1.10.2 tls mtx_unlock(&nmp->nm_mtx);
1650 1.1.1.1.10.2 tls #if 0
1651 1.1.1.1.10.2 tls if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1652 1.1.1.1.10.2 tls (nmp->nm_state & NFSSTA_LOCKTIMEO))
1653 1.1.1.1.10.2 tls vq.vq_flags |= VQ_NOTRESPLOCK;
1654 1.1.1.1.10.2 tls #endif
1655 1.1.1.1.10.2 tls error = SYSCTL_OUT(req, &vq, sizeof(vq));
1656 1.1.1.1.10.2 tls break;
1657 1.1.1.1.10.2 tls case VFS_CTL_TIMEO:
1658 1.1.1.1.10.2 tls if (req->oldptr != NULL) {
1659 1.1.1.1.10.2 tls error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1660 1.1.1.1.10.2 tls sizeof(nmp->nm_tprintf_initial_delay));
1661 1.1.1.1.10.2 tls if (error)
1662 1.1.1.1.10.2 tls return (error);
1663 1.1.1.1.10.2 tls }
1664 1.1.1.1.10.2 tls if (req->newptr != NULL) {
1665 1.1.1.1.10.2 tls error = vfs_suser(mp, req->td);
1666 1.1.1.1.10.2 tls if (error)
1667 1.1.1.1.10.2 tls return (error);
1668 1.1.1.1.10.2 tls error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1669 1.1.1.1.10.2 tls sizeof(nmp->nm_tprintf_initial_delay));
1670 1.1.1.1.10.2 tls if (error)
1671 1.1.1.1.10.2 tls return (error);
1672 1.1.1.1.10.2 tls if (nmp->nm_tprintf_initial_delay < 0)
1673 1.1.1.1.10.2 tls nmp->nm_tprintf_initial_delay = 0;
1674 1.1.1.1.10.2 tls }
1675 1.1.1.1.10.2 tls break;
1676 1.1.1.1.10.2 tls default:
1677 1.1.1.1.10.2 tls return (ENOTSUP);
1678 1.1.1.1.10.2 tls }
1679 1.1.1.1.10.2 tls return (0);
1680 1.1.1.1.10.2 tls }
1681 1.1.1.1.10.2 tls
1682 1.1.1.1.10.2 tls /*
1683 1.1.1.1.10.2 tls * Purge any RPCs in progress, so that they will all return errors.
1684 1.1.1.1.10.2 tls * This allows dounmount() to continue as far as VFS_UNMOUNT() for a
1685 1.1.1.1.10.2 tls * forced dismount.
1686 1.1.1.1.10.2 tls */
1687 1.1.1.1.10.2 tls static void
1688 1.1.1.1.10.2 tls nfs_purge(struct mount *mp)
1689 1.1.1.1.10.2 tls {
1690 1.1.1.1.10.2 tls struct nfsmount *nmp = VFSTONFS(mp);
1691 1.1.1.1.10.2 tls
1692 1.1.1.1.10.2 tls newnfs_nmcancelreqs(nmp);
1693 1.1.1.1.10.2 tls }
1694 1.1.1.1.10.2 tls
1695 1.1.1.1.10.2 tls /*
1696 1.1.1.1.10.2 tls * Extract the information needed by the nlm from the nfs vnode.
1697 1.1.1.1.10.2 tls */
1698 1.1.1.1.10.2 tls static void
1699 1.1.1.1.10.2 tls nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1700 1.1.1.1.10.2 tls struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1701 1.1.1.1.10.2 tls struct timeval *timeop)
1702 1.1.1.1.10.2 tls {
1703 1.1.1.1.10.2 tls struct nfsmount *nmp;
1704 1.1.1.1.10.2 tls struct nfsnode *np = VTONFS(vp);
1705 1.1.1.1.10.2 tls
1706 1.1.1.1.10.2 tls nmp = VFSTONFS(vp->v_mount);
1707 1.1.1.1.10.2 tls if (fhlenp != NULL)
1708 1.1.1.1.10.2 tls *fhlenp = (size_t)np->n_fhp->nfh_len;
1709 1.1.1.1.10.2 tls if (fhp != NULL)
1710 1.1.1.1.10.2 tls bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1711 1.1.1.1.10.2 tls if (sp != NULL)
1712 1.1.1.1.10.2 tls bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1713 1.1.1.1.10.2 tls if (is_v3p != NULL)
1714 1.1.1.1.10.2 tls *is_v3p = NFS_ISV3(vp);
1715 1.1.1.1.10.2 tls if (sizep != NULL)
1716 1.1.1.1.10.2 tls *sizep = np->n_size;
1717 1.1.1.1.10.2 tls if (timeop != NULL) {
1718 1.1.1.1.10.2 tls timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1719 1.1.1.1.10.2 tls timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1720 1.1.1.1.10.2 tls }
1721 1.1.1.1.10.2 tls }
1722 1.1.1.1.10.2 tls
1723 1.1.1.1.10.2 tls /*
1724 1.1.1.1.10.2 tls * This function prints out an option name, based on the conditional
1725 1.1.1.1.10.2 tls * argument.
1726 1.1.1.1.10.2 tls */
1727 1.1.1.1.10.2 tls static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
1728 1.1.1.1.10.2 tls char *opt, char **buf, size_t *blen)
1729 1.1.1.1.10.2 tls {
1730 1.1.1.1.10.2 tls int len;
1731 1.1.1.1.10.2 tls
1732 1.1.1.1.10.2 tls if (testval != 0 && *blen > strlen(opt)) {
1733 1.1.1.1.10.2 tls len = snprintf(*buf, *blen, "%s", opt);
1734 1.1.1.1.10.2 tls if (len != strlen(opt))
1735 1.1.1.1.10.2 tls printf("EEK!!\n");
1736 1.1.1.1.10.2 tls *buf += len;
1737 1.1.1.1.10.2 tls *blen -= len;
1738 1.1.1.1.10.2 tls }
1739 1.1.1.1.10.2 tls }
1740 1.1.1.1.10.2 tls
1741 1.1.1.1.10.2 tls /*
1742 1.1.1.1.10.2 tls * This function printf out an options integer value.
1743 1.1.1.1.10.2 tls */
1744 1.1.1.1.10.2 tls static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
1745 1.1.1.1.10.2 tls char *opt, char **buf, size_t *blen)
1746 1.1.1.1.10.2 tls {
1747 1.1.1.1.10.2 tls int len;
1748 1.1.1.1.10.2 tls
1749 1.1.1.1.10.2 tls if (*blen > strlen(opt) + 1) {
1750 1.1.1.1.10.2 tls /* Could result in truncated output string. */
1751 1.1.1.1.10.2 tls len = snprintf(*buf, *blen, "%s=%d", opt, optval);
1752 1.1.1.1.10.2 tls if (len < *blen) {
1753 1.1.1.1.10.2 tls *buf += len;
1754 1.1.1.1.10.2 tls *blen -= len;
1755 1.1.1.1.10.2 tls }
1756 1.1.1.1.10.2 tls }
1757 1.1.1.1.10.2 tls }
1758 1.1.1.1.10.2 tls
1759 1.1.1.1.10.2 tls /*
1760 1.1.1.1.10.2 tls * Load the option flags and values into the buffer.
1761 1.1.1.1.10.2 tls */
1762 1.1.1.1.10.2 tls void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
1763 1.1.1.1.10.2 tls {
1764 1.1.1.1.10.2 tls char *buf;
1765 1.1.1.1.10.2 tls size_t blen;
1766 1.1.1.1.10.2 tls
1767 1.1.1.1.10.2 tls buf = buffer;
1768 1.1.1.1.10.2 tls blen = buflen;
1769 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
1770 1.1.1.1.10.2 tls &blen);
1771 1.1.1.1.10.2 tls if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) {
1772 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_minorvers, ",minorversion", &buf,
1773 1.1.1.1.10.2 tls &blen);
1774 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
1775 1.1.1.1.10.2 tls &buf, &blen);
1776 1.1.1.1.10.2 tls }
1777 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
1778 1.1.1.1.10.2 tls &blen);
1779 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
1780 1.1.1.1.10.2 tls "nfsv2", &buf, &blen);
1781 1.1.1.1.10.2 tls nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
1782 1.1.1.1.10.2 tls nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
1783 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
1784 1.1.1.1.10.2 tls &buf, &blen);
1785 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
1786 1.1.1.1.10.2 tls &buf, &blen);
1787 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
1788 1.1.1.1.10.2 tls &blen);
1789 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
1790 1.1.1.1.10.2 tls &blen);
1791 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
1792 1.1.1.1.10.2 tls &blen);
1793 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
1794 1.1.1.1.10.2 tls &blen);
1795 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
1796 1.1.1.1.10.2 tls &blen);
1797 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1798 1.1.1.1.10.2 tls 0, ",lockd", &buf, &blen);
1799 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
1800 1.1.1.1.10.2 tls NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
1801 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
1802 1.1.1.1.10.2 tls &buf, &blen);
1803 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
1804 1.1.1.1.10.2 tls &buf, &blen);
1805 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1806 1.1.1.1.10.2 tls NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
1807 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1808 1.1.1.1.10.2 tls NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
1809 1.1.1.1.10.2 tls &buf, &blen);
1810 1.1.1.1.10.2 tls nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
1811 1.1.1.1.10.2 tls NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
1812 1.1.1.1.10.2 tls &buf, &blen);
1813 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
1814 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
1815 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
1816 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
1817 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
1818 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
1819 1.1.1.1.10.2 tls &blen);
1820 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
1821 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
1822 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
1823 1.1.1.1.10.2 tls &blen);
1824 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
1825 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
1826 1.1.1.1.10.2 tls &blen);
1827 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
1828 1.1.1.1.10.2 tls nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
1829 1.1.1.1.10.2 tls }
1830 1.1.1.1.10.2 tls
1831