1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
21 *
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
32 * SUCH DAMAGE.
33 *
34 */
35
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38
39 /*
40 * Socket operations for use by the nfs server.
41 */
42
43 #include <fs/nfs/nfsport.h>
44
45 extern struct nfsstatsv1 nfsstatsv1;
46 extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
47 extern int nfs_pubfhset, nfs_rootfhset;
48 extern struct nfsv4lock nfsv4rootfs_lock;
49 extern struct nfsrv_stablefirst nfsrv_stablefirst;
50 extern struct nfsclienthashhead *nfsclienthash;
51 extern int nfsrv_clienthashsize;
52 extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
53 extern int nfsd_debuglevel;
54 extern int nfsrv_layouthighwater;
55 extern volatile int nfsrv_layoutcnt;
56 NFSV4ROOTLOCKMUTEX;
57 NFSSTATESPINLOCK;
58
59 int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
60 int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
61 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
62 nfsrvd_getattr,
63 nfsrvd_setattr,
64 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
65 nfsrvd_access,
66 nfsrvd_readlink,
67 nfsrvd_read,
68 nfsrvd_write,
69 nfsrvd_create,
70 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
71 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
72 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
73 nfsrvd_remove,
74 nfsrvd_remove,
75 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
76 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
77 nfsrvd_readdir,
78 nfsrvd_readdirplus,
79 nfsrvd_statfs,
80 nfsrvd_fsinfo,
81 nfsrvd_pathconf,
82 nfsrvd_commit,
83 };
84
85 int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *,
86 int, vnode_t , vnode_t *, fhandle_t *,
87 NFSPROC_T *, struct nfsexstuff *) = {
88 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
89 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
90 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
91 nfsrvd_lookup,
92 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
93 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
94 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
95 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
96 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
97 nfsrvd_mkdir,
98 nfsrvd_symlink,
99 nfsrvd_mknod,
100 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
101 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
102 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
103 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
104 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
105 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
106 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
107 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
108 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
109 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
110 };
111
112 int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
113 int, vnode_t , vnode_t , NFSPROC_T *,
114 struct nfsexstuff *, struct nfsexstuff *) = {
115 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
116 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
117 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
118 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
119 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
120 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
121 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
122 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
123 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
124 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
125 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
126 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
127 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
128 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
129 nfsrvd_rename,
130 nfsrvd_link,
131 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
132 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
133 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
134 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
135 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
136 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
137 };
138
139 int (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript *,
140 int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
141 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
142 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
143 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
144 nfsrvd_access,
145 nfsrvd_close,
146 nfsrvd_commit,
147 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
148 nfsrvd_delegpurge,
149 nfsrvd_delegreturn,
150 nfsrvd_getattr,
151 nfsrvd_getfh,
152 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
153 nfsrvd_lock,
154 nfsrvd_lockt,
155 nfsrvd_locku,
156 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
157 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
158 nfsrvd_verify,
159 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
160 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
161 nfsrvd_openconfirm,
162 nfsrvd_opendowngrade,
163 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
164 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
165 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
166 nfsrvd_read,
167 nfsrvd_readdirplus,
168 nfsrvd_readlink,
169 nfsrvd_remove,
170 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
171 nfsrvd_renew,
172 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
173 (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
174 nfsrvd_secinfo,
175 nfsrvd_setattr,
176 nfsrvd_setclientid,
177 nfsrvd_setclientidcfrm,
178 nfsrvd_verify,
179 nfsrvd_write,
180 nfsrvd_releaselckown,
181 nfsrvd_notsupp,
182 nfsrvd_bindconnsess,
183 nfsrvd_exchangeid,
184 nfsrvd_createsession,
185 nfsrvd_destroysession,
186 nfsrvd_freestateid,
187 nfsrvd_notsupp,
188 nfsrvd_getdevinfo,
189 nfsrvd_notsupp,
190 nfsrvd_layoutcommit,
191 nfsrvd_layoutget,
192 nfsrvd_layoutreturn,
193 nfsrvd_notsupp,
194 nfsrvd_sequence,
195 nfsrvd_notsupp,
196 nfsrvd_teststateid,
197 nfsrvd_notsupp,
198 nfsrvd_destroyclientid,
199 nfsrvd_reclaimcomplete,
200 };
201
202 int (*nfsrv4_ops1[NFSV41_NOPS])(struct nfsrv_descript *,
203 int, vnode_t , vnode_t *, fhandle_t *,
204 NFSPROC_T *, struct nfsexstuff *) = {
205 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
206 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
207 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
208 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
209 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
210 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
211 nfsrvd_mknod,
212 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
213 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
214 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
215 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
216 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
217 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
218 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
219 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
220 nfsrvd_lookup,
221 nfsrvd_lookup,
222 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
223 nfsrvd_open,
224 nfsrvd_openattr,
225 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
226 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
227 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
228 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
229 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
230 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
231 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
232 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
233 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
234 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
235 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
236 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
237 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
238 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
239 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
240 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
241 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
242 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
243 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
244 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
245 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
246 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
247 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
248 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
249 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
250 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
251 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
252 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
253 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
254 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
255 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
256 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
257 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
258 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
259 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
260 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
261 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
262 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
263 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
264 };
265
266 int (*nfsrv4_ops2[NFSV41_NOPS])(struct nfsrv_descript *,
267 int, vnode_t , vnode_t , NFSPROC_T *,
268 struct nfsexstuff *, struct nfsexstuff *) = {
269 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
270 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
271 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
272 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
273 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
274 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
275 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
276 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
277 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
278 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
279 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
280 nfsrvd_link,
281 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
282 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
283 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
284 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
285 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
286 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
287 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
288 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
289 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
290 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
291 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
292 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
293 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
294 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
295 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
296 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
297 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
298 nfsrvd_rename,
299 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
300 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
301 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
302 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
303 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
304 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
305 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
306 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
307 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
308 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
309 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
310 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
311 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
312 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
313 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
314 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
315 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
316 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
317 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
318 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
319 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
320 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
321 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
322 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
323 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
324 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
325 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
326 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
327 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
328 };
329
330 /*
331 * Static array that defines which nfs rpc's are nonidempotent
332 */
333 static int nfsrv_nonidempotent[NFS_V3NPROCS] = {
334 FALSE,
335 FALSE,
336 TRUE,
337 FALSE,
338 FALSE,
339 FALSE,
340 FALSE,
341 TRUE,
342 TRUE,
343 TRUE,
344 TRUE,
345 TRUE,
346 TRUE,
347 TRUE,
348 TRUE,
349 TRUE,
350 FALSE,
351 FALSE,
352 FALSE,
353 FALSE,
354 FALSE,
355 FALSE,
356 };
357
358 /*
359 * This static array indicates whether or not the RPC modifies the
360 * file system.
361 */
362 int nfsrv_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
363 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
364 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
365
366 /* local functions */
367 static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
368 u_char *tag, int taglen, u_int32_t minorvers, NFSPROC_T *p);
369
370
371 /*
372 * This static array indicates which server procedures require the extra
373 * arguments to return the current file handle for V2, 3.
374 */
375 static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
376 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
377
378 extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
379
380 static int nfsv3to4op[NFS_V3NPROCS] = {
381 NFSPROC_NULL,
382 NFSV4OP_GETATTR,
383 NFSV4OP_SETATTR,
384 NFSV4OP_LOOKUP,
385 NFSV4OP_ACCESS,
386 NFSV4OP_READLINK,
387 NFSV4OP_READ,
388 NFSV4OP_WRITE,
389 NFSV4OP_V3CREATE,
390 NFSV4OP_MKDIR,
391 NFSV4OP_SYMLINK,
392 NFSV4OP_MKNOD,
393 NFSV4OP_REMOVE,
394 NFSV4OP_RMDIR,
395 NFSV4OP_RENAME,
396 NFSV4OP_LINK,
397 NFSV4OP_READDIR,
398 NFSV4OP_READDIRPLUS,
399 NFSV4OP_FSSTAT,
400 NFSV4OP_FSINFO,
401 NFSV4OP_PATHCONF,
402 NFSV4OP_COMMIT,
403 };
404
405 static struct mtx nfsrvd_statmtx;
406 MTX_SYSINIT(nfsst, &nfsrvd_statmtx, "NFSstat", MTX_DEF);
407
408 static void
409 nfsrvd_statstart(int op, struct bintime *now)
410 {
411 if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) {
412 printf("%s: op %d invalid\n", __func__, op);
413 return;
414 }
415
416 mtx_lock(&nfsrvd_statmtx);
417 if (nfsstatsv1.srvstartcnt == nfsstatsv1.srvdonecnt) {
418 if (now != NULL)
419 nfsstatsv1.busyfrom = *now;
420 else
421 binuptime(&nfsstatsv1.busyfrom);
422
423 }
424 nfsstatsv1.srvrpccnt[op]++;
425 nfsstatsv1.srvstartcnt++;
426 mtx_unlock(&nfsrvd_statmtx);
427
428 }
429
430 static void
431 nfsrvd_statend(int op, uint64_t bytes, struct bintime *now,
432 struct bintime *then)
433 {
434 struct bintime dt, lnow;
435
436 if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) {
437 printf("%s: op %d invalid\n", __func__, op);
438 return;
439 }
440
441 if (now == NULL) {
442 now = &lnow;
443 binuptime(now);
444 }
445
446 mtx_lock(&nfsrvd_statmtx);
447
448 nfsstatsv1.srvbytes[op] += bytes;
449 nfsstatsv1.srvops[op]++;
450
451 if (then != NULL) {
452 dt = *now;
453 bintime_sub(&dt, then);
454 bintime_add(&nfsstatsv1.srvduration[op], &dt);
455 }
456
457 dt = *now;
458 bintime_sub(&dt, &nfsstatsv1.busyfrom);
459 bintime_add(&nfsstatsv1.busytime, &dt);
460 nfsstatsv1.busyfrom = *now;
461
462 nfsstatsv1.srvdonecnt++;
463
464 mtx_unlock(&nfsrvd_statmtx);
465 }
466
467 /*
468 * Do an RPC. Basically, get the file handles translated to vnode pointers
469 * and then call the appropriate server routine. The server routines are
470 * split into groups, based on whether they use a file handle or file
471 * handle plus name or ...
472 * The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
473 */
474 void
475 nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
476 u_int32_t minorvers, NFSPROC_T *p)
477 {
478 int error = 0, lktype;
479 vnode_t vp;
480 mount_t mp = NULL;
481 struct nfsrvfh fh;
482 struct nfsexstuff nes;
483
484 /*
485 * Get a locked vnode for the first file handle
486 */
487 if (!(nd->nd_flag & ND_NFSV4)) {
488 KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc"));
489 /*
490 * For NFSv3, if the malloc/mget allocation is near limits,
491 * return NFSERR_DELAY.
492 */
493 if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) {
494 nd->nd_repstat = NFSERR_DELAY;
495 vp = NULL;
496 } else {
497 error = nfsrv_mtofh(nd, &fh);
498 if (error) {
499 if (error != EBADRPC)
500 printf("nfs dorpc err1=%d\n", error);
501 nd->nd_repstat = NFSERR_GARBAGE;
502 goto out;
503 }
504 if (nd->nd_procnum == NFSPROC_READ ||
505 nd->nd_procnum == NFSPROC_WRITE ||
506 nd->nd_procnum == NFSPROC_READDIR ||
507 nd->nd_procnum == NFSPROC_READDIRPLUS ||
508 nd->nd_procnum == NFSPROC_READLINK ||
509 nd->nd_procnum == NFSPROC_GETATTR ||
510 nd->nd_procnum == NFSPROC_ACCESS ||
511 nd->nd_procnum == NFSPROC_FSSTAT ||
512 nd->nd_procnum == NFSPROC_FSINFO)
513 lktype = LK_SHARED;
514 else
515 lktype = LK_EXCLUSIVE;
516 if (nd->nd_flag & ND_PUBLOOKUP)
517 nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
518 &mp, nfsrv_writerpc[nd->nd_procnum], p);
519 else
520 nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
521 &mp, nfsrv_writerpc[nd->nd_procnum], p);
522 if (nd->nd_repstat == NFSERR_PROGNOTV4)
523 goto out;
524 }
525 }
526
527 /*
528 * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
529 * cache, as required.
530 * For V4, nfsrvd_compound() does this.
531 */
532 if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
533 nd->nd_flag |= ND_SAVEREPLY;
534
535 nfsrvd_rephead(nd);
536 /*
537 * If nd_repstat is non-zero, just fill in the reply status
538 * to complete the RPC reply for V2. Otherwise, you must do
539 * the RPC.
540 */
541 if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
542 *nd->nd_errp = nfsd_errmap(nd);
543 nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL);
544 nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
545 /*now*/ NULL, /*then*/ NULL);
546 vn_finished_write(mp);
547 goto out;
548 }
549
550 /*
551 * Now the procedure can be performed. For V4, nfsrvd_compound()
552 * works through the sub-rpcs, otherwise just call the procedure.
553 * The procedures are in three groups with different arguments.
554 * The group is indicated by the value in nfs_retfh[].
555 */
556 if (nd->nd_flag & ND_NFSV4) {
557 nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p);
558 } else {
559 struct bintime start_time;
560
561 binuptime(&start_time);
562 nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], &start_time);
563
564 if (nfs_retfh[nd->nd_procnum] == 1) {
565 if (vp)
566 NFSVOPUNLOCK(vp, 0);
567 error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
568 vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes);
569 } else if (nfs_retfh[nd->nd_procnum] == 2) {
570 error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
571 vp, NULL, p, &nes, NULL);
572 } else {
573 error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
574 vp, p, &nes);
575 }
576 vn_finished_write(mp);
577
578 nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
579 /*now*/ NULL, /*then*/ &start_time);
580 }
581 if (error) {
582 if (error != EBADRPC)
583 printf("nfs dorpc err2=%d\n", error);
584 nd->nd_repstat = NFSERR_GARBAGE;
585 }
586 *nd->nd_errp = nfsd_errmap(nd);
587
588 /*
589 * Don't cache certain reply status values.
590 */
591 if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
592 (nd->nd_repstat == NFSERR_GARBAGE ||
593 nd->nd_repstat == NFSERR_BADXDR ||
594 nd->nd_repstat == NFSERR_MOVED ||
595 nd->nd_repstat == NFSERR_DELAY ||
596 nd->nd_repstat == NFSERR_BADSEQID ||
597 nd->nd_repstat == NFSERR_RESOURCE ||
598 nd->nd_repstat == NFSERR_SERVERFAULT ||
599 nd->nd_repstat == NFSERR_STALECLIENTID ||
600 nd->nd_repstat == NFSERR_STALESTATEID ||
601 nd->nd_repstat == NFSERR_OLDSTATEID ||
602 nd->nd_repstat == NFSERR_BADSTATEID ||
603 nd->nd_repstat == NFSERR_GRACE ||
604 nd->nd_repstat == NFSERR_NOGRACE))
605 nd->nd_flag &= ~ND_SAVEREPLY;
606
607 out:
608 NFSEXITCODE2(0, nd);
609 }
610
611 /*
612 * Breaks down a compound RPC request and calls the server routines for
613 * the subprocedures.
614 * Some suboperations are performed directly here to simplify file handle<-->
615 * vnode pointer handling.
616 */
617 static void
618 nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
619 int taglen, u_int32_t minorvers, NFSPROC_T *p)
620 {
621 int i, lktype, op, op0 = 0, statsinprog = 0;
622 u_int32_t *tl;
623 struct nfsclient *clp, *nclp;
624 int numops, error = 0, igotlock;
625 u_int32_t retops = 0, *retopsp = NULL, *repp;
626 vnode_t vp, nvp, savevp;
627 struct nfsrvfh fh;
628 mount_t new_mp, temp_mp = NULL;
629 struct ucred *credanon;
630 struct nfsexstuff nes, vpnes, savevpnes;
631 fsid_t cur_fsid, save_fsid;
632 static u_int64_t compref = 0;
633 struct bintime start_time;
634
635 NFSVNO_EXINIT(&vpnes);
636 NFSVNO_EXINIT(&savevpnes);
637 /*
638 * Put the seq# of the current compound RPC in nfsrv_descript.
639 * (This is used by nfsrv_checkgetattr(), to see if the write
640 * delegation was created by the same compound RPC as the one
641 * with that Getattr in it.)
642 * Don't worry about the 64bit number wrapping around. It ain't
643 * gonna happen before this server gets shut down/rebooted.
644 */
645 nd->nd_compref = compref++;
646
647 /*
648 * Check for and optionally get a lock on the root. This lock means that
649 * no nfsd will be fiddling with the V4 file system and state stuff. It
650 * is required when the V4 root is being changed, the stable storage
651 * restart file is being updated, or callbacks are being done.
652 * When any of the nfsd are processing an NFSv4 compound RPC, they must
653 * either hold a reference count (nfs_usecnt) or the lock. When
654 * nfsrv_unlock() is called to release the lock, it can optionally
655 * also get a reference count, which saves the need for a call to
656 * nfsrv_getref() after nfsrv_unlock().
657 */
658 /*
659 * First, check to see if we need to wait for an update lock.
660 */
661 igotlock = 0;
662 NFSLOCKV4ROOTMUTEX();
663 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
664 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
665 NFSV4ROOTLOCKMUTEXPTR, NULL);
666 else
667 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
668 NFSV4ROOTLOCKMUTEXPTR, NULL);
669 NFSUNLOCKV4ROOTMUTEX();
670 if (igotlock) {
671 /*
672 * If I got the lock, I can update the stable storage file.
673 * Done when the grace period is over or a client has long
674 * since expired.
675 */
676 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
677 if ((nfsrv_stablefirst.nsf_flags &
678 (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
679 nfsrv_updatestable(p);
680
681 /*
682 * If at least one client has long since expired, search
683 * the client list for them, write a REVOKE record on the
684 * stable storage file and then remove them from the client
685 * list.
686 */
687 if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
688 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
689 for (i = 0; i < nfsrv_clienthashsize; i++) {
690 LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
691 nclp) {
692 if (clp->lc_flags & LCL_EXPIREIT) {
693 if (!LIST_EMPTY(&clp->lc_open) ||
694 !LIST_EMPTY(&clp->lc_deleg))
695 nfsrv_writestable(clp->lc_id,
696 clp->lc_idlen, NFSNST_REVOKE, p);
697 nfsrv_cleanclient(clp, p);
698 nfsrv_freedeleglist(&clp->lc_deleg);
699 nfsrv_freedeleglist(&clp->lc_olddeleg);
700 LIST_REMOVE(clp, lc_hash);
701 nfsrv_zapclient(clp, p);
702 }
703 }
704 }
705 }
706 NFSLOCKV4ROOTMUTEX();
707 nfsv4_unlock(&nfsv4rootfs_lock, 1);
708 NFSUNLOCKV4ROOTMUTEX();
709 } else {
710 /*
711 * If we didn't get the lock, we need to get a refcnt,
712 * which also checks for and waits for the lock.
713 */
714 NFSLOCKV4ROOTMUTEX();
715 nfsv4_getref(&nfsv4rootfs_lock, NULL,
716 NFSV4ROOTLOCKMUTEXPTR, NULL);
717 NFSUNLOCKV4ROOTMUTEX();
718 }
719
720 /*
721 * If flagged, search for open owners that haven't had any opens
722 * for a long time.
723 */
724 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
725 nfsrv_throwawayopens(p);
726 }
727
728 /* Do a CBLAYOUTRECALL callback if over the high water mark. */
729 if (nfsrv_layoutcnt > nfsrv_layouthighwater)
730 nfsrv_recalloldlayout(p);
731
732 savevp = vp = NULL;
733 save_fsid.val[0] = save_fsid.val[1] = 0;
734 cur_fsid.val[0] = cur_fsid.val[1] = 0;
735
736 /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */
737 if (taglen < 0) {
738 error = EBADRPC;
739 goto nfsmout;
740 }
741
742 (void) nfsm_strtom(nd, tag, taglen);
743 NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
744 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
745 if (minorvers != NFSV4_MINORVERSION && minorvers != NFSV41_MINORVERSION)
746 nd->nd_repstat = NFSERR_MINORVERMISMATCH;
747 if (nd->nd_repstat)
748 numops = 0;
749 else
750 numops = fxdr_unsigned(int, *tl);
751 /*
752 * Loop around doing the sub ops.
753 * vp - is an unlocked vnode pointer for the CFH
754 * savevp - is an unlocked vnode pointer for the SAVEDFH
755 * (at some future date, it might turn out to be more appropriate
756 * to keep the file handles instead of vnode pointers?)
757 * savevpnes and vpnes - are the export flags for the above.
758 */
759 for (i = 0; i < numops; i++) {
760 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
761 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
762 *repp = *tl;
763 op = fxdr_unsigned(int, *tl);
764 NFSD_DEBUG(4, "op=%d\n", op);
765 if (op < NFSV4OP_ACCESS ||
766 (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
767 (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) {
768 nd->nd_repstat = NFSERR_OPILLEGAL;
769 *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
770 *repp = nfsd_errmap(nd);
771 retops++;
772 break;
773 } else {
774 repp++;
775 }
776
777 binuptime(&start_time);
778 nfsrvd_statstart(op, &start_time);
779 statsinprog = 1;
780
781 if (i == 0)
782 op0 = op;
783 if (i == numops - 1)
784 nd->nd_flag |= ND_LASTOP;
785
786 /*
787 * Check for a referral on the current FH and, if so, return
788 * NFSERR_MOVED for all ops that allow it, except Getattr.
789 */
790 if (vp != NULL && op != NFSV4OP_GETATTR &&
791 nfsv4root_getreferral(vp, NULL, 0) != NULL &&
792 nfsrv_errmoved(op)) {
793 nd->nd_repstat = NFSERR_MOVED;
794 *repp = nfsd_errmap(nd);
795 retops++;
796 break;
797 }
798
799 /*
800 * For NFSv4.1, check for a Sequence Operation being first
801 * or one of the other allowed operations by itself.
802 */
803 if ((nd->nd_flag & ND_NFSV41) != 0) {
804 if (i != 0 && op == NFSV4OP_SEQUENCE)
805 nd->nd_repstat = NFSERR_SEQUENCEPOS;
806 else if (i == 0 && op != NFSV4OP_SEQUENCE &&
807 op != NFSV4OP_EXCHANGEID &&
808 op != NFSV4OP_CREATESESSION &&
809 op != NFSV4OP_BINDCONNTOSESS &&
810 op != NFSV4OP_DESTROYCLIENTID &&
811 op != NFSV4OP_DESTROYSESSION)
812 nd->nd_repstat = NFSERR_OPNOTINSESS;
813 else if (i != 0 && op0 != NFSV4OP_SEQUENCE)
814 nd->nd_repstat = NFSERR_NOTONLYOP;
815 if (nd->nd_repstat != 0) {
816 *repp = nfsd_errmap(nd);
817 retops++;
818 break;
819 }
820 }
821
822 nd->nd_procnum = op;
823 /*
824 * If over flood level, reply NFSERR_RESOURCE, if at the first
825 * Op. (Since a client recovery from NFSERR_RESOURCE can get
826 * really nasty for certain Op sequences, I'll play it safe
827 * and only return the error at the beginning.) The cache
828 * will still function over flood level, but uses lots of
829 * mbufs.)
830 * If nfsrv_mallocmget_limit() returns True, the system is near
831 * to its limit for memory that malloc()/mget() can allocate.
832 */
833 if (i == 0 && (nd->nd_rp == NULL ||
834 nd->nd_rp->rc_refcnt == 0) &&
835 (nfsrv_mallocmget_limit() ||
836 nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
837 if (nfsrc_tcpsavedreplies > nfsrc_floodlevel)
838 printf("nfsd server cache flooded, try "
839 "increasing vfs.nfsd.tcphighwater\n");
840 nd->nd_repstat = NFSERR_RESOURCE;
841 *repp = nfsd_errmap(nd);
842 if (op == NFSV4OP_SETATTR) {
843 /*
844 * Setattr replies require a bitmap.
845 * even for errors like these.
846 */
847 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
848 *tl = 0;
849 }
850 retops++;
851 break;
852 }
853 if (nfsv4_opflag[op].savereply)
854 nd->nd_flag |= ND_SAVEREPLY;
855 switch (op) {
856 case NFSV4OP_PUTFH:
857 error = nfsrv_mtofh(nd, &fh);
858 if (error)
859 goto nfsmout;
860 if (!nd->nd_repstat)
861 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
862 NULL, 0, p);
863 /* For now, allow this for non-export FHs */
864 if (!nd->nd_repstat) {
865 if (vp)
866 vrele(vp);
867 vp = nvp;
868 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
869 NFSVOPUNLOCK(vp, 0);
870 vpnes = nes;
871 }
872 break;
873 case NFSV4OP_PUTPUBFH:
874 if (nfs_pubfhset)
875 nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
876 &nes, NULL, 0, p);
877 else
878 nd->nd_repstat = NFSERR_NOFILEHANDLE;
879 if (!nd->nd_repstat) {
880 if (vp)
881 vrele(vp);
882 vp = nvp;
883 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
884 NFSVOPUNLOCK(vp, 0);
885 vpnes = nes;
886 }
887 break;
888 case NFSV4OP_PUTROOTFH:
889 if (nfs_rootfhset) {
890 nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
891 &nes, NULL, 0, p);
892 if (!nd->nd_repstat) {
893 if (vp)
894 vrele(vp);
895 vp = nvp;
896 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
897 NFSVOPUNLOCK(vp, 0);
898 vpnes = nes;
899 }
900 } else
901 nd->nd_repstat = NFSERR_NOFILEHANDLE;
902 break;
903 case NFSV4OP_SAVEFH:
904 if (vp && NFSVNO_EXPORTED(&vpnes)) {
905 nd->nd_repstat = 0;
906 /* If vp == savevp, a no-op */
907 if (vp != savevp) {
908 if (savevp)
909 vrele(savevp);
910 VREF(vp);
911 savevp = vp;
912 savevpnes = vpnes;
913 save_fsid = cur_fsid;
914 }
915 if ((nd->nd_flag & ND_CURSTATEID) != 0) {
916 nd->nd_savedcurstateid =
917 nd->nd_curstateid;
918 nd->nd_flag |= ND_SAVEDCURSTATEID;
919 }
920 } else {
921 nd->nd_repstat = NFSERR_NOFILEHANDLE;
922 }
923 break;
924 case NFSV4OP_RESTOREFH:
925 if (savevp) {
926 nd->nd_repstat = 0;
927 /* If vp == savevp, a no-op */
928 if (vp != savevp) {
929 VREF(savevp);
930 vrele(vp);
931 vp = savevp;
932 vpnes = savevpnes;
933 cur_fsid = save_fsid;
934 }
935 if ((nd->nd_flag & ND_SAVEDCURSTATEID) != 0) {
936 nd->nd_curstateid =
937 nd->nd_savedcurstateid;
938 nd->nd_flag |= ND_CURSTATEID;
939 }
940 } else {
941 nd->nd_repstat = NFSERR_RESTOREFH;
942 }
943 break;
944 default:
945 /*
946 * Allow a Lookup, Getattr, GetFH, Secinfo on an
947 * non-exported directory if
948 * nfs_rootfhset. Do I need to allow any other Ops?
949 * (You can only have a non-exported vpnes if
950 * nfs_rootfhset is true. See nfsd_fhtovp())
951 * Allow AUTH_SYS to be used for file systems
952 * exported GSS only for certain Ops, to allow
953 * clients to do mounts more easily.
954 */
955 if (nfsv4_opflag[op].needscfh && vp) {
956 if (!NFSVNO_EXPORTED(&vpnes) &&
957 op != NFSV4OP_LOOKUP &&
958 op != NFSV4OP_GETATTR &&
959 op != NFSV4OP_GETFH &&
960 op != NFSV4OP_ACCESS &&
961 op != NFSV4OP_READLINK &&
962 op != NFSV4OP_SECINFO)
963 nd->nd_repstat = NFSERR_NOFILEHANDLE;
964 else if (nfsvno_testexp(nd, &vpnes) &&
965 op != NFSV4OP_LOOKUP &&
966 op != NFSV4OP_GETFH &&
967 op != NFSV4OP_GETATTR &&
968 op != NFSV4OP_SECINFO)
969 nd->nd_repstat = NFSERR_WRONGSEC;
970 if (nd->nd_repstat) {
971 if (op == NFSV4OP_SETATTR) {
972 /*
973 * Setattr reply requires a bitmap
974 * even for errors like these.
975 */
976 NFSM_BUILD(tl, u_int32_t *,
977 NFSX_UNSIGNED);
978 *tl = 0;
979 }
980 break;
981 }
982 }
983 if (nfsv4_opflag[op].retfh == 1) {
984 if (!vp) {
985 nd->nd_repstat = NFSERR_NOFILEHANDLE;
986 break;
987 }
988 VREF(vp);
989 if (nfsv4_opflag[op].modifyfs)
990 vn_start_write(vp, &temp_mp, V_WAIT);
991 error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
992 &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
993 if (!error && !nd->nd_repstat) {
994 if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
995 new_mp = nvp->v_mount;
996 if (fsidcmp(&cur_fsid, &new_mp->mnt_stat.f_fsid) != 0) {
997 /* crossed a server mount point */
998 nd->nd_repstat = nfsvno_checkexp(new_mp,
999 nd->nd_nam, &nes, &credanon);
1000 if (!nd->nd_repstat)
1001 nd->nd_repstat = nfsd_excred(nd,
1002 &nes, credanon);
1003 if (credanon != NULL)
1004 crfree(credanon);
1005 if (!nd->nd_repstat) {
1006 vpnes = nes;
1007 cur_fsid = new_mp->mnt_stat.f_fsid;
1008 }
1009 }
1010 /* Lookup ops return a locked vnode */
1011 NFSVOPUNLOCK(nvp, 0);
1012 }
1013 if (!nd->nd_repstat) {
1014 vrele(vp);
1015 vp = nvp;
1016 } else
1017 vrele(nvp);
1018 }
1019 if (nfsv4_opflag[op].modifyfs)
1020 vn_finished_write(temp_mp);
1021 } else if (nfsv4_opflag[op].retfh == 2) {
1022 if (vp == NULL || savevp == NULL) {
1023 nd->nd_repstat = NFSERR_NOFILEHANDLE;
1024 break;
1025 } else if (fsidcmp(&cur_fsid, &save_fsid) != 0) {
1026 nd->nd_repstat = NFSERR_XDEV;
1027 break;
1028 }
1029 if (nfsv4_opflag[op].modifyfs)
1030 vn_start_write(savevp, &temp_mp, V_WAIT);
1031 if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
1032 VREF(vp);
1033 VREF(savevp);
1034 error = (*(nfsrv4_ops2[op]))(nd, isdgram,
1035 savevp, vp, p, &savevpnes, &vpnes);
1036 } else
1037 nd->nd_repstat = NFSERR_PERM;
1038 if (nfsv4_opflag[op].modifyfs)
1039 vn_finished_write(temp_mp);
1040 } else {
1041 if (nfsv4_opflag[op].retfh != 0)
1042 panic("nfsrvd_compound");
1043 if (nfsv4_opflag[op].needscfh) {
1044 if (vp != NULL) {
1045 lktype = nfsv4_opflag[op].lktype;
1046 if (nfsv4_opflag[op].modifyfs) {
1047 vn_start_write(vp, &temp_mp,
1048 V_WAIT);
1049 if (op == NFSV4OP_WRITE &&
1050 MNT_SHARED_WRITES(temp_mp))
1051 lktype = LK_SHARED;
1052 }
1053 if (NFSVOPLOCK(vp, lktype) == 0)
1054 VREF(vp);
1055 else
1056 nd->nd_repstat = NFSERR_PERM;
1057 } else {
1058 nd->nd_repstat = NFSERR_NOFILEHANDLE;
1059 if (op == NFSV4OP_SETATTR) {
1060 /*
1061 * Setattr reply requires a
1062 * bitmap even for errors like
1063 * these.
1064 */
1065 NFSM_BUILD(tl, u_int32_t *,
1066 NFSX_UNSIGNED);
1067 *tl = 0;
1068 }
1069 break;
1070 }
1071 if (nd->nd_repstat == 0)
1072 error = (*(nfsrv4_ops0[op]))(nd,
1073 isdgram, vp, p, &vpnes);
1074 if (nfsv4_opflag[op].modifyfs)
1075 vn_finished_write(temp_mp);
1076 } else {
1077 error = (*(nfsrv4_ops0[op]))(nd, isdgram,
1078 NULL, p, &vpnes);
1079 }
1080 }
1081 }
1082 if (error) {
1083 if (error == EBADRPC || error == NFSERR_BADXDR) {
1084 nd->nd_repstat = NFSERR_BADXDR;
1085 } else {
1086 nd->nd_repstat = error;
1087 printf("nfsv4 comperr0=%d\n", error);
1088 }
1089 error = 0;
1090 }
1091
1092 if (statsinprog != 0) {
1093 nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
1094 /*then*/ &start_time);
1095 statsinprog = 0;
1096 }
1097
1098 retops++;
1099 if (nd->nd_repstat) {
1100 *repp = nfsd_errmap(nd);
1101 break;
1102 } else {
1103 *repp = 0; /* NFS4_OK */
1104 }
1105 }
1106 nfsmout:
1107 if (statsinprog != 0) {
1108 nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
1109 /*then*/ &start_time);
1110 statsinprog = 0;
1111 }
1112 if (error) {
1113 if (error == EBADRPC || error == NFSERR_BADXDR)
1114 nd->nd_repstat = NFSERR_BADXDR;
1115 else
1116 printf("nfsv4 comperr1=%d\n", error);
1117 }
1118 if (taglen == -1) {
1119 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1120 *tl++ = 0;
1121 *tl = 0;
1122 } else {
1123 *retopsp = txdr_unsigned(retops);
1124 }
1125 if (vp)
1126 vrele(vp);
1127 if (savevp)
1128 vrele(savevp);
1129 NFSLOCKV4ROOTMUTEX();
1130 nfsv4_relref(&nfsv4rootfs_lock);
1131 NFSUNLOCKV4ROOTMUTEX();
1132
1133 NFSEXITCODE2(0, nd);
1134 }
Cache object: 1dec708c9402ab21db649386ab74fd3a
|