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