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