2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
40 * Socket operations for use by the nfs server.
44 #include <fs/nfs/nfsport.h>
46 extern struct nfsstatsv1 nfsstatsv1;
47 extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
48 extern int nfs_pubfhset, nfs_rootfhset;
49 extern struct nfsv4lock nfsv4rootfs_lock;
50 extern struct nfsrv_stablefirst nfsrv_stablefirst;
51 extern struct nfsclienthashhead *nfsclienthash;
52 extern int nfsrv_clienthashsize;
53 extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
54 extern int nfsd_debuglevel;
55 extern int nfsrv_layouthighwater;
56 extern volatile int nfsrv_layoutcnt;
60 int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
61 int, vnode_t , struct nfsexstuff *) = {
62 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
65 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
71 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
72 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
73 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
76 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
77 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
86 int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *,
87 int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *) = {
88 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
89 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
90 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
92 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
93 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
94 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
95 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
96 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
100 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
101 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
102 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
103 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
104 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
105 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
106 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
107 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
108 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
109 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
112 int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
113 int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *) = {
114 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
115 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
116 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
117 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
118 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
119 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
120 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
121 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
122 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
123 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
124 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
125 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
126 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
127 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
130 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
131 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
132 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
133 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
134 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
135 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
138 int (*nfsrv4_ops0[NFSV42_NOPS])(struct nfsrv_descript *,
139 int, vnode_t , struct nfsexstuff *) = {
140 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
141 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
142 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
146 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
151 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
155 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
156 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
158 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
159 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
161 nfsrvd_opendowngrade,
162 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
163 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
164 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
169 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
171 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
172 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
176 nfsrvd_setclientidcfrm,
179 nfsrvd_releaselckown,
183 nfsrvd_createsession,
184 nfsrvd_destroysession,
197 nfsrvd_destroyclientid,
198 nfsrvd_reclaimcomplete,
200 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
218 int (*nfsrv4_ops1[NFSV42_NOPS])(struct nfsrv_descript *,
219 int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *) = {
220 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
221 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
222 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
223 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
224 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
225 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
227 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
228 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
229 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
230 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
231 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
232 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
233 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
234 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
237 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
240 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
241 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
242 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
243 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
244 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
245 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
246 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
247 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
248 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
249 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
250 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
251 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
252 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
253 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
254 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
255 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
256 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
257 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
258 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
259 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
260 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
261 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
262 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
263 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
264 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
265 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
266 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
267 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
268 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
269 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
270 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
271 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
272 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
273 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
274 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
275 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
276 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
277 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
278 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
279 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
280 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
281 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
282 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
283 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
284 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
285 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
286 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
287 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
288 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
289 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
290 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
291 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
292 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
293 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
294 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
295 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0,
298 int (*nfsrv4_ops2[NFSV42_NOPS])(struct nfsrv_descript *,
299 int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *) = {
300 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
301 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
302 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
303 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
304 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
305 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
306 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
307 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
308 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
309 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
310 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
312 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
313 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
314 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
315 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
316 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
317 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
318 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
319 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
320 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
321 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
322 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
323 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
324 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
325 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
326 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
327 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
328 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
330 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
331 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
332 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
333 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
334 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
335 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
336 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
337 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
338 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
339 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
340 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
341 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
342 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
343 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
344 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
345 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
346 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
347 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
348 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
349 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
350 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
351 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
352 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
353 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
354 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
355 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
356 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
357 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
358 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
359 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
360 nfsrvd_copy_file_range,
361 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
362 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
363 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
364 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
365 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
366 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
367 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
368 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
369 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
370 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
371 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
372 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
373 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
374 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
375 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
377 #endif /* !APPLEKEXT */
380 * Static array that defines which nfs rpc's are nonidempotent
382 static int nfsrv_nonidempotent[NFS_V3NPROCS] = {
408 * This static array indicates whether or not the RPC modifies the
411 int nfsrv_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
412 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
415 SYSCTL_DECL(_vfs_nfsd);
416 static int nfs_minminorv4 = NFSV4_MINORVERSION;
417 SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_min_minorversion4, CTLFLAG_RWTUN,
419 "The lowest minor version of NFSv4 handled by the server");
421 static int nfs_maxminorv4 = NFSV42_MINORVERSION;
422 SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_max_minorversion4, CTLFLAG_RWTUN,
424 "The highest minor version of NFSv4 handled by the server");
426 /* local functions */
427 static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
428 u_char *tag, int taglen, u_int32_t minorvers);
432 * This static array indicates which server procedures require the extra
433 * arguments to return the current file handle for V2, 3.
435 static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
436 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
438 extern struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS];
440 static int nfsv3to4op[NFS_V3NPROCS] = {
465 static struct mtx nfsrvd_statmtx;
466 MTX_SYSINIT(nfsst, &nfsrvd_statmtx, "NFSstat", MTX_DEF);
469 nfsrvd_statstart(int op, struct bintime *now)
471 if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) {
472 printf("%s: op %d invalid\n", __func__, op);
476 mtx_lock(&nfsrvd_statmtx);
477 if (nfsstatsv1.srvstartcnt == nfsstatsv1.srvdonecnt) {
479 nfsstatsv1.busyfrom = *now;
481 binuptime(&nfsstatsv1.busyfrom);
484 nfsstatsv1.srvrpccnt[op]++;
485 nfsstatsv1.srvstartcnt++;
486 mtx_unlock(&nfsrvd_statmtx);
491 nfsrvd_statend(int op, uint64_t bytes, struct bintime *now,
492 struct bintime *then)
494 struct bintime dt, lnow;
496 if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) {
497 printf("%s: op %d invalid\n", __func__, op);
506 mtx_lock(&nfsrvd_statmtx);
508 nfsstatsv1.srvbytes[op] += bytes;
509 nfsstatsv1.srvops[op]++;
513 bintime_sub(&dt, then);
514 bintime_add(&nfsstatsv1.srvduration[op], &dt);
518 bintime_sub(&dt, &nfsstatsv1.busyfrom);
519 bintime_add(&nfsstatsv1.busytime, &dt);
520 nfsstatsv1.busyfrom = *now;
522 nfsstatsv1.srvdonecnt++;
524 mtx_unlock(&nfsrvd_statmtx);
528 * Do an RPC. Basically, get the file handles translated to vnode pointers
529 * and then call the appropriate server routine. The server routines are
530 * split into groups, based on whether they use a file handle or file
531 * handle plus name or ...
532 * The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
535 nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
538 int error = 0, lktype;
542 struct nfsexstuff nes;
545 * Get a locked vnode for the first file handle
547 if (!(nd->nd_flag & ND_NFSV4)) {
548 KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc"));
550 * For NFSv3, if the malloc/mget allocation is near limits,
551 * return NFSERR_DELAY.
553 if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) {
554 nd->nd_repstat = NFSERR_DELAY;
557 error = nfsrv_mtofh(nd, &fh);
559 if (error != EBADRPC)
560 printf("nfs dorpc err1=%d\n", error);
561 nd->nd_repstat = NFSERR_GARBAGE;
564 if (nd->nd_procnum == NFSPROC_READ ||
565 nd->nd_procnum == NFSPROC_WRITE ||
566 nd->nd_procnum == NFSPROC_READDIR ||
567 nd->nd_procnum == NFSPROC_READDIRPLUS ||
568 nd->nd_procnum == NFSPROC_READLINK ||
569 nd->nd_procnum == NFSPROC_GETATTR ||
570 nd->nd_procnum == NFSPROC_ACCESS ||
571 nd->nd_procnum == NFSPROC_FSSTAT ||
572 nd->nd_procnum == NFSPROC_FSINFO)
575 lktype = LK_EXCLUSIVE;
576 if (nd->nd_flag & ND_PUBLOOKUP)
577 nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
578 &mp, nfsrv_writerpc[nd->nd_procnum]);
580 nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
581 &mp, nfsrv_writerpc[nd->nd_procnum]);
582 if (nd->nd_repstat == NFSERR_PROGNOTV4)
588 * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
589 * cache, as required.
590 * For V4, nfsrvd_compound() does this.
592 if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
593 nd->nd_flag |= ND_SAVEREPLY;
597 * If nd_repstat is non-zero, just fill in the reply status
598 * to complete the RPC reply for V2. Otherwise, you must do
601 if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
602 *nd->nd_errp = nfsd_errmap(nd);
603 nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL);
604 nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
605 /*now*/ NULL, /*then*/ NULL);
606 if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0)
607 vn_finished_write(mp);
612 * Now the procedure can be performed. For V4, nfsrvd_compound()
613 * works through the sub-rpcs, otherwise just call the procedure.
614 * The procedures are in three groups with different arguments.
615 * The group is indicated by the value in nfs_retfh[].
617 if (nd->nd_flag & ND_NFSV4) {
618 nfsrvd_compound(nd, isdgram, tag, taglen, minorvers);
620 struct bintime start_time;
622 binuptime(&start_time);
623 nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], &start_time);
625 if (nfs_retfh[nd->nd_procnum] == 1) {
628 error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
629 vp, NULL, (fhandle_t *)fh.nfsrvfh_data, &nes);
630 } else if (nfs_retfh[nd->nd_procnum] == 2) {
631 error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
632 vp, NULL, &nes, NULL);
634 error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
637 if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0)
638 vn_finished_write(mp);
640 nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
641 /*now*/ NULL, /*then*/ &start_time);
644 if (error != EBADRPC)
645 printf("nfs dorpc err2=%d\n", error);
646 nd->nd_repstat = NFSERR_GARBAGE;
648 *nd->nd_errp = nfsd_errmap(nd);
651 * Don't cache certain reply status values.
653 if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
654 (nd->nd_repstat == NFSERR_GARBAGE ||
655 nd->nd_repstat == NFSERR_BADXDR ||
656 nd->nd_repstat == NFSERR_MOVED ||
657 nd->nd_repstat == NFSERR_DELAY ||
658 nd->nd_repstat == NFSERR_BADSEQID ||
659 nd->nd_repstat == NFSERR_RESOURCE ||
660 nd->nd_repstat == NFSERR_SERVERFAULT ||
661 nd->nd_repstat == NFSERR_STALECLIENTID ||
662 nd->nd_repstat == NFSERR_STALESTATEID ||
663 nd->nd_repstat == NFSERR_OLDSTATEID ||
664 nd->nd_repstat == NFSERR_BADSTATEID ||
665 nd->nd_repstat == NFSERR_GRACE ||
666 nd->nd_repstat == NFSERR_NOGRACE))
667 nd->nd_flag &= ~ND_SAVEREPLY;
674 * Breaks down a compound RPC request and calls the server routines for
676 * Some suboperations are performed directly here to simplify file handle<-->
677 * vnode pointer handling.
680 nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
681 int taglen, u_int32_t minorvers)
683 int i, lktype, op, op0 = 0, statsinprog = 0;
685 struct nfsclient *clp, *nclp;
686 int numops, error = 0, igotlock;
687 u_int32_t retops = 0, *retopsp = NULL, *repp;
688 vnode_t vp, nvp, savevp;
690 mount_t new_mp, temp_mp = NULL;
691 struct ucred *credanon;
692 struct nfsexstuff nes, vpnes, savevpnes;
693 fsid_t cur_fsid, save_fsid;
694 static u_int64_t compref = 0;
695 struct bintime start_time;
700 NFSVNO_EXINIT(&vpnes);
701 NFSVNO_EXINIT(&savevpnes);
703 * Put the seq# of the current compound RPC in nfsrv_descript.
704 * (This is used by nfsrv_checkgetattr(), to see if the write
705 * delegation was created by the same compound RPC as the one
706 * with that Getattr in it.)
707 * Don't worry about the 64bit number wrapping around. It ain't
708 * gonna happen before this server gets shut down/rebooted.
710 nd->nd_compref = compref++;
713 * Check for and optionally get a lock on the root. This lock means that
714 * no nfsd will be fiddling with the V4 file system and state stuff. It
715 * is required when the V4 root is being changed, the stable storage
716 * restart file is being updated, or callbacks are being done.
717 * When any of the nfsd are processing an NFSv4 compound RPC, they must
718 * either hold a reference count (nfs_usecnt) or the lock. When
719 * nfsrv_unlock() is called to release the lock, it can optionally
720 * also get a reference count, which saves the need for a call to
721 * nfsrv_getref() after nfsrv_unlock().
724 * First, check to see if we need to wait for an update lock.
727 NFSLOCKV4ROOTMUTEX();
728 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
729 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
730 NFSV4ROOTLOCKMUTEXPTR, NULL);
732 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
733 NFSV4ROOTLOCKMUTEXPTR, NULL);
734 NFSUNLOCKV4ROOTMUTEX();
737 * If I got the lock, I can update the stable storage file.
738 * Done when the grace period is over or a client has long
741 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
742 if ((nfsrv_stablefirst.nsf_flags &
743 (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
744 nfsrv_updatestable(p);
747 * If at least one client has long since expired, search
748 * the client list for them, write a REVOKE record on the
749 * stable storage file and then remove them from the client
752 if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
753 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
754 for (i = 0; i < nfsrv_clienthashsize; i++) {
755 LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
757 if (clp->lc_flags & LCL_EXPIREIT) {
758 if (!LIST_EMPTY(&clp->lc_open) ||
759 !LIST_EMPTY(&clp->lc_deleg))
760 nfsrv_writestable(clp->lc_id,
761 clp->lc_idlen, NFSNST_REVOKE, p);
762 nfsrv_cleanclient(clp, p);
763 nfsrv_freedeleglist(&clp->lc_deleg);
764 nfsrv_freedeleglist(&clp->lc_olddeleg);
765 LIST_REMOVE(clp, lc_hash);
766 nfsrv_zapclient(clp, p);
771 NFSLOCKV4ROOTMUTEX();
772 nfsv4_unlock(&nfsv4rootfs_lock, 1);
773 NFSUNLOCKV4ROOTMUTEX();
776 * If we didn't get the lock, we need to get a refcnt,
777 * which also checks for and waits for the lock.
779 NFSLOCKV4ROOTMUTEX();
780 nfsv4_getref(&nfsv4rootfs_lock, NULL,
781 NFSV4ROOTLOCKMUTEXPTR, NULL);
782 NFSUNLOCKV4ROOTMUTEX();
786 * If flagged, search for open owners that haven't had any opens
789 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
790 nfsrv_throwawayopens(p);
793 /* Do a CBLAYOUTRECALL callback if over the high water mark. */
794 if (nfsrv_layoutcnt > nfsrv_layouthighwater)
795 nfsrv_recalloldlayout(p);
798 save_fsid.val[0] = save_fsid.val[1] = 0;
799 cur_fsid.val[0] = cur_fsid.val[1] = 0;
801 /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */
807 (void) nfsm_strtom(nd, tag, taglen);
808 NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
809 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
810 if ((minorvers != NFSV4_MINORVERSION &&
811 minorvers != NFSV41_MINORVERSION &&
812 minorvers != NFSV42_MINORVERSION) ||
813 minorvers < nfs_minminorv4 || minorvers > nfs_maxminorv4)
814 nd->nd_repstat = NFSERR_MINORVERMISMATCH;
818 numops = fxdr_unsigned(int, *tl);
820 * Loop around doing the sub ops.
821 * vp - is an unlocked vnode pointer for the CFH
822 * savevp - is an unlocked vnode pointer for the SAVEDFH
823 * (at some future date, it might turn out to be more appropriate
824 * to keep the file handles instead of vnode pointers?)
825 * savevpnes and vpnes - are the export flags for the above.
827 for (i = 0; i < numops; i++) {
828 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
829 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
831 op = fxdr_unsigned(int, *tl);
832 NFSD_DEBUG(4, "op=%d\n", op);
833 if (op < NFSV4OP_ACCESS || op >= NFSV42_NOPS ||
834 (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
835 (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV42) == 0)) {
836 nd->nd_repstat = NFSERR_OPILLEGAL;
837 *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
838 *repp = nfsd_errmap(nd);
845 binuptime(&start_time);
846 nfsrvd_statstart(op, &start_time);
852 nd->nd_flag |= ND_LASTOP;
855 * Check for a referral on the current FH and, if so, return
856 * NFSERR_MOVED for all ops that allow it, except Getattr.
858 if (vp != NULL && op != NFSV4OP_GETATTR &&
859 nfsv4root_getreferral(vp, NULL, 0) != NULL &&
860 nfsrv_errmoved(op)) {
861 nd->nd_repstat = NFSERR_MOVED;
862 *repp = nfsd_errmap(nd);
868 * For NFSv4.1, check for a Sequence Operation being first
869 * or one of the other allowed operations by itself.
871 if ((nd->nd_flag & ND_NFSV41) != 0) {
872 if (i != 0 && op == NFSV4OP_SEQUENCE)
873 nd->nd_repstat = NFSERR_SEQUENCEPOS;
874 else if (i == 0 && op != NFSV4OP_SEQUENCE &&
875 op != NFSV4OP_EXCHANGEID &&
876 op != NFSV4OP_CREATESESSION &&
877 op != NFSV4OP_BINDCONNTOSESS &&
878 op != NFSV4OP_DESTROYCLIENTID &&
879 op != NFSV4OP_DESTROYSESSION)
880 nd->nd_repstat = NFSERR_OPNOTINSESS;
881 else if (i != 0 && op0 != NFSV4OP_SEQUENCE)
882 nd->nd_repstat = NFSERR_NOTONLYOP;
883 if (nd->nd_repstat != 0) {
884 *repp = nfsd_errmap(nd);
892 * If over flood level, reply NFSERR_RESOURCE, if at the first
893 * Op. (Since a client recovery from NFSERR_RESOURCE can get
894 * really nasty for certain Op sequences, I'll play it safe
895 * and only return the error at the beginning.) The cache
896 * will still function over flood level, but uses lots of
898 * If nfsrv_mallocmget_limit() returns True, the system is near
899 * to its limit for memory that malloc()/mget() can allocate.
901 if (i == 0 && (nd->nd_rp == NULL ||
902 nd->nd_rp->rc_refcnt == 0) &&
903 (nfsrv_mallocmget_limit() ||
904 nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
905 if (nfsrc_tcpsavedreplies > nfsrc_floodlevel)
906 printf("nfsd server cache flooded, try "
907 "increasing vfs.nfsd.tcphighwater\n");
908 nd->nd_repstat = NFSERR_RESOURCE;
909 *repp = nfsd_errmap(nd);
910 if (op == NFSV4OP_SETATTR) {
912 * Setattr replies require a bitmap.
913 * even for errors like these.
915 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
921 if (nfsv4_opflag[op].savereply)
922 nd->nd_flag |= ND_SAVEREPLY;
925 error = nfsrv_mtofh(nd, &fh);
929 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
931 /* For now, allow this for non-export FHs */
932 if (!nd->nd_repstat) {
936 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
941 case NFSV4OP_PUTPUBFH:
943 nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
946 nd->nd_repstat = NFSERR_NOFILEHANDLE;
947 if (!nd->nd_repstat) {
951 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
956 case NFSV4OP_PUTROOTFH:
958 nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
960 if (!nd->nd_repstat) {
964 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
969 nd->nd_repstat = NFSERR_NOFILEHANDLE;
972 if (vp && NFSVNO_EXPORTED(&vpnes)) {
974 /* If vp == savevp, a no-op */
981 save_fsid = cur_fsid;
983 if ((nd->nd_flag & ND_CURSTATEID) != 0) {
984 nd->nd_savedcurstateid =
986 nd->nd_flag |= ND_SAVEDCURSTATEID;
989 nd->nd_repstat = NFSERR_NOFILEHANDLE;
992 case NFSV4OP_RESTOREFH:
995 /* If vp == savevp, a no-op */
1001 cur_fsid = save_fsid;
1003 if ((nd->nd_flag & ND_SAVEDCURSTATEID) != 0) {
1005 nd->nd_savedcurstateid;
1006 nd->nd_flag |= ND_CURSTATEID;
1009 nd->nd_repstat = NFSERR_RESTOREFH;
1014 * Allow a Lookup, Getattr, GetFH, Secinfo on an
1015 * non-exported directory if
1016 * nfs_rootfhset. Do I need to allow any other Ops?
1017 * (You can only have a non-exported vpnes if
1018 * nfs_rootfhset is true. See nfsd_fhtovp())
1019 * Allow AUTH_SYS to be used for file systems
1020 * exported GSS only for certain Ops, to allow
1021 * clients to do mounts more easily.
1023 if (nfsv4_opflag[op].needscfh && vp) {
1024 if (!NFSVNO_EXPORTED(&vpnes) &&
1025 op != NFSV4OP_LOOKUP &&
1026 op != NFSV4OP_GETATTR &&
1027 op != NFSV4OP_GETFH &&
1028 op != NFSV4OP_ACCESS &&
1029 op != NFSV4OP_READLINK &&
1030 op != NFSV4OP_SECINFO)
1031 nd->nd_repstat = NFSERR_NOFILEHANDLE;
1032 else if (nfsvno_testexp(nd, &vpnes) &&
1033 op != NFSV4OP_LOOKUP &&
1034 op != NFSV4OP_GETFH &&
1035 op != NFSV4OP_GETATTR &&
1036 op != NFSV4OP_SECINFO)
1037 nd->nd_repstat = NFSERR_WRONGSEC;
1038 if (nd->nd_repstat) {
1039 if (op == NFSV4OP_SETATTR) {
1041 * Setattr reply requires a bitmap
1042 * even for errors like these.
1044 NFSM_BUILD(tl, u_int32_t *,
1051 if (nfsv4_opflag[op].retfh == 1) {
1053 nd->nd_repstat = NFSERR_NOFILEHANDLE;
1057 if (nfsv4_opflag[op].modifyfs)
1058 vn_start_write(vp, &temp_mp, V_WAIT);
1059 error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
1060 &nvp, (fhandle_t *)fh.nfsrvfh_data, &vpnes);
1061 if (!error && !nd->nd_repstat) {
1062 if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
1063 new_mp = nvp->v_mount;
1064 if (cur_fsid.val[0] !=
1065 new_mp->mnt_stat.f_fsid.val[0] ||
1067 new_mp->mnt_stat.f_fsid.val[1]) {
1068 /* crossed a server mount point */
1069 nd->nd_repstat = nfsvno_checkexp(new_mp,
1070 nd->nd_nam, &nes, &credanon);
1071 if (!nd->nd_repstat)
1072 nd->nd_repstat = nfsd_excred(nd,
1074 if (credanon != NULL)
1076 if (!nd->nd_repstat) {
1078 cur_fsid = new_mp->mnt_stat.f_fsid;
1081 /* Lookup ops return a locked vnode */
1084 if (!nd->nd_repstat) {
1090 if (nfsv4_opflag[op].modifyfs)
1091 vn_finished_write(temp_mp);
1092 } else if (nfsv4_opflag[op].retfh == 2) {
1093 if (vp == NULL || savevp == NULL) {
1094 nd->nd_repstat = NFSERR_NOFILEHANDLE;
1096 } else if (cur_fsid.val[0] != save_fsid.val[0] ||
1097 cur_fsid.val[1] != save_fsid.val[1]) {
1098 nd->nd_repstat = NFSERR_XDEV;
1101 if (nfsv4_opflag[op].modifyfs)
1102 vn_start_write(savevp, &temp_mp, V_WAIT);
1103 if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
1106 error = (*(nfsrv4_ops2[op]))(nd, isdgram,
1107 savevp, vp, &savevpnes, &vpnes);
1109 nd->nd_repstat = NFSERR_PERM;
1110 if (nfsv4_opflag[op].modifyfs)
1111 vn_finished_write(temp_mp);
1113 if (nfsv4_opflag[op].retfh != 0)
1114 panic("nfsrvd_compound");
1115 if (nfsv4_opflag[op].needscfh) {
1117 lktype = nfsv4_opflag[op].lktype;
1118 if (nfsv4_opflag[op].modifyfs) {
1119 vn_start_write(vp, &temp_mp,
1121 if (op == NFSV4OP_WRITE &&
1122 MNT_SHARED_WRITES(temp_mp))
1125 if (NFSVOPLOCK(vp, lktype) == 0)
1128 nd->nd_repstat = NFSERR_PERM;
1130 nd->nd_repstat = NFSERR_NOFILEHANDLE;
1131 if (op == NFSV4OP_SETATTR) {
1133 * Setattr reply requires a
1134 * bitmap even for errors like
1137 NFSM_BUILD(tl, u_int32_t *,
1143 if (nd->nd_repstat == 0)
1144 error = (*(nfsrv4_ops0[op]))(nd,
1145 isdgram, vp, &vpnes);
1146 if (nfsv4_opflag[op].modifyfs)
1147 vn_finished_write(temp_mp);
1149 error = (*(nfsrv4_ops0[op]))(nd, isdgram,
1155 if (error == EBADRPC || error == NFSERR_BADXDR) {
1156 nd->nd_repstat = NFSERR_BADXDR;
1158 nd->nd_repstat = error;
1159 printf("nfsv4 comperr0=%d\n", error);
1164 if (statsinprog != 0) {
1165 nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
1166 /*then*/ &start_time);
1171 if (nd->nd_repstat) {
1172 *repp = nfsd_errmap(nd);
1175 *repp = 0; /* NFS4_OK */
1179 if (statsinprog != 0) {
1180 nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
1181 /*then*/ &start_time);
1185 if (error == EBADRPC || error == NFSERR_BADXDR)
1186 nd->nd_repstat = NFSERR_BADXDR;
1188 printf("nfsv4 comperr1=%d\n", error);
1191 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1195 *retopsp = txdr_unsigned(retops);
1201 NFSLOCKV4ROOTMUTEX();
1202 nfsv4_relref(&nfsv4rootfs_lock);
1203 NFSUNLOCKV4ROOTMUTEX();
1205 NFSEXITCODE2(0, nd);