nfs_nfsdsocket.c revision 1.1 1 1.1 dholland /* $NetBSD: nfs_nfsdsocket.c,v 1.1 2013/09/30 07:19:47 dholland Exp $ */
2 1.1 dholland /*-
3 1.1 dholland * Copyright (c) 1989, 1993
4 1.1 dholland * The Regents of the University of California. All rights reserved.
5 1.1 dholland *
6 1.1 dholland * This code is derived from software contributed to Berkeley by
7 1.1 dholland * Rick Macklem at The University of Guelph.
8 1.1 dholland *
9 1.1 dholland * Redistribution and use in source and binary forms, with or without
10 1.1 dholland * modification, are permitted provided that the following conditions
11 1.1 dholland * are met:
12 1.1 dholland * 1. Redistributions of source code must retain the above copyright
13 1.1 dholland * notice, this list of conditions and the following disclaimer.
14 1.1 dholland * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 dholland * notice, this list of conditions and the following disclaimer in the
16 1.1 dholland * documentation and/or other materials provided with the distribution.
17 1.1 dholland * 4. Neither the name of the University nor the names of its contributors
18 1.1 dholland * may be used to endorse or promote products derived from this software
19 1.1 dholland * without specific prior written permission.
20 1.1 dholland *
21 1.1 dholland * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.1 dholland * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.1 dholland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1 dholland * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.1 dholland * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1 dholland * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1 dholland * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 dholland * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1 dholland * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1 dholland * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1 dholland * SUCH DAMAGE.
32 1.1 dholland *
33 1.1 dholland */
34 1.1 dholland
35 1.1 dholland #include <sys/cdefs.h>
36 1.1 dholland /* __FBSDID("FreeBSD: head/sys/fs/nfsserver/nfs_nfsdsocket.c 249592 2013-04-17 21:00:22Z ken "); */
37 1.1 dholland __RCSID("$NetBSD: nfs_nfsdsocket.c,v 1.1 2013/09/30 07:19:47 dholland Exp $");
38 1.1 dholland
39 1.1 dholland /*
40 1.1 dholland * Socket operations for use by the nfs server.
41 1.1 dholland */
42 1.1 dholland
43 1.1 dholland #ifndef APPLEKEXT
44 1.1 dholland #include <fs/nfs/nfsport.h>
45 1.1 dholland
46 1.1 dholland extern struct nfsstats newnfsstats;
47 1.1 dholland extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
48 1.1 dholland extern int nfs_pubfhset, nfs_rootfhset;
49 1.1 dholland extern struct nfsv4lock nfsv4rootfs_lock;
50 1.1 dholland extern struct nfsrv_stablefirst nfsrv_stablefirst;
51 1.1 dholland extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
52 1.1 dholland extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
53 1.1 dholland NFSV4ROOTLOCKMUTEX;
54 1.1 dholland NFSSTATESPINLOCK;
55 1.1 dholland
56 1.1 dholland int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
57 1.1 dholland int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
58 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
59 1.1 dholland nfsrvd_getattr,
60 1.1 dholland nfsrvd_setattr,
61 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
62 1.1 dholland nfsrvd_access,
63 1.1 dholland nfsrvd_readlink,
64 1.1 dholland nfsrvd_read,
65 1.1 dholland nfsrvd_write,
66 1.1 dholland nfsrvd_create,
67 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
68 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
69 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
70 1.1 dholland nfsrvd_remove,
71 1.1 dholland nfsrvd_remove,
72 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
73 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
74 1.1 dholland nfsrvd_readdir,
75 1.1 dholland nfsrvd_readdirplus,
76 1.1 dholland nfsrvd_statfs,
77 1.1 dholland nfsrvd_fsinfo,
78 1.1 dholland nfsrvd_pathconf,
79 1.1 dholland nfsrvd_commit,
80 1.1 dholland };
81 1.1 dholland
82 1.1 dholland int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *,
83 1.1 dholland int, vnode_t , vnode_t *, fhandle_t *,
84 1.1 dholland NFSPROC_T *, struct nfsexstuff *) = {
85 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
86 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
87 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
88 1.1 dholland nfsrvd_lookup,
89 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
90 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
91 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
92 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
93 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
94 1.1 dholland nfsrvd_mkdir,
95 1.1 dholland nfsrvd_symlink,
96 1.1 dholland nfsrvd_mknod,
97 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
98 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
99 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
100 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
101 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
102 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
103 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
104 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
105 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
106 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
107 1.1 dholland };
108 1.1 dholland
109 1.1 dholland int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
110 1.1 dholland int, vnode_t , vnode_t , NFSPROC_T *,
111 1.1 dholland struct nfsexstuff *, struct nfsexstuff *) = {
112 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
113 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
114 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
115 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
116 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
117 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
118 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
119 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
120 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
121 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
122 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
123 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
124 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
125 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
126 1.1 dholland nfsrvd_rename,
127 1.1 dholland nfsrvd_link,
128 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
129 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
130 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
131 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
132 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
133 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
134 1.1 dholland };
135 1.1 dholland
136 1.1 dholland int (*nfsrv4_ops0[NFSV4OP_NOPS])(struct nfsrv_descript *,
137 1.1 dholland int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
138 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
139 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
140 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
141 1.1 dholland nfsrvd_access,
142 1.1 dholland nfsrvd_close,
143 1.1 dholland nfsrvd_commit,
144 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
145 1.1 dholland nfsrvd_delegpurge,
146 1.1 dholland nfsrvd_delegreturn,
147 1.1 dholland nfsrvd_getattr,
148 1.1 dholland nfsrvd_getfh,
149 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
150 1.1 dholland nfsrvd_lock,
151 1.1 dholland nfsrvd_lockt,
152 1.1 dholland nfsrvd_locku,
153 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
154 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
155 1.1 dholland nfsrvd_verify,
156 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
157 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
158 1.1 dholland nfsrvd_openconfirm,
159 1.1 dholland nfsrvd_opendowngrade,
160 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
161 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
162 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
163 1.1 dholland nfsrvd_read,
164 1.1 dholland nfsrvd_readdirplus,
165 1.1 dholland nfsrvd_readlink,
166 1.1 dholland nfsrvd_remove,
167 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
168 1.1 dholland nfsrvd_renew,
169 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
170 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
171 1.1 dholland nfsrvd_secinfo,
172 1.1 dholland nfsrvd_setattr,
173 1.1 dholland nfsrvd_setclientid,
174 1.1 dholland nfsrvd_setclientidcfrm,
175 1.1 dholland nfsrvd_verify,
176 1.1 dholland nfsrvd_write,
177 1.1 dholland nfsrvd_releaselckown,
178 1.1 dholland };
179 1.1 dholland
180 1.1 dholland int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct nfsrv_descript *,
181 1.1 dholland int, vnode_t , vnode_t *, fhandle_t *,
182 1.1 dholland NFSPROC_T *, struct nfsexstuff *) = {
183 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
184 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
185 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
186 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
187 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
188 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
189 1.1 dholland nfsrvd_mknod,
190 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
191 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
192 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
193 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
194 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
195 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
196 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
197 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
198 1.1 dholland nfsrvd_lookup,
199 1.1 dholland nfsrvd_lookup,
200 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
201 1.1 dholland nfsrvd_open,
202 1.1 dholland nfsrvd_openattr,
203 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
204 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
205 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
206 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
207 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
208 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
209 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
210 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
211 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
212 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
213 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
214 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
215 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
216 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
217 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
218 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
219 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
220 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
221 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
222 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
223 1.1 dholland };
224 1.1 dholland
225 1.1 dholland int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct nfsrv_descript *,
226 1.1 dholland int, vnode_t , vnode_t , NFSPROC_T *,
227 1.1 dholland struct nfsexstuff *, struct nfsexstuff *) = {
228 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
229 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
230 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
231 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
232 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
233 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
234 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
235 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
236 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
237 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
238 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
239 1.1 dholland nfsrvd_link,
240 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
241 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
242 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
243 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
244 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
245 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
246 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
247 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
248 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
249 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
250 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
251 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
252 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
253 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
254 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
255 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
256 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
257 1.1 dholland nfsrvd_rename,
258 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
259 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
260 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
261 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
262 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
263 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
264 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
265 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
266 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
267 1.1 dholland (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
268 1.1 dholland };
269 1.1 dholland #endif /* !APPLEKEXT */
270 1.1 dholland
271 1.1 dholland /*
272 1.1 dholland * Static array that defines which nfs rpc's are nonidempotent
273 1.1 dholland */
274 1.1 dholland static int nfsrv_nonidempotent[NFS_V3NPROCS] = {
275 1.1 dholland FALSE,
276 1.1 dholland FALSE,
277 1.1 dholland TRUE,
278 1.1 dholland FALSE,
279 1.1 dholland FALSE,
280 1.1 dholland FALSE,
281 1.1 dholland FALSE,
282 1.1 dholland TRUE,
283 1.1 dholland TRUE,
284 1.1 dholland TRUE,
285 1.1 dholland TRUE,
286 1.1 dholland TRUE,
287 1.1 dholland TRUE,
288 1.1 dholland TRUE,
289 1.1 dholland TRUE,
290 1.1 dholland TRUE,
291 1.1 dholland FALSE,
292 1.1 dholland FALSE,
293 1.1 dholland FALSE,
294 1.1 dholland FALSE,
295 1.1 dholland FALSE,
296 1.1 dholland FALSE,
297 1.1 dholland };
298 1.1 dholland
299 1.1 dholland /*
300 1.1 dholland * This static array indicates whether or not the RPC modifies the
301 1.1 dholland * file system.
302 1.1 dholland */
303 1.1 dholland static int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
304 1.1 dholland 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
305 1.1 dholland 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
306 1.1 dholland
307 1.1 dholland /* local functions */
308 1.1 dholland static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
309 1.1 dholland NFSPROC_T *p);
310 1.1 dholland
311 1.1 dholland
312 1.1 dholland /*
313 1.1 dholland * This static array indicates which server procedures require the extra
314 1.1 dholland * arguments to return the current file handle for V2, 3.
315 1.1 dholland */
316 1.1 dholland static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
317 1.1 dholland 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
318 1.1 dholland
319 1.1 dholland extern struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS];
320 1.1 dholland
321 1.1 dholland static int nfsv3to4op[NFS_V3NPROCS] = {
322 1.1 dholland NFSPROC_NULL,
323 1.1 dholland NFSV4OP_GETATTR,
324 1.1 dholland NFSV4OP_SETATTR,
325 1.1 dholland NFSV4OP_LOOKUP,
326 1.1 dholland NFSV4OP_ACCESS,
327 1.1 dholland NFSV4OP_READLINK,
328 1.1 dholland NFSV4OP_READ,
329 1.1 dholland NFSV4OP_WRITE,
330 1.1 dholland NFSV4OP_V3CREATE,
331 1.1 dholland NFSV4OP_MKDIR,
332 1.1 dholland NFSV4OP_SYMLINK,
333 1.1 dholland NFSV4OP_MKNOD,
334 1.1 dholland NFSV4OP_REMOVE,
335 1.1 dholland NFSV4OP_RMDIR,
336 1.1 dholland NFSV4OP_RENAME,
337 1.1 dholland NFSV4OP_LINK,
338 1.1 dholland NFSV4OP_READDIR,
339 1.1 dholland NFSV4OP_READDIRPLUS,
340 1.1 dholland NFSV4OP_FSSTAT,
341 1.1 dholland NFSV4OP_FSINFO,
342 1.1 dholland NFSV4OP_PATHCONF,
343 1.1 dholland NFSV4OP_COMMIT,
344 1.1 dholland };
345 1.1 dholland
346 1.1 dholland /*
347 1.1 dholland * Do an RPC. Basically, get the file handles translated to vnode pointers
348 1.1 dholland * and then call the appropriate server routine. The server routines are
349 1.1 dholland * split into groups, based on whether they use a file handle or file
350 1.1 dholland * handle plus name or ...
351 1.1 dholland * The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
352 1.1 dholland */
353 1.1 dholland APPLESTATIC void
354 1.1 dholland nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
355 1.1 dholland NFSPROC_T *p)
356 1.1 dholland {
357 1.1 dholland int error = 0, lktype;
358 1.1 dholland vnode_t vp;
359 1.1 dholland mount_t mp = NULL;
360 1.1 dholland struct nfsrvfh fh;
361 1.1 dholland struct nfsexstuff nes;
362 1.1 dholland
363 1.1 dholland /*
364 1.1 dholland * Get a locked vnode for the first file handle
365 1.1 dholland */
366 1.1 dholland if (!(nd->nd_flag & ND_NFSV4)) {
367 1.1 dholland KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc"));
368 1.1 dholland /*
369 1.1 dholland * For NFSv3, if the malloc/mget allocation is near limits,
370 1.1 dholland * return NFSERR_DELAY.
371 1.1 dholland */
372 1.1 dholland if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) {
373 1.1 dholland nd->nd_repstat = NFSERR_DELAY;
374 1.1 dholland vp = NULL;
375 1.1 dholland } else {
376 1.1 dholland error = nfsrv_mtofh(nd, &fh);
377 1.1 dholland if (error) {
378 1.1 dholland if (error != EBADRPC)
379 1.1 dholland printf("nfs dorpc err1=%d\n", error);
380 1.1 dholland nd->nd_repstat = NFSERR_GARBAGE;
381 1.1 dholland goto out;
382 1.1 dholland }
383 1.1 dholland if (nd->nd_procnum == NFSPROC_READ ||
384 1.1 dholland nd->nd_procnum == NFSPROC_WRITE ||
385 1.1 dholland nd->nd_procnum == NFSPROC_READDIR ||
386 1.1 dholland nd->nd_procnum == NFSPROC_READLINK ||
387 1.1 dholland nd->nd_procnum == NFSPROC_GETATTR ||
388 1.1 dholland nd->nd_procnum == NFSPROC_ACCESS)
389 1.1 dholland lktype = LK_SHARED;
390 1.1 dholland else
391 1.1 dholland lktype = LK_EXCLUSIVE;
392 1.1 dholland if (nd->nd_flag & ND_PUBLOOKUP)
393 1.1 dholland nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
394 1.1 dholland &mp, nfs_writerpc[nd->nd_procnum], p);
395 1.1 dholland else
396 1.1 dholland nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
397 1.1 dholland &mp, nfs_writerpc[nd->nd_procnum], p);
398 1.1 dholland if (nd->nd_repstat == NFSERR_PROGNOTV4)
399 1.1 dholland goto out;
400 1.1 dholland }
401 1.1 dholland }
402 1.1 dholland
403 1.1 dholland /*
404 1.1 dholland * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
405 1.1 dholland * cache, as required.
406 1.1 dholland * For V4, nfsrvd_compound() does this.
407 1.1 dholland */
408 1.1 dholland if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
409 1.1 dholland nd->nd_flag |= ND_SAVEREPLY;
410 1.1 dholland
411 1.1 dholland nfsrvd_rephead(nd);
412 1.1 dholland /*
413 1.1 dholland * If nd_repstat is non-zero, just fill in the reply status
414 1.1 dholland * to complete the RPC reply for V2. Otherwise, you must do
415 1.1 dholland * the RPC.
416 1.1 dholland */
417 1.1 dholland if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
418 1.1 dholland *nd->nd_errp = nfsd_errmap(nd);
419 1.1 dholland NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
420 1.1 dholland if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
421 1.1 dholland vn_finished_write(mp);
422 1.1 dholland goto out;
423 1.1 dholland }
424 1.1 dholland
425 1.1 dholland /*
426 1.1 dholland * Now the procedure can be performed. For V4, nfsrvd_compound()
427 1.1 dholland * works through the sub-rpcs, otherwise just call the procedure.
428 1.1 dholland * The procedures are in three groups with different arguments.
429 1.1 dholland * The group is indicated by the value in nfs_retfh[].
430 1.1 dholland */
431 1.1 dholland if (nd->nd_flag & ND_NFSV4) {
432 1.1 dholland nfsrvd_compound(nd, isdgram, p);
433 1.1 dholland } else {
434 1.1 dholland if (nfs_retfh[nd->nd_procnum] == 1) {
435 1.1 dholland if (vp)
436 1.1 dholland NFSVOPUNLOCK(vp, 0);
437 1.1 dholland error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
438 1.1 dholland vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes);
439 1.1 dholland } else if (nfs_retfh[nd->nd_procnum] == 2) {
440 1.1 dholland error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
441 1.1 dholland vp, NULL, p, &nes, NULL);
442 1.1 dholland } else {
443 1.1 dholland error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
444 1.1 dholland vp, p, &nes);
445 1.1 dholland }
446 1.1 dholland if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
447 1.1 dholland vn_finished_write(mp);
448 1.1 dholland NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
449 1.1 dholland }
450 1.1 dholland if (error) {
451 1.1 dholland if (error != EBADRPC)
452 1.1 dholland printf("nfs dorpc err2=%d\n", error);
453 1.1 dholland nd->nd_repstat = NFSERR_GARBAGE;
454 1.1 dholland }
455 1.1 dholland *nd->nd_errp = nfsd_errmap(nd);
456 1.1 dholland
457 1.1 dholland /*
458 1.1 dholland * Don't cache certain reply status values.
459 1.1 dholland */
460 1.1 dholland if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
461 1.1 dholland (nd->nd_repstat == NFSERR_GARBAGE ||
462 1.1 dholland nd->nd_repstat == NFSERR_BADXDR ||
463 1.1 dholland nd->nd_repstat == NFSERR_MOVED ||
464 1.1 dholland nd->nd_repstat == NFSERR_DELAY ||
465 1.1 dholland nd->nd_repstat == NFSERR_BADSEQID ||
466 1.1 dholland nd->nd_repstat == NFSERR_RESOURCE ||
467 1.1 dholland nd->nd_repstat == NFSERR_SERVERFAULT ||
468 1.1 dholland nd->nd_repstat == NFSERR_STALECLIENTID ||
469 1.1 dholland nd->nd_repstat == NFSERR_STALESTATEID ||
470 1.1 dholland nd->nd_repstat == NFSERR_OLDSTATEID ||
471 1.1 dholland nd->nd_repstat == NFSERR_BADSTATEID ||
472 1.1 dholland nd->nd_repstat == NFSERR_GRACE ||
473 1.1 dholland nd->nd_repstat == NFSERR_NOGRACE))
474 1.1 dholland nd->nd_flag &= ~ND_SAVEREPLY;
475 1.1 dholland
476 1.1 dholland out:
477 1.1 dholland NFSEXITCODE2(0, nd);
478 1.1 dholland }
479 1.1 dholland
480 1.1 dholland /*
481 1.1 dholland * Breaks down a compound RPC request and calls the server routines for
482 1.1 dholland * the subprocedures.
483 1.1 dholland * Some suboperations are performed directly here to simplify file handle<-->
484 1.1 dholland * vnode pointer handling.
485 1.1 dholland */
486 1.1 dholland static void
487 1.1 dholland nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
488 1.1 dholland NFSPROC_T *p)
489 1.1 dholland {
490 1.1 dholland int i, op;
491 1.1 dholland u_int32_t *tl;
492 1.1 dholland struct nfsclient *clp, *nclp;
493 1.1 dholland int numops, taglen = -1, error = 0, igotlock;
494 1.1 dholland u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp;
495 1.1 dholland u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
496 1.1 dholland vnode_t vp, nvp, savevp;
497 1.1 dholland struct nfsrvfh fh;
498 1.1 dholland mount_t new_mp, temp_mp = NULL;
499 1.1 dholland struct ucred *credanon;
500 1.1 dholland struct nfsexstuff nes, vpnes, savevpnes;
501 1.1 dholland fsid_t cur_fsid, save_fsid;
502 1.1 dholland static u_int64_t compref = 0;
503 1.1 dholland
504 1.1 dholland NFSVNO_EXINIT(&vpnes);
505 1.1 dholland NFSVNO_EXINIT(&savevpnes);
506 1.1 dholland /*
507 1.1 dholland * Put the seq# of the current compound RPC in nfsrv_descript.
508 1.1 dholland * (This is used by nfsrv_checkgetattr(), to see if the write
509 1.1 dholland * delegation was created by the same compound RPC as the one
510 1.1 dholland * with that Getattr in it.)
511 1.1 dholland * Don't worry about the 64bit number wrapping around. It ain't
512 1.1 dholland * gonna happen before this server gets shut down/rebooted.
513 1.1 dholland */
514 1.1 dholland nd->nd_compref = compref++;
515 1.1 dholland
516 1.1 dholland /*
517 1.1 dholland * Check for and optionally get a lock on the root. This lock means that
518 1.1 dholland * no nfsd will be fiddling with the V4 file system and state stuff. It
519 1.1 dholland * is required when the V4 root is being changed, the stable storage
520 1.1 dholland * restart file is being updated, or callbacks are being done.
521 1.1 dholland * When any of the nfsd are processing an NFSv4 compound RPC, they must
522 1.1 dholland * either hold a reference count (nfs_usecnt) or the lock. When
523 1.1 dholland * nfsrv_unlock() is called to release the lock, it can optionally
524 1.1 dholland * also get a reference count, which saves the need for a call to
525 1.1 dholland * nfsrv_getref() after nfsrv_unlock().
526 1.1 dholland */
527 1.1 dholland /*
528 1.1 dholland * First, check to see if we need to wait for an update lock.
529 1.1 dholland */
530 1.1 dholland igotlock = 0;
531 1.1 dholland NFSLOCKV4ROOTMUTEX();
532 1.1 dholland if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
533 1.1 dholland igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
534 1.1 dholland NFSV4ROOTLOCKMUTEXPTR, NULL);
535 1.1 dholland else
536 1.1 dholland igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
537 1.1 dholland NFSV4ROOTLOCKMUTEXPTR, NULL);
538 1.1 dholland NFSUNLOCKV4ROOTMUTEX();
539 1.1 dholland if (igotlock) {
540 1.1 dholland /*
541 1.1 dholland * If I got the lock, I can update the stable storage file.
542 1.1 dholland * Done when the grace period is over or a client has long
543 1.1 dholland * since expired.
544 1.1 dholland */
545 1.1 dholland nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
546 1.1 dholland if ((nfsrv_stablefirst.nsf_flags &
547 1.1 dholland (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
548 1.1 dholland nfsrv_updatestable(p);
549 1.1 dholland
550 1.1 dholland /*
551 1.1 dholland * If at least one client has long since expired, search
552 1.1 dholland * the client list for them, write a REVOKE record on the
553 1.1 dholland * stable storage file and then remove them from the client
554 1.1 dholland * list.
555 1.1 dholland */
556 1.1 dholland if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
557 1.1 dholland nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
558 1.1 dholland for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
559 1.1 dholland LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
560 1.1 dholland nclp) {
561 1.1 dholland if (clp->lc_flags & LCL_EXPIREIT) {
562 1.1 dholland if (!LIST_EMPTY(&clp->lc_open) ||
563 1.1 dholland !LIST_EMPTY(&clp->lc_deleg))
564 1.1 dholland nfsrv_writestable(clp->lc_id,
565 1.1 dholland clp->lc_idlen, NFSNST_REVOKE, p);
566 1.1 dholland nfsrv_cleanclient(clp, p);
567 1.1 dholland nfsrv_freedeleglist(&clp->lc_deleg);
568 1.1 dholland nfsrv_freedeleglist(&clp->lc_olddeleg);
569 1.1 dholland LIST_REMOVE(clp, lc_hash);
570 1.1 dholland nfsrv_zapclient(clp, p);
571 1.1 dholland }
572 1.1 dholland }
573 1.1 dholland }
574 1.1 dholland }
575 1.1 dholland NFSLOCKV4ROOTMUTEX();
576 1.1 dholland nfsv4_unlock(&nfsv4rootfs_lock, 1);
577 1.1 dholland NFSUNLOCKV4ROOTMUTEX();
578 1.1 dholland } else {
579 1.1 dholland /*
580 1.1 dholland * If we didn't get the lock, we need to get a refcnt,
581 1.1 dholland * which also checks for and waits for the lock.
582 1.1 dholland */
583 1.1 dholland NFSLOCKV4ROOTMUTEX();
584 1.1 dholland nfsv4_getref(&nfsv4rootfs_lock, NULL,
585 1.1 dholland NFSV4ROOTLOCKMUTEXPTR, NULL);
586 1.1 dholland NFSUNLOCKV4ROOTMUTEX();
587 1.1 dholland }
588 1.1 dholland
589 1.1 dholland /*
590 1.1 dholland * If flagged, search for open owners that haven't had any opens
591 1.1 dholland * for a long time.
592 1.1 dholland */
593 1.1 dholland if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
594 1.1 dholland nfsrv_throwawayopens(p);
595 1.1 dholland }
596 1.1 dholland
597 1.1 dholland savevp = vp = NULL;
598 1.1 dholland save_fsid.val[0] = save_fsid.val[1] = 0;
599 1.1 dholland cur_fsid.val[0] = cur_fsid.val[1] = 0;
600 1.1 dholland NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
601 1.1 dholland taglen = fxdr_unsigned(int, *tl);
602 1.1 dholland if (taglen < 0) {
603 1.1 dholland error = EBADRPC;
604 1.1 dholland goto nfsmout;
605 1.1 dholland }
606 1.1 dholland if (taglen <= NFSV4_SMALLSTR)
607 1.1 dholland tagstr = tag;
608 1.1 dholland else
609 1.1 dholland tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK);
610 1.1 dholland error = nfsrv_mtostr(nd, tagstr, taglen);
611 1.1 dholland if (error) {
612 1.1 dholland if (taglen > NFSV4_SMALLSTR)
613 1.1 dholland free(tagstr, M_TEMP);
614 1.1 dholland taglen = -1;
615 1.1 dholland goto nfsmout;
616 1.1 dholland }
617 1.1 dholland (void) nfsm_strtom(nd, tag, taglen);
618 1.1 dholland if (taglen > NFSV4_SMALLSTR) {
619 1.1 dholland free(tagstr, M_TEMP);
620 1.1 dholland }
621 1.1 dholland NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
622 1.1 dholland NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
623 1.1 dholland minorvers = fxdr_unsigned(u_int32_t, *tl++);
624 1.1 dholland if (minorvers != NFSV4_MINORVERSION)
625 1.1 dholland nd->nd_repstat = NFSERR_MINORVERMISMATCH;
626 1.1 dholland if (nd->nd_repstat)
627 1.1 dholland numops = 0;
628 1.1 dholland else
629 1.1 dholland numops = fxdr_unsigned(int, *tl);
630 1.1 dholland /*
631 1.1 dholland * Loop around doing the sub ops.
632 1.1 dholland * vp - is an unlocked vnode pointer for the CFH
633 1.1 dholland * savevp - is an unlocked vnode pointer for the SAVEDFH
634 1.1 dholland * (at some future date, it might turn out to be more appropriate
635 1.1 dholland * to keep the file handles instead of vnode pointers?)
636 1.1 dholland * savevpnes and vpnes - are the export flags for the above.
637 1.1 dholland */
638 1.1 dholland for (i = 0; i < numops; i++) {
639 1.1 dholland NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
640 1.1 dholland NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
641 1.1 dholland *repp = *tl;
642 1.1 dholland op = fxdr_unsigned(int, *tl);
643 1.1 dholland if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) {
644 1.1 dholland nd->nd_repstat = NFSERR_OPILLEGAL;
645 1.1 dholland *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
646 1.1 dholland *repp = nfsd_errmap(nd);
647 1.1 dholland retops++;
648 1.1 dholland break;
649 1.1 dholland } else {
650 1.1 dholland repp++;
651 1.1 dholland }
652 1.1 dholland
653 1.1 dholland /*
654 1.1 dholland * Check for a referral on the current FH and, if so, return
655 1.1 dholland * NFSERR_MOVED for all ops that allow it, except Getattr.
656 1.1 dholland */
657 1.1 dholland if (vp != NULL && op != NFSV4OP_GETATTR &&
658 1.1 dholland nfsv4root_getreferral(vp, NULL, 0) != NULL &&
659 1.1 dholland nfsrv_errmoved(op)) {
660 1.1 dholland nd->nd_repstat = NFSERR_MOVED;
661 1.1 dholland *repp = nfsd_errmap(nd);
662 1.1 dholland retops++;
663 1.1 dholland break;
664 1.1 dholland }
665 1.1 dholland
666 1.1 dholland nd->nd_procnum = op;
667 1.1 dholland /*
668 1.1 dholland * If over flood level, reply NFSERR_RESOURCE, if at the first
669 1.1 dholland * Op. (Since a client recovery from NFSERR_RESOURCE can get
670 1.1 dholland * really nasty for certain Op sequences, I'll play it safe
671 1.1 dholland * and only return the error at the beginning.) The cache
672 1.1 dholland * will still function over flood level, but uses lots of
673 1.1 dholland * mbufs.)
674 1.1 dholland * If nfsrv_mallocmget_limit() returns True, the system is near
675 1.1 dholland * to its limit for memory that malloc()/mget() can allocate.
676 1.1 dholland */
677 1.1 dholland if (i == 0 && nd->nd_rp->rc_refcnt == 0 &&
678 1.1 dholland (nfsrv_mallocmget_limit() ||
679 1.1 dholland nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
680 1.1 dholland if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) {
681 1.1 dholland printf("nfsd server cache flooded, try to");
682 1.1 dholland printf(" increase nfsrc_floodlevel\n");
683 1.1 dholland }
684 1.1 dholland nd->nd_repstat = NFSERR_RESOURCE;
685 1.1 dholland *repp = nfsd_errmap(nd);
686 1.1 dholland if (op == NFSV4OP_SETATTR) {
687 1.1 dholland /*
688 1.1 dholland * Setattr replies require a bitmap.
689 1.1 dholland * even for errors like these.
690 1.1 dholland */
691 1.1 dholland NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
692 1.1 dholland *tl = 0;
693 1.1 dholland }
694 1.1 dholland retops++;
695 1.1 dholland break;
696 1.1 dholland }
697 1.1 dholland if (nfsv4_opflag[op].savereply)
698 1.1 dholland nd->nd_flag |= ND_SAVEREPLY;
699 1.1 dholland NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
700 1.1 dholland switch (op) {
701 1.1 dholland case NFSV4OP_PUTFH:
702 1.1 dholland error = nfsrv_mtofh(nd, &fh);
703 1.1 dholland if (error)
704 1.1 dholland goto nfsmout;
705 1.1 dholland if (!nd->nd_repstat)
706 1.1 dholland nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
707 1.1 dholland NULL, 0, p);
708 1.1 dholland /* For now, allow this for non-export FHs */
709 1.1 dholland if (!nd->nd_repstat) {
710 1.1 dholland if (vp)
711 1.1 dholland vrele(vp);
712 1.1 dholland vp = nvp;
713 1.1 dholland cur_fsid = vp->v_mount->mnt_stat.f_fsid;
714 1.1 dholland NFSVOPUNLOCK(vp, 0);
715 1.1 dholland vpnes = nes;
716 1.1 dholland }
717 1.1 dholland break;
718 1.1 dholland case NFSV4OP_PUTPUBFH:
719 1.1 dholland if (nfs_pubfhset)
720 1.1 dholland nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
721 1.1 dholland &nes, NULL, 0, p);
722 1.1 dholland else
723 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
724 1.1 dholland if (!nd->nd_repstat) {
725 1.1 dholland if (vp)
726 1.1 dholland vrele(vp);
727 1.1 dholland vp = nvp;
728 1.1 dholland cur_fsid = vp->v_mount->mnt_stat.f_fsid;
729 1.1 dholland NFSVOPUNLOCK(vp, 0);
730 1.1 dholland vpnes = nes;
731 1.1 dholland }
732 1.1 dholland break;
733 1.1 dholland case NFSV4OP_PUTROOTFH:
734 1.1 dholland if (nfs_rootfhset) {
735 1.1 dholland nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
736 1.1 dholland &nes, NULL, 0, p);
737 1.1 dholland if (!nd->nd_repstat) {
738 1.1 dholland if (vp)
739 1.1 dholland vrele(vp);
740 1.1 dholland vp = nvp;
741 1.1 dholland cur_fsid = vp->v_mount->mnt_stat.f_fsid;
742 1.1 dholland NFSVOPUNLOCK(vp, 0);
743 1.1 dholland vpnes = nes;
744 1.1 dholland }
745 1.1 dholland } else
746 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
747 1.1 dholland break;
748 1.1 dholland case NFSV4OP_SAVEFH:
749 1.1 dholland if (vp && NFSVNO_EXPORTED(&vpnes)) {
750 1.1 dholland nd->nd_repstat = 0;
751 1.1 dholland /* If vp == savevp, a no-op */
752 1.1 dholland if (vp != savevp) {
753 1.1 dholland if (savevp)
754 1.1 dholland vrele(savevp);
755 1.1 dholland VREF(vp);
756 1.1 dholland savevp = vp;
757 1.1 dholland savevpnes = vpnes;
758 1.1 dholland save_fsid = cur_fsid;
759 1.1 dholland }
760 1.1 dholland } else {
761 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
762 1.1 dholland }
763 1.1 dholland break;
764 1.1 dholland case NFSV4OP_RESTOREFH:
765 1.1 dholland if (savevp) {
766 1.1 dholland nd->nd_repstat = 0;
767 1.1 dholland /* If vp == savevp, a no-op */
768 1.1 dholland if (vp != savevp) {
769 1.1 dholland VREF(savevp);
770 1.1 dholland vrele(vp);
771 1.1 dholland vp = savevp;
772 1.1 dholland vpnes = savevpnes;
773 1.1 dholland cur_fsid = save_fsid;
774 1.1 dholland }
775 1.1 dholland } else {
776 1.1 dholland nd->nd_repstat = NFSERR_RESTOREFH;
777 1.1 dholland }
778 1.1 dholland break;
779 1.1 dholland default:
780 1.1 dholland /*
781 1.1 dholland * Allow a Lookup, Getattr, GetFH, Secinfo on an
782 1.1 dholland * non-exported directory if
783 1.1 dholland * nfs_rootfhset. Do I need to allow any other Ops?
784 1.1 dholland * (You can only have a non-exported vpnes if
785 1.1 dholland * nfs_rootfhset is true. See nfsd_fhtovp())
786 1.1 dholland * Allow AUTH_SYS to be used for file systems
787 1.1 dholland * exported GSS only for certain Ops, to allow
788 1.1 dholland * clients to do mounts more easily.
789 1.1 dholland */
790 1.1 dholland if (nfsv4_opflag[op].needscfh && vp) {
791 1.1 dholland if (!NFSVNO_EXPORTED(&vpnes) &&
792 1.1 dholland op != NFSV4OP_LOOKUP &&
793 1.1 dholland op != NFSV4OP_GETATTR &&
794 1.1 dholland op != NFSV4OP_GETFH &&
795 1.1 dholland op != NFSV4OP_ACCESS &&
796 1.1 dholland op != NFSV4OP_READLINK &&
797 1.1 dholland op != NFSV4OP_SECINFO)
798 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
799 1.1 dholland else if (nfsvno_testexp(nd, &vpnes) &&
800 1.1 dholland op != NFSV4OP_LOOKUP &&
801 1.1 dholland op != NFSV4OP_GETFH &&
802 1.1 dholland op != NFSV4OP_GETATTR &&
803 1.1 dholland op != NFSV4OP_SECINFO)
804 1.1 dholland nd->nd_repstat = NFSERR_WRONGSEC;
805 1.1 dholland if (nd->nd_repstat) {
806 1.1 dholland if (op == NFSV4OP_SETATTR) {
807 1.1 dholland /*
808 1.1 dholland * Setattr reply requires a bitmap
809 1.1 dholland * even for errors like these.
810 1.1 dholland */
811 1.1 dholland NFSM_BUILD(tl, u_int32_t *,
812 1.1 dholland NFSX_UNSIGNED);
813 1.1 dholland *tl = 0;
814 1.1 dholland }
815 1.1 dholland break;
816 1.1 dholland }
817 1.1 dholland }
818 1.1 dholland if (nfsv4_opflag[op].retfh == 1) {
819 1.1 dholland if (!vp) {
820 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
821 1.1 dholland break;
822 1.1 dholland }
823 1.1 dholland VREF(vp);
824 1.1 dholland if (nfsv4_opflag[op].modifyfs)
825 1.1 dholland vn_start_write(vp, &temp_mp, V_WAIT);
826 1.1 dholland error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
827 1.1 dholland &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
828 1.1 dholland if (!error && !nd->nd_repstat) {
829 1.1 dholland if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
830 1.1 dholland new_mp = nvp->v_mount;
831 1.1 dholland if (cur_fsid.val[0] !=
832 1.1 dholland new_mp->mnt_stat.f_fsid.val[0] ||
833 1.1 dholland cur_fsid.val[1] !=
834 1.1 dholland new_mp->mnt_stat.f_fsid.val[1]) {
835 1.1 dholland /* crossed a server mount point */
836 1.1 dholland nd->nd_repstat = nfsvno_checkexp(new_mp,
837 1.1 dholland nd->nd_nam, &nes, &credanon);
838 1.1 dholland if (!nd->nd_repstat)
839 1.1 dholland nd->nd_repstat = nfsd_excred(nd,
840 1.1 dholland &nes, credanon);
841 1.1 dholland if (credanon != NULL)
842 1.1 dholland crfree(credanon);
843 1.1 dholland if (!nd->nd_repstat) {
844 1.1 dholland vpnes = nes;
845 1.1 dholland cur_fsid = new_mp->mnt_stat.f_fsid;
846 1.1 dholland }
847 1.1 dholland }
848 1.1 dholland /* Lookup ops return a locked vnode */
849 1.1 dholland NFSVOPUNLOCK(nvp, 0);
850 1.1 dholland }
851 1.1 dholland if (!nd->nd_repstat) {
852 1.1 dholland vrele(vp);
853 1.1 dholland vp = nvp;
854 1.1 dholland } else
855 1.1 dholland vrele(nvp);
856 1.1 dholland }
857 1.1 dholland if (nfsv4_opflag[op].modifyfs)
858 1.1 dholland vn_finished_write(temp_mp);
859 1.1 dholland } else if (nfsv4_opflag[op].retfh == 2) {
860 1.1 dholland if (vp == NULL || savevp == NULL) {
861 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
862 1.1 dholland break;
863 1.1 dholland } else if (cur_fsid.val[0] != save_fsid.val[0] ||
864 1.1 dholland cur_fsid.val[1] != save_fsid.val[1]) {
865 1.1 dholland nd->nd_repstat = NFSERR_XDEV;
866 1.1 dholland break;
867 1.1 dholland }
868 1.1 dholland if (nfsv4_opflag[op].modifyfs)
869 1.1 dholland vn_start_write(savevp, &temp_mp, V_WAIT);
870 1.1 dholland if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
871 1.1 dholland VREF(vp);
872 1.1 dholland VREF(savevp);
873 1.1 dholland error = (*(nfsrv4_ops2[op]))(nd, isdgram,
874 1.1 dholland savevp, vp, p, &savevpnes, &vpnes);
875 1.1 dholland } else
876 1.1 dholland nd->nd_repstat = NFSERR_PERM;
877 1.1 dholland if (nfsv4_opflag[op].modifyfs)
878 1.1 dholland vn_finished_write(temp_mp);
879 1.1 dholland } else {
880 1.1 dholland if (nfsv4_opflag[op].retfh != 0)
881 1.1 dholland panic("nfsrvd_compound");
882 1.1 dholland if (nfsv4_opflag[op].needscfh) {
883 1.1 dholland if (vp != NULL) {
884 1.1 dholland if (nfsv4_opflag[op].modifyfs)
885 1.1 dholland vn_start_write(vp, &temp_mp,
886 1.1 dholland V_WAIT);
887 1.1 dholland if (NFSVOPLOCK(vp, nfsv4_opflag[op].lktype)
888 1.1 dholland == 0)
889 1.1 dholland VREF(vp);
890 1.1 dholland else
891 1.1 dholland nd->nd_repstat = NFSERR_PERM;
892 1.1 dholland } else {
893 1.1 dholland nd->nd_repstat = NFSERR_NOFILEHANDLE;
894 1.1 dholland if (op == NFSV4OP_SETATTR) {
895 1.1 dholland /*
896 1.1 dholland * Setattr reply requires a
897 1.1 dholland * bitmap even for errors like
898 1.1 dholland * these.
899 1.1 dholland */
900 1.1 dholland NFSM_BUILD(tl, u_int32_t *,
901 1.1 dholland NFSX_UNSIGNED);
902 1.1 dholland *tl = 0;
903 1.1 dholland }
904 1.1 dholland break;
905 1.1 dholland }
906 1.1 dholland if (nd->nd_repstat == 0)
907 1.1 dholland error = (*(nfsrv4_ops0[op]))(nd,
908 1.1 dholland isdgram, vp, p, &vpnes);
909 1.1 dholland if (nfsv4_opflag[op].modifyfs)
910 1.1 dholland vn_finished_write(temp_mp);
911 1.1 dholland } else {
912 1.1 dholland error = (*(nfsrv4_ops0[op]))(nd, isdgram,
913 1.1 dholland NULL, p, &vpnes);
914 1.1 dholland }
915 1.1 dholland }
916 1.1 dholland };
917 1.1 dholland if (error) {
918 1.1 dholland if (error == EBADRPC || error == NFSERR_BADXDR) {
919 1.1 dholland nd->nd_repstat = NFSERR_BADXDR;
920 1.1 dholland } else {
921 1.1 dholland nd->nd_repstat = error;
922 1.1 dholland printf("nfsv4 comperr0=%d\n", error);
923 1.1 dholland }
924 1.1 dholland error = 0;
925 1.1 dholland }
926 1.1 dholland retops++;
927 1.1 dholland if (nd->nd_repstat) {
928 1.1 dholland *repp = nfsd_errmap(nd);
929 1.1 dholland break;
930 1.1 dholland } else {
931 1.1 dholland *repp = 0; /* NFS4_OK */
932 1.1 dholland }
933 1.1 dholland }
934 1.1 dholland nfsmout:
935 1.1 dholland if (error) {
936 1.1 dholland if (error == EBADRPC || error == NFSERR_BADXDR)
937 1.1 dholland nd->nd_repstat = NFSERR_BADXDR;
938 1.1 dholland else
939 1.1 dholland printf("nfsv4 comperr1=%d\n", error);
940 1.1 dholland }
941 1.1 dholland if (taglen == -1) {
942 1.1 dholland NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
943 1.1 dholland *tl++ = 0;
944 1.1 dholland *tl = 0;
945 1.1 dholland } else {
946 1.1 dholland *retopsp = txdr_unsigned(retops);
947 1.1 dholland }
948 1.1 dholland if (vp)
949 1.1 dholland vrele(vp);
950 1.1 dholland if (savevp)
951 1.1 dholland vrele(savevp);
952 1.1 dholland NFSLOCKV4ROOTMUTEX();
953 1.1 dholland nfsv4_relref(&nfsv4rootfs_lock);
954 1.1 dholland NFSUNLOCKV4ROOTMUTEX();
955 1.1 dholland
956 1.1 dholland NFSEXITCODE2(0, nd);
957 1.1 dholland }
958