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