Commit 35f7a14fc1180164d6358a5885031fc187ef1bfa

Authored by J. Bruce Fields
1 parent 1c327d962f

nfsd4: fix minorversion support interface

You can turn on or off support for minorversions using e.g.

	echo "-4.2" >/proc/fs/nfsd/versions

However, the current implementation is a little wonky.  For example, the
above will turn off 4.2 support, but it will also turn *on* 4.1 support.

This didn't matter as long as we only had 2 minorversions, which was
true till very recently.

And do a little cleanup here.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>

Showing 3 changed files with 8 additions and 8 deletions Inline Diff

1 /* 1 /*
2 * Server-side procedures for NFSv4. 2 * Server-side procedures for NFSv4.
3 * 3 *
4 * Copyright (c) 2002 The Regents of the University of Michigan. 4 * Copyright (c) 2002 The Regents of the University of Michigan.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Kendrick Smith <kmsmith@umich.edu> 7 * Kendrick Smith <kmsmith@umich.edu>
8 * Andy Adamson <andros@umich.edu> 8 * Andy Adamson <andros@umich.edu>
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 13 *
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its 19 * 3. Neither the name of the University nor the names of its
20 * contributors may be used to endorse or promote products derived 20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission. 21 * from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 #include <linux/file.h> 35 #include <linux/file.h>
36 #include <linux/slab.h> 36 #include <linux/slab.h>
37 37
38 #include "idmap.h" 38 #include "idmap.h"
39 #include "cache.h" 39 #include "cache.h"
40 #include "xdr4.h" 40 #include "xdr4.h"
41 #include "vfs.h" 41 #include "vfs.h"
42 #include "current_stateid.h" 42 #include "current_stateid.h"
43 #include "netns.h" 43 #include "netns.h"
44 44
45 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL 45 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
46 #include <linux/security.h> 46 #include <linux/security.h>
47 47
48 static inline void 48 static inline void
49 nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval) 49 nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
50 { 50 {
51 struct inode *inode = resfh->fh_dentry->d_inode; 51 struct inode *inode = resfh->fh_dentry->d_inode;
52 int status; 52 int status;
53 53
54 mutex_lock(&inode->i_mutex); 54 mutex_lock(&inode->i_mutex);
55 status = security_inode_setsecctx(resfh->fh_dentry, 55 status = security_inode_setsecctx(resfh->fh_dentry,
56 label->data, label->len); 56 label->data, label->len);
57 mutex_unlock(&inode->i_mutex); 57 mutex_unlock(&inode->i_mutex);
58 58
59 if (status) 59 if (status)
60 /* 60 /*
61 * XXX: We should really fail the whole open, but we may 61 * XXX: We should really fail the whole open, but we may
62 * already have created a new file, so it may be too 62 * already have created a new file, so it may be too
63 * late. For now this seems the least of evils: 63 * late. For now this seems the least of evils:
64 */ 64 */
65 bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 65 bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
66 66
67 return; 67 return;
68 } 68 }
69 #else 69 #else
70 static inline void 70 static inline void
71 nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval) 71 nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
72 { } 72 { }
73 #endif 73 #endif
74 74
75 #define NFSDDBG_FACILITY NFSDDBG_PROC 75 #define NFSDDBG_FACILITY NFSDDBG_PROC
76 76
77 static u32 nfsd_attrmask[] = { 77 static u32 nfsd_attrmask[] = {
78 NFSD_WRITEABLE_ATTRS_WORD0, 78 NFSD_WRITEABLE_ATTRS_WORD0,
79 NFSD_WRITEABLE_ATTRS_WORD1, 79 NFSD_WRITEABLE_ATTRS_WORD1,
80 NFSD_WRITEABLE_ATTRS_WORD2 80 NFSD_WRITEABLE_ATTRS_WORD2
81 }; 81 };
82 82
83 static u32 nfsd41_ex_attrmask[] = { 83 static u32 nfsd41_ex_attrmask[] = {
84 NFSD_SUPPATTR_EXCLCREAT_WORD0, 84 NFSD_SUPPATTR_EXCLCREAT_WORD0,
85 NFSD_SUPPATTR_EXCLCREAT_WORD1, 85 NFSD_SUPPATTR_EXCLCREAT_WORD1,
86 NFSD_SUPPATTR_EXCLCREAT_WORD2 86 NFSD_SUPPATTR_EXCLCREAT_WORD2
87 }; 87 };
88 88
89 static __be32 89 static __be32
90 check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 90 check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
91 u32 *bmval, u32 *writable) 91 u32 *bmval, u32 *writable)
92 { 92 {
93 struct dentry *dentry = cstate->current_fh.fh_dentry; 93 struct dentry *dentry = cstate->current_fh.fh_dentry;
94 94
95 /* 95 /*
96 * Check about attributes are supported by the NFSv4 server or not. 96 * Check about attributes are supported by the NFSv4 server or not.
97 * According to spec, unsupported attributes return ERR_ATTRNOTSUPP. 97 * According to spec, unsupported attributes return ERR_ATTRNOTSUPP.
98 */ 98 */
99 if ((bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) || 99 if ((bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) ||
100 (bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) || 100 (bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) ||
101 (bmval[2] & ~nfsd_suppattrs2(cstate->minorversion))) 101 (bmval[2] & ~nfsd_suppattrs2(cstate->minorversion)))
102 return nfserr_attrnotsupp; 102 return nfserr_attrnotsupp;
103 103
104 /* 104 /*
105 * Check FATTR4_WORD0_ACL can be supported 105 * Check FATTR4_WORD0_ACL can be supported
106 * in current environment or not. 106 * in current environment or not.
107 */ 107 */
108 if (bmval[0] & FATTR4_WORD0_ACL) { 108 if (bmval[0] & FATTR4_WORD0_ACL) {
109 if (!IS_POSIXACL(dentry->d_inode)) 109 if (!IS_POSIXACL(dentry->d_inode))
110 return nfserr_attrnotsupp; 110 return nfserr_attrnotsupp;
111 } 111 }
112 112
113 /* 113 /*
114 * According to spec, read-only attributes return ERR_INVAL. 114 * According to spec, read-only attributes return ERR_INVAL.
115 */ 115 */
116 if (writable) { 116 if (writable) {
117 if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) || 117 if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
118 (bmval[2] & ~writable[2])) 118 (bmval[2] & ~writable[2]))
119 return nfserr_inval; 119 return nfserr_inval;
120 } 120 }
121 121
122 return nfs_ok; 122 return nfs_ok;
123 } 123 }
124 124
125 static __be32 125 static __be32
126 nfsd4_check_open_attributes(struct svc_rqst *rqstp, 126 nfsd4_check_open_attributes(struct svc_rqst *rqstp,
127 struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 127 struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
128 { 128 {
129 __be32 status = nfs_ok; 129 __be32 status = nfs_ok;
130 130
131 if (open->op_create == NFS4_OPEN_CREATE) { 131 if (open->op_create == NFS4_OPEN_CREATE) {
132 if (open->op_createmode == NFS4_CREATE_UNCHECKED 132 if (open->op_createmode == NFS4_CREATE_UNCHECKED
133 || open->op_createmode == NFS4_CREATE_GUARDED) 133 || open->op_createmode == NFS4_CREATE_GUARDED)
134 status = check_attr_support(rqstp, cstate, 134 status = check_attr_support(rqstp, cstate,
135 open->op_bmval, nfsd_attrmask); 135 open->op_bmval, nfsd_attrmask);
136 else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1) 136 else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1)
137 status = check_attr_support(rqstp, cstate, 137 status = check_attr_support(rqstp, cstate,
138 open->op_bmval, nfsd41_ex_attrmask); 138 open->op_bmval, nfsd41_ex_attrmask);
139 } 139 }
140 140
141 return status; 141 return status;
142 } 142 }
143 143
144 static int 144 static int
145 is_create_with_attrs(struct nfsd4_open *open) 145 is_create_with_attrs(struct nfsd4_open *open)
146 { 146 {
147 return open->op_create == NFS4_OPEN_CREATE 147 return open->op_create == NFS4_OPEN_CREATE
148 && (open->op_createmode == NFS4_CREATE_UNCHECKED 148 && (open->op_createmode == NFS4_CREATE_UNCHECKED
149 || open->op_createmode == NFS4_CREATE_GUARDED 149 || open->op_createmode == NFS4_CREATE_GUARDED
150 || open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1); 150 || open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1);
151 } 151 }
152 152
153 /* 153 /*
154 * if error occurs when setting the acl, just clear the acl bit 154 * if error occurs when setting the acl, just clear the acl bit
155 * in the returned attr bitmap. 155 * in the returned attr bitmap.
156 */ 156 */
157 static void 157 static void
158 do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, 158 do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
159 struct nfs4_acl *acl, u32 *bmval) 159 struct nfs4_acl *acl, u32 *bmval)
160 { 160 {
161 __be32 status; 161 __be32 status;
162 162
163 status = nfsd4_set_nfs4_acl(rqstp, fhp, acl); 163 status = nfsd4_set_nfs4_acl(rqstp, fhp, acl);
164 if (status) 164 if (status)
165 /* 165 /*
166 * We should probably fail the whole open at this point, 166 * We should probably fail the whole open at this point,
167 * but we've already created the file, so it's too late; 167 * but we've already created the file, so it's too late;
168 * So this seems the least of evils: 168 * So this seems the least of evils:
169 */ 169 */
170 bmval[0] &= ~FATTR4_WORD0_ACL; 170 bmval[0] &= ~FATTR4_WORD0_ACL;
171 } 171 }
172 172
173 static inline void 173 static inline void
174 fh_dup2(struct svc_fh *dst, struct svc_fh *src) 174 fh_dup2(struct svc_fh *dst, struct svc_fh *src)
175 { 175 {
176 fh_put(dst); 176 fh_put(dst);
177 dget(src->fh_dentry); 177 dget(src->fh_dentry);
178 if (src->fh_export) 178 if (src->fh_export)
179 cache_get(&src->fh_export->h); 179 cache_get(&src->fh_export->h);
180 *dst = *src; 180 *dst = *src;
181 } 181 }
182 182
183 static __be32 183 static __be32
184 do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode) 184 do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode)
185 { 185 {
186 __be32 status; 186 __be32 status;
187 187
188 if (open->op_truncate && 188 if (open->op_truncate &&
189 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) 189 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
190 return nfserr_inval; 190 return nfserr_inval;
191 191
192 accmode |= NFSD_MAY_READ_IF_EXEC; 192 accmode |= NFSD_MAY_READ_IF_EXEC;
193 193
194 if (open->op_share_access & NFS4_SHARE_ACCESS_READ) 194 if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
195 accmode |= NFSD_MAY_READ; 195 accmode |= NFSD_MAY_READ;
196 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 196 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
197 accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC); 197 accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC);
198 if (open->op_share_deny & NFS4_SHARE_DENY_READ) 198 if (open->op_share_deny & NFS4_SHARE_DENY_READ)
199 accmode |= NFSD_MAY_WRITE; 199 accmode |= NFSD_MAY_WRITE;
200 200
201 status = fh_verify(rqstp, current_fh, S_IFREG, accmode); 201 status = fh_verify(rqstp, current_fh, S_IFREG, accmode);
202 202
203 return status; 203 return status;
204 } 204 }
205 205
206 static __be32 nfsd_check_obj_isreg(struct svc_fh *fh) 206 static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
207 { 207 {
208 umode_t mode = fh->fh_dentry->d_inode->i_mode; 208 umode_t mode = fh->fh_dentry->d_inode->i_mode;
209 209
210 if (S_ISREG(mode)) 210 if (S_ISREG(mode))
211 return nfs_ok; 211 return nfs_ok;
212 if (S_ISDIR(mode)) 212 if (S_ISDIR(mode))
213 return nfserr_isdir; 213 return nfserr_isdir;
214 /* 214 /*
215 * Using err_symlink as our catch-all case may look odd; but 215 * Using err_symlink as our catch-all case may look odd; but
216 * there's no other obvious error for this case in 4.0, and we 216 * there's no other obvious error for this case in 4.0, and we
217 * happen to know that it will cause the linux v4 client to do 217 * happen to know that it will cause the linux v4 client to do
218 * the right thing on attempts to open something other than a 218 * the right thing on attempts to open something other than a
219 * regular file. 219 * regular file.
220 */ 220 */
221 return nfserr_symlink; 221 return nfserr_symlink;
222 } 222 }
223 223
224 static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh) 224 static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh)
225 { 225 {
226 if (nfsd4_has_session(cstate)) 226 if (nfsd4_has_session(cstate))
227 return; 227 return;
228 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 228 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
229 &resfh->fh_handle); 229 &resfh->fh_handle);
230 } 230 }
231 231
232 static __be32 232 static __be32
233 do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 233 do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
234 { 234 {
235 struct svc_fh *current_fh = &cstate->current_fh; 235 struct svc_fh *current_fh = &cstate->current_fh;
236 struct svc_fh *resfh; 236 struct svc_fh *resfh;
237 int accmode; 237 int accmode;
238 __be32 status; 238 __be32 status;
239 239
240 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); 240 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
241 if (!resfh) 241 if (!resfh)
242 return nfserr_jukebox; 242 return nfserr_jukebox;
243 fh_init(resfh, NFS4_FHSIZE); 243 fh_init(resfh, NFS4_FHSIZE);
244 open->op_truncate = 0; 244 open->op_truncate = 0;
245 245
246 if (open->op_create) { 246 if (open->op_create) {
247 /* FIXME: check session persistence and pnfs flags. 247 /* FIXME: check session persistence and pnfs flags.
248 * The nfsv4.1 spec requires the following semantics: 248 * The nfsv4.1 spec requires the following semantics:
249 * 249 *
250 * Persistent | pNFS | Server REQUIRED | Client Allowed 250 * Persistent | pNFS | Server REQUIRED | Client Allowed
251 * Reply Cache | server | | 251 * Reply Cache | server | |
252 * -------------+--------+-----------------+-------------------- 252 * -------------+--------+-----------------+--------------------
253 * no | no | EXCLUSIVE4_1 | EXCLUSIVE4_1 253 * no | no | EXCLUSIVE4_1 | EXCLUSIVE4_1
254 * | | | (SHOULD) 254 * | | | (SHOULD)
255 * | | and EXCLUSIVE4 | or EXCLUSIVE4 255 * | | and EXCLUSIVE4 | or EXCLUSIVE4
256 * | | | (SHOULD NOT) 256 * | | | (SHOULD NOT)
257 * no | yes | EXCLUSIVE4_1 | EXCLUSIVE4_1 257 * no | yes | EXCLUSIVE4_1 | EXCLUSIVE4_1
258 * yes | no | GUARDED4 | GUARDED4 258 * yes | no | GUARDED4 | GUARDED4
259 * yes | yes | GUARDED4 | GUARDED4 259 * yes | yes | GUARDED4 | GUARDED4
260 */ 260 */
261 261
262 /* 262 /*
263 * Note: create modes (UNCHECKED,GUARDED...) are the same 263 * Note: create modes (UNCHECKED,GUARDED...) are the same
264 * in NFSv4 as in v3 except EXCLUSIVE4_1. 264 * in NFSv4 as in v3 except EXCLUSIVE4_1.
265 */ 265 */
266 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, 266 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
267 open->op_fname.len, &open->op_iattr, 267 open->op_fname.len, &open->op_iattr,
268 resfh, open->op_createmode, 268 resfh, open->op_createmode,
269 (u32 *)open->op_verf.data, 269 (u32 *)open->op_verf.data,
270 &open->op_truncate, &open->op_created); 270 &open->op_truncate, &open->op_created);
271 271
272 if (!status && open->op_label.len) 272 if (!status && open->op_label.len)
273 nfsd4_security_inode_setsecctx(resfh, &open->op_label, open->op_bmval); 273 nfsd4_security_inode_setsecctx(resfh, &open->op_label, open->op_bmval);
274 274
275 /* 275 /*
276 * Following rfc 3530 14.2.16, use the returned bitmask 276 * Following rfc 3530 14.2.16, use the returned bitmask
277 * to indicate which attributes we used to store the 277 * to indicate which attributes we used to store the
278 * verifier: 278 * verifier:
279 */ 279 */
280 if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) 280 if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
281 open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | 281 open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
282 FATTR4_WORD1_TIME_MODIFY); 282 FATTR4_WORD1_TIME_MODIFY);
283 } else { 283 } else {
284 status = nfsd_lookup(rqstp, current_fh, 284 status = nfsd_lookup(rqstp, current_fh,
285 open->op_fname.data, open->op_fname.len, resfh); 285 open->op_fname.data, open->op_fname.len, resfh);
286 fh_unlock(current_fh); 286 fh_unlock(current_fh);
287 } 287 }
288 if (status) 288 if (status)
289 goto out; 289 goto out;
290 status = nfsd_check_obj_isreg(resfh); 290 status = nfsd_check_obj_isreg(resfh);
291 if (status) 291 if (status)
292 goto out; 292 goto out;
293 293
294 if (is_create_with_attrs(open) && open->op_acl != NULL) 294 if (is_create_with_attrs(open) && open->op_acl != NULL)
295 do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval); 295 do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
296 296
297 nfsd4_set_open_owner_reply_cache(cstate, open, resfh); 297 nfsd4_set_open_owner_reply_cache(cstate, open, resfh);
298 accmode = NFSD_MAY_NOP; 298 accmode = NFSD_MAY_NOP;
299 if (open->op_created || 299 if (open->op_created ||
300 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 300 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
301 accmode |= NFSD_MAY_OWNER_OVERRIDE; 301 accmode |= NFSD_MAY_OWNER_OVERRIDE;
302 status = do_open_permission(rqstp, resfh, open, accmode); 302 status = do_open_permission(rqstp, resfh, open, accmode);
303 set_change_info(&open->op_cinfo, current_fh); 303 set_change_info(&open->op_cinfo, current_fh);
304 fh_dup2(current_fh, resfh); 304 fh_dup2(current_fh, resfh);
305 out: 305 out:
306 fh_put(resfh); 306 fh_put(resfh);
307 kfree(resfh); 307 kfree(resfh);
308 return status; 308 return status;
309 } 309 }
310 310
311 static __be32 311 static __be32
312 do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 312 do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
313 { 313 {
314 struct svc_fh *current_fh = &cstate->current_fh; 314 struct svc_fh *current_fh = &cstate->current_fh;
315 __be32 status; 315 __be32 status;
316 int accmode = 0; 316 int accmode = 0;
317 317
318 /* We don't know the target directory, and therefore can not 318 /* We don't know the target directory, and therefore can not
319 * set the change info 319 * set the change info
320 */ 320 */
321 321
322 memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info)); 322 memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info));
323 323
324 nfsd4_set_open_owner_reply_cache(cstate, open, current_fh); 324 nfsd4_set_open_owner_reply_cache(cstate, open, current_fh);
325 325
326 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && 326 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
327 (open->op_iattr.ia_size == 0); 327 (open->op_iattr.ia_size == 0);
328 /* 328 /*
329 * In the delegation case, the client is telling us about an 329 * In the delegation case, the client is telling us about an
330 * open that it *already* performed locally, some time ago. We 330 * open that it *already* performed locally, some time ago. We
331 * should let it succeed now if possible. 331 * should let it succeed now if possible.
332 * 332 *
333 * In the case of a CLAIM_FH open, on the other hand, the client 333 * In the case of a CLAIM_FH open, on the other hand, the client
334 * may be counting on us to enforce permissions (the Linux 4.1 334 * may be counting on us to enforce permissions (the Linux 4.1
335 * client uses this for normal opens, for example). 335 * client uses this for normal opens, for example).
336 */ 336 */
337 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH) 337 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH)
338 accmode = NFSD_MAY_OWNER_OVERRIDE; 338 accmode = NFSD_MAY_OWNER_OVERRIDE;
339 339
340 status = do_open_permission(rqstp, current_fh, open, accmode); 340 status = do_open_permission(rqstp, current_fh, open, accmode);
341 341
342 return status; 342 return status;
343 } 343 }
344 344
345 static void 345 static void
346 copy_clientid(clientid_t *clid, struct nfsd4_session *session) 346 copy_clientid(clientid_t *clid, struct nfsd4_session *session)
347 { 347 {
348 struct nfsd4_sessionid *sid = 348 struct nfsd4_sessionid *sid =
349 (struct nfsd4_sessionid *)session->se_sessionid.data; 349 (struct nfsd4_sessionid *)session->se_sessionid.data;
350 350
351 clid->cl_boot = sid->clientid.cl_boot; 351 clid->cl_boot = sid->clientid.cl_boot;
352 clid->cl_id = sid->clientid.cl_id; 352 clid->cl_id = sid->clientid.cl_id;
353 } 353 }
354 354
355 static __be32 355 static __be32
356 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 356 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
357 struct nfsd4_open *open) 357 struct nfsd4_open *open)
358 { 358 {
359 __be32 status; 359 __be32 status;
360 struct nfsd4_compoundres *resp; 360 struct nfsd4_compoundres *resp;
361 struct net *net = SVC_NET(rqstp); 361 struct net *net = SVC_NET(rqstp);
362 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 362 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
363 363
364 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n", 364 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
365 (int)open->op_fname.len, open->op_fname.data, 365 (int)open->op_fname.len, open->op_fname.data,
366 open->op_openowner); 366 open->op_openowner);
367 367
368 /* This check required by spec. */ 368 /* This check required by spec. */
369 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 369 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
370 return nfserr_inval; 370 return nfserr_inval;
371 371
372 open->op_created = 0; 372 open->op_created = 0;
373 /* 373 /*
374 * RFC5661 18.51.3 374 * RFC5661 18.51.3
375 * Before RECLAIM_COMPLETE done, server should deny new lock 375 * Before RECLAIM_COMPLETE done, server should deny new lock
376 */ 376 */
377 if (nfsd4_has_session(cstate) && 377 if (nfsd4_has_session(cstate) &&
378 !test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, 378 !test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
379 &cstate->session->se_client->cl_flags) && 379 &cstate->session->se_client->cl_flags) &&
380 open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 380 open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
381 return nfserr_grace; 381 return nfserr_grace;
382 382
383 if (nfsd4_has_session(cstate)) 383 if (nfsd4_has_session(cstate))
384 copy_clientid(&open->op_clientid, cstate->session); 384 copy_clientid(&open->op_clientid, cstate->session);
385 385
386 nfs4_lock_state(); 386 nfs4_lock_state();
387 387
388 /* check seqid for replay. set nfs4_owner */ 388 /* check seqid for replay. set nfs4_owner */
389 resp = rqstp->rq_resp; 389 resp = rqstp->rq_resp;
390 status = nfsd4_process_open1(&resp->cstate, open, nn); 390 status = nfsd4_process_open1(&resp->cstate, open, nn);
391 if (status == nfserr_replay_me) { 391 if (status == nfserr_replay_me) {
392 struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay; 392 struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay;
393 fh_put(&cstate->current_fh); 393 fh_put(&cstate->current_fh);
394 fh_copy_shallow(&cstate->current_fh.fh_handle, 394 fh_copy_shallow(&cstate->current_fh.fh_handle,
395 &rp->rp_openfh); 395 &rp->rp_openfh);
396 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); 396 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
397 if (status) 397 if (status)
398 dprintk("nfsd4_open: replay failed" 398 dprintk("nfsd4_open: replay failed"
399 " restoring previous filehandle\n"); 399 " restoring previous filehandle\n");
400 else 400 else
401 status = nfserr_replay_me; 401 status = nfserr_replay_me;
402 } 402 }
403 if (status) 403 if (status)
404 goto out; 404 goto out;
405 if (open->op_xdr_error) { 405 if (open->op_xdr_error) {
406 status = open->op_xdr_error; 406 status = open->op_xdr_error;
407 goto out; 407 goto out;
408 } 408 }
409 409
410 status = nfsd4_check_open_attributes(rqstp, cstate, open); 410 status = nfsd4_check_open_attributes(rqstp, cstate, open);
411 if (status) 411 if (status)
412 goto out; 412 goto out;
413 413
414 /* Openowner is now set, so sequence id will get bumped. Now we need 414 /* Openowner is now set, so sequence id will get bumped. Now we need
415 * these checks before we do any creates: */ 415 * these checks before we do any creates: */
416 status = nfserr_grace; 416 status = nfserr_grace;
417 if (locks_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 417 if (locks_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
418 goto out; 418 goto out;
419 status = nfserr_no_grace; 419 status = nfserr_no_grace;
420 if (!locks_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 420 if (!locks_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
421 goto out; 421 goto out;
422 422
423 switch (open->op_claim_type) { 423 switch (open->op_claim_type) {
424 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 424 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
425 case NFS4_OPEN_CLAIM_NULL: 425 case NFS4_OPEN_CLAIM_NULL:
426 status = do_open_lookup(rqstp, cstate, open); 426 status = do_open_lookup(rqstp, cstate, open);
427 if (status) 427 if (status)
428 goto out; 428 goto out;
429 break; 429 break;
430 case NFS4_OPEN_CLAIM_PREVIOUS: 430 case NFS4_OPEN_CLAIM_PREVIOUS:
431 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 431 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
432 status = nfs4_check_open_reclaim(&open->op_clientid, 432 status = nfs4_check_open_reclaim(&open->op_clientid,
433 cstate->minorversion, 433 cstate->minorversion,
434 nn); 434 nn);
435 if (status) 435 if (status)
436 goto out; 436 goto out;
437 case NFS4_OPEN_CLAIM_FH: 437 case NFS4_OPEN_CLAIM_FH:
438 case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 438 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
439 status = do_open_fhandle(rqstp, cstate, open); 439 status = do_open_fhandle(rqstp, cstate, open);
440 if (status) 440 if (status)
441 goto out; 441 goto out;
442 break; 442 break;
443 case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 443 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
444 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 444 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
445 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 445 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
446 dprintk("NFSD: unsupported OPEN claim type %d\n", 446 dprintk("NFSD: unsupported OPEN claim type %d\n",
447 open->op_claim_type); 447 open->op_claim_type);
448 status = nfserr_notsupp; 448 status = nfserr_notsupp;
449 goto out; 449 goto out;
450 default: 450 default:
451 dprintk("NFSD: Invalid OPEN claim type %d\n", 451 dprintk("NFSD: Invalid OPEN claim type %d\n",
452 open->op_claim_type); 452 open->op_claim_type);
453 status = nfserr_inval; 453 status = nfserr_inval;
454 goto out; 454 goto out;
455 } 455 }
456 /* 456 /*
457 * nfsd4_process_open2() does the actual opening of the file. If 457 * nfsd4_process_open2() does the actual opening of the file. If
458 * successful, it (1) truncates the file if open->op_truncate was 458 * successful, it (1) truncates the file if open->op_truncate was
459 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 459 * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
460 */ 460 */
461 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 461 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open);
462 WARN_ON(status && open->op_created); 462 WARN_ON(status && open->op_created);
463 out: 463 out:
464 nfsd4_cleanup_open_state(open, status); 464 nfsd4_cleanup_open_state(open, status);
465 if (open->op_openowner && !nfsd4_has_session(cstate)) 465 if (open->op_openowner && !nfsd4_has_session(cstate))
466 cstate->replay_owner = &open->op_openowner->oo_owner; 466 cstate->replay_owner = &open->op_openowner->oo_owner;
467 nfsd4_bump_seqid(cstate, status); 467 nfsd4_bump_seqid(cstate, status);
468 if (!cstate->replay_owner) 468 if (!cstate->replay_owner)
469 nfs4_unlock_state(); 469 nfs4_unlock_state();
470 return status; 470 return status;
471 } 471 }
472 472
473 /* 473 /*
474 * OPEN is the only seqid-mutating operation whose decoding can fail 474 * OPEN is the only seqid-mutating operation whose decoding can fail
475 * with a seqid-mutating error (specifically, decoding of user names in 475 * with a seqid-mutating error (specifically, decoding of user names in
476 * the attributes). Therefore we have to do some processing to look up 476 * the attributes). Therefore we have to do some processing to look up
477 * the stateowner so that we can bump the seqid. 477 * the stateowner so that we can bump the seqid.
478 */ 478 */
479 static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op) 479 static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op)
480 { 480 {
481 struct nfsd4_open *open = (struct nfsd4_open *)&op->u; 481 struct nfsd4_open *open = (struct nfsd4_open *)&op->u;
482 482
483 if (!seqid_mutating_err(ntohl(op->status))) 483 if (!seqid_mutating_err(ntohl(op->status)))
484 return op->status; 484 return op->status;
485 if (nfsd4_has_session(cstate)) 485 if (nfsd4_has_session(cstate))
486 return op->status; 486 return op->status;
487 open->op_xdr_error = op->status; 487 open->op_xdr_error = op->status;
488 return nfsd4_open(rqstp, cstate, open); 488 return nfsd4_open(rqstp, cstate, open);
489 } 489 }
490 490
491 /* 491 /*
492 * filehandle-manipulating ops. 492 * filehandle-manipulating ops.
493 */ 493 */
494 static __be32 494 static __be32
495 nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 495 nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
496 struct svc_fh **getfh) 496 struct svc_fh **getfh)
497 { 497 {
498 if (!cstate->current_fh.fh_dentry) 498 if (!cstate->current_fh.fh_dentry)
499 return nfserr_nofilehandle; 499 return nfserr_nofilehandle;
500 500
501 *getfh = &cstate->current_fh; 501 *getfh = &cstate->current_fh;
502 return nfs_ok; 502 return nfs_ok;
503 } 503 }
504 504
505 static __be32 505 static __be32
506 nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 506 nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
507 struct nfsd4_putfh *putfh) 507 struct nfsd4_putfh *putfh)
508 { 508 {
509 fh_put(&cstate->current_fh); 509 fh_put(&cstate->current_fh);
510 cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; 510 cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen;
511 memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, 511 memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval,
512 putfh->pf_fhlen); 512 putfh->pf_fhlen);
513 return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); 513 return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS);
514 } 514 }
515 515
516 static __be32 516 static __be32
517 nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 517 nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
518 void *arg) 518 void *arg)
519 { 519 {
520 __be32 status; 520 __be32 status;
521 521
522 fh_put(&cstate->current_fh); 522 fh_put(&cstate->current_fh);
523 status = exp_pseudoroot(rqstp, &cstate->current_fh); 523 status = exp_pseudoroot(rqstp, &cstate->current_fh);
524 return status; 524 return status;
525 } 525 }
526 526
527 static __be32 527 static __be32
528 nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 528 nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
529 void *arg) 529 void *arg)
530 { 530 {
531 if (!cstate->save_fh.fh_dentry) 531 if (!cstate->save_fh.fh_dentry)
532 return nfserr_restorefh; 532 return nfserr_restorefh;
533 533
534 fh_dup2(&cstate->current_fh, &cstate->save_fh); 534 fh_dup2(&cstate->current_fh, &cstate->save_fh);
535 if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) { 535 if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) {
536 memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t)); 536 memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
537 SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); 537 SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
538 } 538 }
539 return nfs_ok; 539 return nfs_ok;
540 } 540 }
541 541
542 static __be32 542 static __be32
543 nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 543 nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
544 void *arg) 544 void *arg)
545 { 545 {
546 if (!cstate->current_fh.fh_dentry) 546 if (!cstate->current_fh.fh_dentry)
547 return nfserr_nofilehandle; 547 return nfserr_nofilehandle;
548 548
549 fh_dup2(&cstate->save_fh, &cstate->current_fh); 549 fh_dup2(&cstate->save_fh, &cstate->current_fh);
550 if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) { 550 if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) {
551 memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t)); 551 memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t));
552 SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG); 552 SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG);
553 } 553 }
554 return nfs_ok; 554 return nfs_ok;
555 } 555 }
556 556
557 /* 557 /*
558 * misc nfsv4 ops 558 * misc nfsv4 ops
559 */ 559 */
560 static __be32 560 static __be32
561 nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 561 nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
562 struct nfsd4_access *access) 562 struct nfsd4_access *access)
563 { 563 {
564 if (access->ac_req_access & ~NFS3_ACCESS_FULL) 564 if (access->ac_req_access & ~NFS3_ACCESS_FULL)
565 return nfserr_inval; 565 return nfserr_inval;
566 566
567 access->ac_resp_access = access->ac_req_access; 567 access->ac_resp_access = access->ac_req_access;
568 return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access, 568 return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access,
569 &access->ac_supported); 569 &access->ac_supported);
570 } 570 }
571 571
572 static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net) 572 static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net)
573 { 573 {
574 __be32 verf[2]; 574 __be32 verf[2];
575 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 575 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
576 576
577 verf[0] = (__be32)nn->nfssvc_boot.tv_sec; 577 verf[0] = (__be32)nn->nfssvc_boot.tv_sec;
578 verf[1] = (__be32)nn->nfssvc_boot.tv_usec; 578 verf[1] = (__be32)nn->nfssvc_boot.tv_usec;
579 memcpy(verifier->data, verf, sizeof(verifier->data)); 579 memcpy(verifier->data, verf, sizeof(verifier->data));
580 } 580 }
581 581
582 static __be32 582 static __be32
583 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 583 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
584 struct nfsd4_commit *commit) 584 struct nfsd4_commit *commit)
585 { 585 {
586 gen_boot_verifier(&commit->co_verf, SVC_NET(rqstp)); 586 gen_boot_verifier(&commit->co_verf, SVC_NET(rqstp));
587 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 587 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
588 commit->co_count); 588 commit->co_count);
589 } 589 }
590 590
591 static __be32 591 static __be32
592 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 592 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
593 struct nfsd4_create *create) 593 struct nfsd4_create *create)
594 { 594 {
595 struct svc_fh resfh; 595 struct svc_fh resfh;
596 __be32 status; 596 __be32 status;
597 dev_t rdev; 597 dev_t rdev;
598 598
599 fh_init(&resfh, NFS4_FHSIZE); 599 fh_init(&resfh, NFS4_FHSIZE);
600 600
601 status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, 601 status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR,
602 NFSD_MAY_CREATE); 602 NFSD_MAY_CREATE);
603 if (status) 603 if (status)
604 return status; 604 return status;
605 605
606 status = check_attr_support(rqstp, cstate, create->cr_bmval, 606 status = check_attr_support(rqstp, cstate, create->cr_bmval,
607 nfsd_attrmask); 607 nfsd_attrmask);
608 if (status) 608 if (status)
609 return status; 609 return status;
610 610
611 switch (create->cr_type) { 611 switch (create->cr_type) {
612 case NF4LNK: 612 case NF4LNK:
613 /* ugh! we have to null-terminate the linktext, or 613 /* ugh! we have to null-terminate the linktext, or
614 * vfs_symlink() will choke. it is always safe to 614 * vfs_symlink() will choke. it is always safe to
615 * null-terminate by brute force, since at worst we 615 * null-terminate by brute force, since at worst we
616 * will overwrite the first byte of the create namelen 616 * will overwrite the first byte of the create namelen
617 * in the XDR buffer, which has already been extracted 617 * in the XDR buffer, which has already been extracted
618 * during XDR decode. 618 * during XDR decode.
619 */ 619 */
620 create->cr_linkname[create->cr_linklen] = 0; 620 create->cr_linkname[create->cr_linklen] = 0;
621 621
622 status = nfsd_symlink(rqstp, &cstate->current_fh, 622 status = nfsd_symlink(rqstp, &cstate->current_fh,
623 create->cr_name, create->cr_namelen, 623 create->cr_name, create->cr_namelen,
624 create->cr_linkname, create->cr_linklen, 624 create->cr_linkname, create->cr_linklen,
625 &resfh, &create->cr_iattr); 625 &resfh, &create->cr_iattr);
626 break; 626 break;
627 627
628 case NF4BLK: 628 case NF4BLK:
629 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); 629 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
630 if (MAJOR(rdev) != create->cr_specdata1 || 630 if (MAJOR(rdev) != create->cr_specdata1 ||
631 MINOR(rdev) != create->cr_specdata2) 631 MINOR(rdev) != create->cr_specdata2)
632 return nfserr_inval; 632 return nfserr_inval;
633 status = nfsd_create(rqstp, &cstate->current_fh, 633 status = nfsd_create(rqstp, &cstate->current_fh,
634 create->cr_name, create->cr_namelen, 634 create->cr_name, create->cr_namelen,
635 &create->cr_iattr, S_IFBLK, rdev, &resfh); 635 &create->cr_iattr, S_IFBLK, rdev, &resfh);
636 break; 636 break;
637 637
638 case NF4CHR: 638 case NF4CHR:
639 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); 639 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
640 if (MAJOR(rdev) != create->cr_specdata1 || 640 if (MAJOR(rdev) != create->cr_specdata1 ||
641 MINOR(rdev) != create->cr_specdata2) 641 MINOR(rdev) != create->cr_specdata2)
642 return nfserr_inval; 642 return nfserr_inval;
643 status = nfsd_create(rqstp, &cstate->current_fh, 643 status = nfsd_create(rqstp, &cstate->current_fh,
644 create->cr_name, create->cr_namelen, 644 create->cr_name, create->cr_namelen,
645 &create->cr_iattr,S_IFCHR, rdev, &resfh); 645 &create->cr_iattr,S_IFCHR, rdev, &resfh);
646 break; 646 break;
647 647
648 case NF4SOCK: 648 case NF4SOCK:
649 status = nfsd_create(rqstp, &cstate->current_fh, 649 status = nfsd_create(rqstp, &cstate->current_fh,
650 create->cr_name, create->cr_namelen, 650 create->cr_name, create->cr_namelen,
651 &create->cr_iattr, S_IFSOCK, 0, &resfh); 651 &create->cr_iattr, S_IFSOCK, 0, &resfh);
652 break; 652 break;
653 653
654 case NF4FIFO: 654 case NF4FIFO:
655 status = nfsd_create(rqstp, &cstate->current_fh, 655 status = nfsd_create(rqstp, &cstate->current_fh,
656 create->cr_name, create->cr_namelen, 656 create->cr_name, create->cr_namelen,
657 &create->cr_iattr, S_IFIFO, 0, &resfh); 657 &create->cr_iattr, S_IFIFO, 0, &resfh);
658 break; 658 break;
659 659
660 case NF4DIR: 660 case NF4DIR:
661 create->cr_iattr.ia_valid &= ~ATTR_SIZE; 661 create->cr_iattr.ia_valid &= ~ATTR_SIZE;
662 status = nfsd_create(rqstp, &cstate->current_fh, 662 status = nfsd_create(rqstp, &cstate->current_fh,
663 create->cr_name, create->cr_namelen, 663 create->cr_name, create->cr_namelen,
664 &create->cr_iattr, S_IFDIR, 0, &resfh); 664 &create->cr_iattr, S_IFDIR, 0, &resfh);
665 break; 665 break;
666 666
667 default: 667 default:
668 status = nfserr_badtype; 668 status = nfserr_badtype;
669 } 669 }
670 670
671 if (status) 671 if (status)
672 goto out; 672 goto out;
673 673
674 if (create->cr_label.len) 674 if (create->cr_label.len)
675 nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval); 675 nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval);
676 676
677 if (create->cr_acl != NULL) 677 if (create->cr_acl != NULL)
678 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, 678 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
679 create->cr_bmval); 679 create->cr_bmval);
680 680
681 fh_unlock(&cstate->current_fh); 681 fh_unlock(&cstate->current_fh);
682 set_change_info(&create->cr_cinfo, &cstate->current_fh); 682 set_change_info(&create->cr_cinfo, &cstate->current_fh);
683 fh_dup2(&cstate->current_fh, &resfh); 683 fh_dup2(&cstate->current_fh, &resfh);
684 out: 684 out:
685 fh_put(&resfh); 685 fh_put(&resfh);
686 return status; 686 return status;
687 } 687 }
688 688
689 static __be32 689 static __be32
690 nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 690 nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
691 struct nfsd4_getattr *getattr) 691 struct nfsd4_getattr *getattr)
692 { 692 {
693 __be32 status; 693 __be32 status;
694 694
695 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); 695 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
696 if (status) 696 if (status)
697 return status; 697 return status;
698 698
699 if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) 699 if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
700 return nfserr_inval; 700 return nfserr_inval;
701 701
702 getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion); 702 getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
703 getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); 703 getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
704 getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); 704 getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
705 705
706 getattr->ga_fhp = &cstate->current_fh; 706 getattr->ga_fhp = &cstate->current_fh;
707 return nfs_ok; 707 return nfs_ok;
708 } 708 }
709 709
710 static __be32 710 static __be32
711 nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 711 nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
712 struct nfsd4_link *link) 712 struct nfsd4_link *link)
713 { 713 {
714 __be32 status = nfserr_nofilehandle; 714 __be32 status = nfserr_nofilehandle;
715 715
716 if (!cstate->save_fh.fh_dentry) 716 if (!cstate->save_fh.fh_dentry)
717 return status; 717 return status;
718 status = nfsd_link(rqstp, &cstate->current_fh, 718 status = nfsd_link(rqstp, &cstate->current_fh,
719 link->li_name, link->li_namelen, &cstate->save_fh); 719 link->li_name, link->li_namelen, &cstate->save_fh);
720 if (!status) 720 if (!status)
721 set_change_info(&link->li_cinfo, &cstate->current_fh); 721 set_change_info(&link->li_cinfo, &cstate->current_fh);
722 return status; 722 return status;
723 } 723 }
724 724
725 static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) 725 static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
726 { 726 {
727 struct svc_fh tmp_fh; 727 struct svc_fh tmp_fh;
728 __be32 ret; 728 __be32 ret;
729 729
730 fh_init(&tmp_fh, NFS4_FHSIZE); 730 fh_init(&tmp_fh, NFS4_FHSIZE);
731 ret = exp_pseudoroot(rqstp, &tmp_fh); 731 ret = exp_pseudoroot(rqstp, &tmp_fh);
732 if (ret) 732 if (ret)
733 return ret; 733 return ret;
734 if (tmp_fh.fh_dentry == fh->fh_dentry) { 734 if (tmp_fh.fh_dentry == fh->fh_dentry) {
735 fh_put(&tmp_fh); 735 fh_put(&tmp_fh);
736 return nfserr_noent; 736 return nfserr_noent;
737 } 737 }
738 fh_put(&tmp_fh); 738 fh_put(&tmp_fh);
739 return nfsd_lookup(rqstp, fh, "..", 2, fh); 739 return nfsd_lookup(rqstp, fh, "..", 2, fh);
740 } 740 }
741 741
742 static __be32 742 static __be32
743 nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 743 nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
744 void *arg) 744 void *arg)
745 { 745 {
746 return nfsd4_do_lookupp(rqstp, &cstate->current_fh); 746 return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
747 } 747 }
748 748
749 static __be32 749 static __be32
750 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 750 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
751 struct nfsd4_lookup *lookup) 751 struct nfsd4_lookup *lookup)
752 { 752 {
753 return nfsd_lookup(rqstp, &cstate->current_fh, 753 return nfsd_lookup(rqstp, &cstate->current_fh,
754 lookup->lo_name, lookup->lo_len, 754 lookup->lo_name, lookup->lo_len,
755 &cstate->current_fh); 755 &cstate->current_fh);
756 } 756 }
757 757
758 static __be32 758 static __be32
759 nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 759 nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
760 struct nfsd4_read *read) 760 struct nfsd4_read *read)
761 { 761 {
762 __be32 status; 762 __be32 status;
763 763
764 /* no need to check permission - this will be done in nfsd_read() */ 764 /* no need to check permission - this will be done in nfsd_read() */
765 765
766 read->rd_filp = NULL; 766 read->rd_filp = NULL;
767 if (read->rd_offset >= OFFSET_MAX) 767 if (read->rd_offset >= OFFSET_MAX)
768 return nfserr_inval; 768 return nfserr_inval;
769 769
770 /* 770 /*
771 * If we do a zero copy read, then a client will see read data 771 * If we do a zero copy read, then a client will see read data
772 * that reflects the state of the file *after* performing the 772 * that reflects the state of the file *after* performing the
773 * following compound. 773 * following compound.
774 * 774 *
775 * To ensure proper ordering, we therefore turn off zero copy if 775 * To ensure proper ordering, we therefore turn off zero copy if
776 * the client wants us to do more in this compound: 776 * the client wants us to do more in this compound:
777 */ 777 */
778 if (!nfsd4_last_compound_op(rqstp)) 778 if (!nfsd4_last_compound_op(rqstp))
779 rqstp->rq_splice_ok = false; 779 rqstp->rq_splice_ok = false;
780 780
781 nfs4_lock_state(); 781 nfs4_lock_state();
782 /* check stateid */ 782 /* check stateid */
783 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), 783 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
784 cstate, &read->rd_stateid, 784 cstate, &read->rd_stateid,
785 RD_STATE, &read->rd_filp))) { 785 RD_STATE, &read->rd_filp))) {
786 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); 786 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
787 goto out; 787 goto out;
788 } 788 }
789 if (read->rd_filp) 789 if (read->rd_filp)
790 get_file(read->rd_filp); 790 get_file(read->rd_filp);
791 status = nfs_ok; 791 status = nfs_ok;
792 out: 792 out:
793 nfs4_unlock_state(); 793 nfs4_unlock_state();
794 read->rd_rqstp = rqstp; 794 read->rd_rqstp = rqstp;
795 read->rd_fhp = &cstate->current_fh; 795 read->rd_fhp = &cstate->current_fh;
796 return status; 796 return status;
797 } 797 }
798 798
799 static __be32 799 static __be32
800 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 800 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
801 struct nfsd4_readdir *readdir) 801 struct nfsd4_readdir *readdir)
802 { 802 {
803 u64 cookie = readdir->rd_cookie; 803 u64 cookie = readdir->rd_cookie;
804 static const nfs4_verifier zeroverf; 804 static const nfs4_verifier zeroverf;
805 805
806 /* no need to check permission - this will be done in nfsd_readdir() */ 806 /* no need to check permission - this will be done in nfsd_readdir() */
807 807
808 if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) 808 if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
809 return nfserr_inval; 809 return nfserr_inval;
810 810
811 readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion); 811 readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
812 readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); 812 readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
813 readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); 813 readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
814 814
815 if ((cookie == 1) || (cookie == 2) || 815 if ((cookie == 1) || (cookie == 2) ||
816 (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) 816 (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
817 return nfserr_bad_cookie; 817 return nfserr_bad_cookie;
818 818
819 readdir->rd_rqstp = rqstp; 819 readdir->rd_rqstp = rqstp;
820 readdir->rd_fhp = &cstate->current_fh; 820 readdir->rd_fhp = &cstate->current_fh;
821 return nfs_ok; 821 return nfs_ok;
822 } 822 }
823 823
824 static __be32 824 static __be32
825 nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 825 nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
826 struct nfsd4_readlink *readlink) 826 struct nfsd4_readlink *readlink)
827 { 827 {
828 readlink->rl_rqstp = rqstp; 828 readlink->rl_rqstp = rqstp;
829 readlink->rl_fhp = &cstate->current_fh; 829 readlink->rl_fhp = &cstate->current_fh;
830 return nfs_ok; 830 return nfs_ok;
831 } 831 }
832 832
833 static __be32 833 static __be32
834 nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 834 nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
835 struct nfsd4_remove *remove) 835 struct nfsd4_remove *remove)
836 { 836 {
837 __be32 status; 837 __be32 status;
838 838
839 if (locks_in_grace(SVC_NET(rqstp))) 839 if (locks_in_grace(SVC_NET(rqstp)))
840 return nfserr_grace; 840 return nfserr_grace;
841 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 841 status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
842 remove->rm_name, remove->rm_namelen); 842 remove->rm_name, remove->rm_namelen);
843 if (!status) { 843 if (!status) {
844 fh_unlock(&cstate->current_fh); 844 fh_unlock(&cstate->current_fh);
845 set_change_info(&remove->rm_cinfo, &cstate->current_fh); 845 set_change_info(&remove->rm_cinfo, &cstate->current_fh);
846 } 846 }
847 return status; 847 return status;
848 } 848 }
849 849
850 static __be32 850 static __be32
851 nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 851 nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
852 struct nfsd4_rename *rename) 852 struct nfsd4_rename *rename)
853 { 853 {
854 __be32 status = nfserr_nofilehandle; 854 __be32 status = nfserr_nofilehandle;
855 855
856 if (!cstate->save_fh.fh_dentry) 856 if (!cstate->save_fh.fh_dentry)
857 return status; 857 return status;
858 if (locks_in_grace(SVC_NET(rqstp)) && 858 if (locks_in_grace(SVC_NET(rqstp)) &&
859 !(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK)) 859 !(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK))
860 return nfserr_grace; 860 return nfserr_grace;
861 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 861 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
862 rename->rn_snamelen, &cstate->current_fh, 862 rename->rn_snamelen, &cstate->current_fh,
863 rename->rn_tname, rename->rn_tnamelen); 863 rename->rn_tname, rename->rn_tnamelen);
864 if (status) 864 if (status)
865 return status; 865 return status;
866 set_change_info(&rename->rn_sinfo, &cstate->current_fh); 866 set_change_info(&rename->rn_sinfo, &cstate->current_fh);
867 set_change_info(&rename->rn_tinfo, &cstate->save_fh); 867 set_change_info(&rename->rn_tinfo, &cstate->save_fh);
868 return nfs_ok; 868 return nfs_ok;
869 } 869 }
870 870
871 static __be32 871 static __be32
872 nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 872 nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
873 struct nfsd4_secinfo *secinfo) 873 struct nfsd4_secinfo *secinfo)
874 { 874 {
875 struct svc_fh resfh; 875 struct svc_fh resfh;
876 struct svc_export *exp; 876 struct svc_export *exp;
877 struct dentry *dentry; 877 struct dentry *dentry;
878 __be32 err; 878 __be32 err;
879 879
880 fh_init(&resfh, NFS4_FHSIZE); 880 fh_init(&resfh, NFS4_FHSIZE);
881 err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC); 881 err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC);
882 if (err) 882 if (err)
883 return err; 883 return err;
884 err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, 884 err = nfsd_lookup_dentry(rqstp, &cstate->current_fh,
885 secinfo->si_name, secinfo->si_namelen, 885 secinfo->si_name, secinfo->si_namelen,
886 &exp, &dentry); 886 &exp, &dentry);
887 if (err) 887 if (err)
888 return err; 888 return err;
889 if (dentry->d_inode == NULL) { 889 if (dentry->d_inode == NULL) {
890 exp_put(exp); 890 exp_put(exp);
891 err = nfserr_noent; 891 err = nfserr_noent;
892 } else 892 } else
893 secinfo->si_exp = exp; 893 secinfo->si_exp = exp;
894 dput(dentry); 894 dput(dentry);
895 if (cstate->minorversion) 895 if (cstate->minorversion)
896 /* See rfc 5661 section 2.6.3.1.1.8 */ 896 /* See rfc 5661 section 2.6.3.1.1.8 */
897 fh_put(&cstate->current_fh); 897 fh_put(&cstate->current_fh);
898 return err; 898 return err;
899 } 899 }
900 900
901 static __be32 901 static __be32
902 nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 902 nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
903 struct nfsd4_secinfo_no_name *sin) 903 struct nfsd4_secinfo_no_name *sin)
904 { 904 {
905 __be32 err; 905 __be32 err;
906 906
907 switch (sin->sin_style) { 907 switch (sin->sin_style) {
908 case NFS4_SECINFO_STYLE4_CURRENT_FH: 908 case NFS4_SECINFO_STYLE4_CURRENT_FH:
909 break; 909 break;
910 case NFS4_SECINFO_STYLE4_PARENT: 910 case NFS4_SECINFO_STYLE4_PARENT:
911 err = nfsd4_do_lookupp(rqstp, &cstate->current_fh); 911 err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
912 if (err) 912 if (err)
913 return err; 913 return err;
914 break; 914 break;
915 default: 915 default:
916 return nfserr_inval; 916 return nfserr_inval;
917 } 917 }
918 exp_get(cstate->current_fh.fh_export); 918 exp_get(cstate->current_fh.fh_export);
919 sin->sin_exp = cstate->current_fh.fh_export; 919 sin->sin_exp = cstate->current_fh.fh_export;
920 fh_put(&cstate->current_fh); 920 fh_put(&cstate->current_fh);
921 return nfs_ok; 921 return nfs_ok;
922 } 922 }
923 923
924 static __be32 924 static __be32
925 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 925 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
926 struct nfsd4_setattr *setattr) 926 struct nfsd4_setattr *setattr)
927 { 927 {
928 __be32 status = nfs_ok; 928 __be32 status = nfs_ok;
929 int err; 929 int err;
930 930
931 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { 931 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
932 nfs4_lock_state(); 932 nfs4_lock_state();
933 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate, 933 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
934 &setattr->sa_stateid, WR_STATE, NULL); 934 &setattr->sa_stateid, WR_STATE, NULL);
935 nfs4_unlock_state(); 935 nfs4_unlock_state();
936 if (status) { 936 if (status) {
937 dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); 937 dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
938 return status; 938 return status;
939 } 939 }
940 } 940 }
941 err = fh_want_write(&cstate->current_fh); 941 err = fh_want_write(&cstate->current_fh);
942 if (err) 942 if (err)
943 return nfserrno(err); 943 return nfserrno(err);
944 status = nfs_ok; 944 status = nfs_ok;
945 945
946 status = check_attr_support(rqstp, cstate, setattr->sa_bmval, 946 status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
947 nfsd_attrmask); 947 nfsd_attrmask);
948 if (status) 948 if (status)
949 goto out; 949 goto out;
950 950
951 if (setattr->sa_acl != NULL) 951 if (setattr->sa_acl != NULL)
952 status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, 952 status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
953 setattr->sa_acl); 953 setattr->sa_acl);
954 if (status) 954 if (status)
955 goto out; 955 goto out;
956 if (setattr->sa_label.len) 956 if (setattr->sa_label.len)
957 status = nfsd4_set_nfs4_label(rqstp, &cstate->current_fh, 957 status = nfsd4_set_nfs4_label(rqstp, &cstate->current_fh,
958 &setattr->sa_label); 958 &setattr->sa_label);
959 if (status) 959 if (status)
960 goto out; 960 goto out;
961 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 961 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
962 0, (time_t)0); 962 0, (time_t)0);
963 out: 963 out:
964 fh_drop_write(&cstate->current_fh); 964 fh_drop_write(&cstate->current_fh);
965 return status; 965 return status;
966 } 966 }
967 967
968 static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write) 968 static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
969 { 969 {
970 int i = 1; 970 int i = 1;
971 int buflen = write->wr_buflen; 971 int buflen = write->wr_buflen;
972 972
973 vec[0].iov_base = write->wr_head.iov_base; 973 vec[0].iov_base = write->wr_head.iov_base;
974 vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len); 974 vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
975 buflen -= vec[0].iov_len; 975 buflen -= vec[0].iov_len;
976 976
977 while (buflen) { 977 while (buflen) {
978 vec[i].iov_base = page_address(write->wr_pagelist[i - 1]); 978 vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
979 vec[i].iov_len = min_t(int, PAGE_SIZE, buflen); 979 vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
980 buflen -= vec[i].iov_len; 980 buflen -= vec[i].iov_len;
981 i++; 981 i++;
982 } 982 }
983 return i; 983 return i;
984 } 984 }
985 985
986 static __be32 986 static __be32
987 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 987 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
988 struct nfsd4_write *write) 988 struct nfsd4_write *write)
989 { 989 {
990 stateid_t *stateid = &write->wr_stateid; 990 stateid_t *stateid = &write->wr_stateid;
991 struct file *filp = NULL; 991 struct file *filp = NULL;
992 __be32 status = nfs_ok; 992 __be32 status = nfs_ok;
993 unsigned long cnt; 993 unsigned long cnt;
994 int nvecs; 994 int nvecs;
995 995
996 /* no need to check permission - this will be done in nfsd_write() */ 996 /* no need to check permission - this will be done in nfsd_write() */
997 997
998 if (write->wr_offset >= OFFSET_MAX) 998 if (write->wr_offset >= OFFSET_MAX)
999 return nfserr_inval; 999 return nfserr_inval;
1000 1000
1001 nfs4_lock_state(); 1001 nfs4_lock_state();
1002 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), 1002 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
1003 cstate, stateid, WR_STATE, &filp); 1003 cstate, stateid, WR_STATE, &filp);
1004 if (status) { 1004 if (status) {
1005 nfs4_unlock_state(); 1005 nfs4_unlock_state();
1006 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); 1006 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
1007 return status; 1007 return status;
1008 } 1008 }
1009 if (filp) 1009 if (filp)
1010 get_file(filp); 1010 get_file(filp);
1011 nfs4_unlock_state(); 1011 nfs4_unlock_state();
1012 1012
1013 cnt = write->wr_buflen; 1013 cnt = write->wr_buflen;
1014 write->wr_how_written = write->wr_stable_how; 1014 write->wr_how_written = write->wr_stable_how;
1015 gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp)); 1015 gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
1016 1016
1017 nvecs = fill_in_write_vector(rqstp->rq_vec, write); 1017 nvecs = fill_in_write_vector(rqstp->rq_vec, write);
1018 WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec)); 1018 WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
1019 1019
1020 status = nfsd_write(rqstp, &cstate->current_fh, filp, 1020 status = nfsd_write(rqstp, &cstate->current_fh, filp,
1021 write->wr_offset, rqstp->rq_vec, nvecs, 1021 write->wr_offset, rqstp->rq_vec, nvecs,
1022 &cnt, &write->wr_how_written); 1022 &cnt, &write->wr_how_written);
1023 if (filp) 1023 if (filp)
1024 fput(filp); 1024 fput(filp);
1025 1025
1026 write->wr_bytes_written = cnt; 1026 write->wr_bytes_written = cnt;
1027 1027
1028 return status; 1028 return status;
1029 } 1029 }
1030 1030
1031 /* This routine never returns NFS_OK! If there are no other errors, it 1031 /* This routine never returns NFS_OK! If there are no other errors, it
1032 * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the 1032 * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
1033 * attributes matched. VERIFY is implemented by mapping NFSERR_SAME 1033 * attributes matched. VERIFY is implemented by mapping NFSERR_SAME
1034 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. 1034 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
1035 */ 1035 */
1036 static __be32 1036 static __be32
1037 _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1037 _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1038 struct nfsd4_verify *verify) 1038 struct nfsd4_verify *verify)
1039 { 1039 {
1040 __be32 *buf, *p; 1040 __be32 *buf, *p;
1041 int count; 1041 int count;
1042 __be32 status; 1042 __be32 status;
1043 1043
1044 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); 1044 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
1045 if (status) 1045 if (status)
1046 return status; 1046 return status;
1047 1047
1048 status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL); 1048 status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL);
1049 if (status) 1049 if (status)
1050 return status; 1050 return status;
1051 1051
1052 if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR) 1052 if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)
1053 || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)) 1053 || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1))
1054 return nfserr_inval; 1054 return nfserr_inval;
1055 if (verify->ve_attrlen & 3) 1055 if (verify->ve_attrlen & 3)
1056 return nfserr_inval; 1056 return nfserr_inval;
1057 1057
1058 /* count in words: 1058 /* count in words:
1059 * bitmap_len(1) + bitmap(2) + attr_len(1) = 4 1059 * bitmap_len(1) + bitmap(2) + attr_len(1) = 4
1060 */ 1060 */
1061 count = 4 + (verify->ve_attrlen >> 2); 1061 count = 4 + (verify->ve_attrlen >> 2);
1062 buf = kmalloc(count << 2, GFP_KERNEL); 1062 buf = kmalloc(count << 2, GFP_KERNEL);
1063 if (!buf) 1063 if (!buf)
1064 return nfserr_jukebox; 1064 return nfserr_jukebox;
1065 1065
1066 p = buf; 1066 p = buf;
1067 status = nfsd4_encode_fattr(&cstate->current_fh, 1067 status = nfsd4_encode_fattr(&cstate->current_fh,
1068 cstate->current_fh.fh_export, 1068 cstate->current_fh.fh_export,
1069 cstate->current_fh.fh_dentry, &p, 1069 cstate->current_fh.fh_dentry, &p,
1070 count, verify->ve_bmval, 1070 count, verify->ve_bmval,
1071 rqstp, 0); 1071 rqstp, 0);
1072 1072
1073 /* this means that nfsd4_encode_fattr() ran out of space */ 1073 /* this means that nfsd4_encode_fattr() ran out of space */
1074 if (status == nfserr_resource) 1074 if (status == nfserr_resource)
1075 status = nfserr_not_same; 1075 status = nfserr_not_same;
1076 if (status) 1076 if (status)
1077 goto out_kfree; 1077 goto out_kfree;
1078 1078
1079 /* skip bitmap */ 1079 /* skip bitmap */
1080 p = buf + 1 + ntohl(buf[0]); 1080 p = buf + 1 + ntohl(buf[0]);
1081 status = nfserr_not_same; 1081 status = nfserr_not_same;
1082 if (ntohl(*p++) != verify->ve_attrlen) 1082 if (ntohl(*p++) != verify->ve_attrlen)
1083 goto out_kfree; 1083 goto out_kfree;
1084 if (!memcmp(p, verify->ve_attrval, verify->ve_attrlen)) 1084 if (!memcmp(p, verify->ve_attrval, verify->ve_attrlen))
1085 status = nfserr_same; 1085 status = nfserr_same;
1086 1086
1087 out_kfree: 1087 out_kfree:
1088 kfree(buf); 1088 kfree(buf);
1089 return status; 1089 return status;
1090 } 1090 }
1091 1091
1092 static __be32 1092 static __be32
1093 nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1093 nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1094 struct nfsd4_verify *verify) 1094 struct nfsd4_verify *verify)
1095 { 1095 {
1096 __be32 status; 1096 __be32 status;
1097 1097
1098 status = _nfsd4_verify(rqstp, cstate, verify); 1098 status = _nfsd4_verify(rqstp, cstate, verify);
1099 return status == nfserr_not_same ? nfs_ok : status; 1099 return status == nfserr_not_same ? nfs_ok : status;
1100 } 1100 }
1101 1101
1102 static __be32 1102 static __be32
1103 nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1103 nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1104 struct nfsd4_verify *verify) 1104 struct nfsd4_verify *verify)
1105 { 1105 {
1106 __be32 status; 1106 __be32 status;
1107 1107
1108 status = _nfsd4_verify(rqstp, cstate, verify); 1108 status = _nfsd4_verify(rqstp, cstate, verify);
1109 return status == nfserr_same ? nfs_ok : status; 1109 return status == nfserr_same ? nfs_ok : status;
1110 } 1110 }
1111 1111
1112 /* 1112 /*
1113 * NULL call. 1113 * NULL call.
1114 */ 1114 */
1115 static __be32 1115 static __be32
1116 nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 1116 nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
1117 { 1117 {
1118 return nfs_ok; 1118 return nfs_ok;
1119 } 1119 }
1120 1120
1121 static inline void nfsd4_increment_op_stats(u32 opnum) 1121 static inline void nfsd4_increment_op_stats(u32 opnum)
1122 { 1122 {
1123 if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) 1123 if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
1124 nfsdstats.nfs4_opcount[opnum]++; 1124 nfsdstats.nfs4_opcount[opnum]++;
1125 } 1125 }
1126 1126
1127 typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1127 typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
1128 void *); 1128 void *);
1129 typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); 1129 typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
1130 typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *); 1130 typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *);
1131 typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *); 1131 typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *);
1132 1132
1133 enum nfsd4_op_flags { 1133 enum nfsd4_op_flags {
1134 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 1134 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
1135 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 1135 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */
1136 ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ 1136 ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */
1137 /* For rfc 5661 section 2.6.3.1.1: */ 1137 /* For rfc 5661 section 2.6.3.1.1: */
1138 OP_HANDLES_WRONGSEC = 1 << 3, 1138 OP_HANDLES_WRONGSEC = 1 << 3,
1139 OP_IS_PUTFH_LIKE = 1 << 4, 1139 OP_IS_PUTFH_LIKE = 1 << 4,
1140 /* 1140 /*
1141 * These are the ops whose result size we estimate before 1141 * These are the ops whose result size we estimate before
1142 * encoding, to avoid performing an op then not being able to 1142 * encoding, to avoid performing an op then not being able to
1143 * respond or cache a response. This includes writes and setattrs 1143 * respond or cache a response. This includes writes and setattrs
1144 * as well as the operations usually called "nonidempotent": 1144 * as well as the operations usually called "nonidempotent":
1145 */ 1145 */
1146 OP_MODIFIES_SOMETHING = 1 << 5, 1146 OP_MODIFIES_SOMETHING = 1 << 5,
1147 /* 1147 /*
1148 * Cache compounds containing these ops in the xid-based drc: 1148 * Cache compounds containing these ops in the xid-based drc:
1149 * We use the DRC for compounds containing non-idempotent 1149 * We use the DRC for compounds containing non-idempotent
1150 * operations, *except* those that are 4.1-specific (since 1150 * operations, *except* those that are 4.1-specific (since
1151 * sessions provide their own EOS), and except for stateful 1151 * sessions provide their own EOS), and except for stateful
1152 * operations other than setclientid and setclientid_confirm 1152 * operations other than setclientid and setclientid_confirm
1153 * (since sequence numbers provide EOS for open, lock, etc in 1153 * (since sequence numbers provide EOS for open, lock, etc in
1154 * the v4.0 case). 1154 * the v4.0 case).
1155 */ 1155 */
1156 OP_CACHEME = 1 << 6, 1156 OP_CACHEME = 1 << 6,
1157 /* 1157 /*
1158 * These are ops which clear current state id. 1158 * These are ops which clear current state id.
1159 */ 1159 */
1160 OP_CLEAR_STATEID = 1 << 7, 1160 OP_CLEAR_STATEID = 1 << 7,
1161 }; 1161 };
1162 1162
1163 struct nfsd4_operation { 1163 struct nfsd4_operation {
1164 nfsd4op_func op_func; 1164 nfsd4op_func op_func;
1165 u32 op_flags; 1165 u32 op_flags;
1166 char *op_name; 1166 char *op_name;
1167 /* Try to get response size before operation */ 1167 /* Try to get response size before operation */
1168 nfsd4op_rsize op_rsize_bop; 1168 nfsd4op_rsize op_rsize_bop;
1169 stateid_getter op_get_currentstateid; 1169 stateid_getter op_get_currentstateid;
1170 stateid_setter op_set_currentstateid; 1170 stateid_setter op_set_currentstateid;
1171 }; 1171 };
1172 1172
1173 static struct nfsd4_operation nfsd4_ops[]; 1173 static struct nfsd4_operation nfsd4_ops[];
1174 1174
1175 #ifdef NFSD_DEBUG 1175 #ifdef NFSD_DEBUG
1176 static const char *nfsd4_op_name(unsigned opnum); 1176 static const char *nfsd4_op_name(unsigned opnum);
1177 #endif 1177 #endif
1178 1178
1179 /* 1179 /*
1180 * Enforce NFSv4.1 COMPOUND ordering rules: 1180 * Enforce NFSv4.1 COMPOUND ordering rules:
1181 * 1181 *
1182 * Also note, enforced elsewhere: 1182 * Also note, enforced elsewhere:
1183 * - SEQUENCE other than as first op results in 1183 * - SEQUENCE other than as first op results in
1184 * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().) 1184 * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
1185 * - BIND_CONN_TO_SESSION must be the only op in its compound. 1185 * - BIND_CONN_TO_SESSION must be the only op in its compound.
1186 * (Enforced in nfsd4_bind_conn_to_session().) 1186 * (Enforced in nfsd4_bind_conn_to_session().)
1187 * - DESTROY_SESSION must be the final operation in a compound, if 1187 * - DESTROY_SESSION must be the final operation in a compound, if
1188 * sessionid's in SEQUENCE and DESTROY_SESSION are the same. 1188 * sessionid's in SEQUENCE and DESTROY_SESSION are the same.
1189 * (Enforced in nfsd4_destroy_session().) 1189 * (Enforced in nfsd4_destroy_session().)
1190 */ 1190 */
1191 static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) 1191 static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
1192 { 1192 {
1193 struct nfsd4_op *op = &args->ops[0]; 1193 struct nfsd4_op *op = &args->ops[0];
1194 1194
1195 /* These ordering requirements don't apply to NFSv4.0: */ 1195 /* These ordering requirements don't apply to NFSv4.0: */
1196 if (args->minorversion == 0) 1196 if (args->minorversion == 0)
1197 return nfs_ok; 1197 return nfs_ok;
1198 /* This is weird, but OK, not our problem: */ 1198 /* This is weird, but OK, not our problem: */
1199 if (args->opcnt == 0) 1199 if (args->opcnt == 0)
1200 return nfs_ok; 1200 return nfs_ok;
1201 if (op->status == nfserr_op_illegal) 1201 if (op->status == nfserr_op_illegal)
1202 return nfs_ok; 1202 return nfs_ok;
1203 if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP)) 1203 if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
1204 return nfserr_op_not_in_session; 1204 return nfserr_op_not_in_session;
1205 if (op->opnum == OP_SEQUENCE) 1205 if (op->opnum == OP_SEQUENCE)
1206 return nfs_ok; 1206 return nfs_ok;
1207 if (args->opcnt != 1) 1207 if (args->opcnt != 1)
1208 return nfserr_not_only_op; 1208 return nfserr_not_only_op;
1209 return nfs_ok; 1209 return nfs_ok;
1210 } 1210 }
1211 1211
1212 static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) 1212 static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
1213 { 1213 {
1214 return &nfsd4_ops[op->opnum]; 1214 return &nfsd4_ops[op->opnum];
1215 } 1215 }
1216 1216
1217 bool nfsd4_cache_this_op(struct nfsd4_op *op) 1217 bool nfsd4_cache_this_op(struct nfsd4_op *op)
1218 { 1218 {
1219 return OPDESC(op)->op_flags & OP_CACHEME; 1219 return OPDESC(op)->op_flags & OP_CACHEME;
1220 } 1220 }
1221 1221
1222 static bool need_wrongsec_check(struct svc_rqst *rqstp) 1222 static bool need_wrongsec_check(struct svc_rqst *rqstp)
1223 { 1223 {
1224 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1224 struct nfsd4_compoundres *resp = rqstp->rq_resp;
1225 struct nfsd4_compoundargs *argp = rqstp->rq_argp; 1225 struct nfsd4_compoundargs *argp = rqstp->rq_argp;
1226 struct nfsd4_op *this = &argp->ops[resp->opcnt - 1]; 1226 struct nfsd4_op *this = &argp->ops[resp->opcnt - 1];
1227 struct nfsd4_op *next = &argp->ops[resp->opcnt]; 1227 struct nfsd4_op *next = &argp->ops[resp->opcnt];
1228 struct nfsd4_operation *thisd; 1228 struct nfsd4_operation *thisd;
1229 struct nfsd4_operation *nextd; 1229 struct nfsd4_operation *nextd;
1230 1230
1231 thisd = OPDESC(this); 1231 thisd = OPDESC(this);
1232 /* 1232 /*
1233 * Most ops check wronsec on our own; only the putfh-like ops 1233 * Most ops check wronsec on our own; only the putfh-like ops
1234 * have special rules. 1234 * have special rules.
1235 */ 1235 */
1236 if (!(thisd->op_flags & OP_IS_PUTFH_LIKE)) 1236 if (!(thisd->op_flags & OP_IS_PUTFH_LIKE))
1237 return false; 1237 return false;
1238 /* 1238 /*
1239 * rfc 5661 2.6.3.1.1.6: don't bother erroring out a 1239 * rfc 5661 2.6.3.1.1.6: don't bother erroring out a
1240 * put-filehandle operation if we're not going to use the 1240 * put-filehandle operation if we're not going to use the
1241 * result: 1241 * result:
1242 */ 1242 */
1243 if (argp->opcnt == resp->opcnt) 1243 if (argp->opcnt == resp->opcnt)
1244 return false; 1244 return false;
1245 1245
1246 nextd = OPDESC(next); 1246 nextd = OPDESC(next);
1247 /* 1247 /*
1248 * Rest of 2.6.3.1.1: certain operations will return WRONGSEC 1248 * Rest of 2.6.3.1.1: certain operations will return WRONGSEC
1249 * errors themselves as necessary; others should check for them 1249 * errors themselves as necessary; others should check for them
1250 * now: 1250 * now:
1251 */ 1251 */
1252 return !(nextd->op_flags & OP_HANDLES_WRONGSEC); 1252 return !(nextd->op_flags & OP_HANDLES_WRONGSEC);
1253 } 1253 }
1254 1254
1255 /* 1255 /*
1256 * COMPOUND call. 1256 * COMPOUND call.
1257 */ 1257 */
1258 static __be32 1258 static __be32
1259 nfsd4_proc_compound(struct svc_rqst *rqstp, 1259 nfsd4_proc_compound(struct svc_rqst *rqstp,
1260 struct nfsd4_compoundargs *args, 1260 struct nfsd4_compoundargs *args,
1261 struct nfsd4_compoundres *resp) 1261 struct nfsd4_compoundres *resp)
1262 { 1262 {
1263 struct nfsd4_op *op; 1263 struct nfsd4_op *op;
1264 struct nfsd4_operation *opdesc; 1264 struct nfsd4_operation *opdesc;
1265 struct nfsd4_compound_state *cstate = &resp->cstate; 1265 struct nfsd4_compound_state *cstate = &resp->cstate;
1266 int slack_bytes; 1266 int slack_bytes;
1267 u32 plen = 0; 1267 u32 plen = 0;
1268 __be32 status; 1268 __be32 status;
1269 1269
1270 resp->xbuf = &rqstp->rq_res; 1270 resp->xbuf = &rqstp->rq_res;
1271 resp->p = rqstp->rq_res.head[0].iov_base + 1271 resp->p = rqstp->rq_res.head[0].iov_base +
1272 rqstp->rq_res.head[0].iov_len; 1272 rqstp->rq_res.head[0].iov_len;
1273 resp->tagp = resp->p; 1273 resp->tagp = resp->p;
1274 /* reserve space for: taglen, tag, and opcnt */ 1274 /* reserve space for: taglen, tag, and opcnt */
1275 resp->p += 2 + XDR_QUADLEN(args->taglen); 1275 resp->p += 2 + XDR_QUADLEN(args->taglen);
1276 resp->end = rqstp->rq_res.head[0].iov_base + PAGE_SIZE; 1276 resp->end = rqstp->rq_res.head[0].iov_base + PAGE_SIZE;
1277 resp->taglen = args->taglen; 1277 resp->taglen = args->taglen;
1278 resp->tag = args->tag; 1278 resp->tag = args->tag;
1279 resp->opcnt = 0; 1279 resp->opcnt = 0;
1280 resp->rqstp = rqstp; 1280 resp->rqstp = rqstp;
1281 resp->cstate.minorversion = args->minorversion; 1281 resp->cstate.minorversion = args->minorversion;
1282 resp->cstate.replay_owner = NULL; 1282 resp->cstate.replay_owner = NULL;
1283 resp->cstate.session = NULL; 1283 resp->cstate.session = NULL;
1284 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); 1284 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
1285 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); 1285 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
1286 /* 1286 /*
1287 * Don't use the deferral mechanism for NFSv4; compounds make it 1287 * Don't use the deferral mechanism for NFSv4; compounds make it
1288 * too hard to avoid non-idempotency problems. 1288 * too hard to avoid non-idempotency problems.
1289 */ 1289 */
1290 rqstp->rq_usedeferral = 0; 1290 rqstp->rq_usedeferral = 0;
1291 1291
1292 /* 1292 /*
1293 * According to RFC3010, this takes precedence over all other errors. 1293 * According to RFC3010, this takes precedence over all other errors.
1294 */ 1294 */
1295 status = nfserr_minor_vers_mismatch; 1295 status = nfserr_minor_vers_mismatch;
1296 if (args->minorversion > nfsd_supported_minorversion) 1296 if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
1297 goto out; 1297 goto out;
1298 1298
1299 status = nfs41_check_op_ordering(args); 1299 status = nfs41_check_op_ordering(args);
1300 if (status) { 1300 if (status) {
1301 op = &args->ops[0]; 1301 op = &args->ops[0];
1302 op->status = status; 1302 op->status = status;
1303 goto encode_op; 1303 goto encode_op;
1304 } 1304 }
1305 1305
1306 while (!status && resp->opcnt < args->opcnt) { 1306 while (!status && resp->opcnt < args->opcnt) {
1307 op = &args->ops[resp->opcnt++]; 1307 op = &args->ops[resp->opcnt++];
1308 1308
1309 dprintk("nfsv4 compound op #%d/%d: %d (%s)\n", 1309 dprintk("nfsv4 compound op #%d/%d: %d (%s)\n",
1310 resp->opcnt, args->opcnt, op->opnum, 1310 resp->opcnt, args->opcnt, op->opnum,
1311 nfsd4_op_name(op->opnum)); 1311 nfsd4_op_name(op->opnum));
1312 /* 1312 /*
1313 * The XDR decode routines may have pre-set op->status; 1313 * The XDR decode routines may have pre-set op->status;
1314 * for example, if there is a miscellaneous XDR error 1314 * for example, if there is a miscellaneous XDR error
1315 * it will be set to nfserr_bad_xdr. 1315 * it will be set to nfserr_bad_xdr.
1316 */ 1316 */
1317 if (op->status) { 1317 if (op->status) {
1318 if (op->opnum == OP_OPEN) 1318 if (op->opnum == OP_OPEN)
1319 op->status = nfsd4_open_omfg(rqstp, cstate, op); 1319 op->status = nfsd4_open_omfg(rqstp, cstate, op);
1320 goto encode_op; 1320 goto encode_op;
1321 } 1321 }
1322 1322
1323 /* We must be able to encode a successful response to 1323 /* We must be able to encode a successful response to
1324 * this operation, with enough room left over to encode a 1324 * this operation, with enough room left over to encode a
1325 * failed response to the next operation. If we don't 1325 * failed response to the next operation. If we don't
1326 * have enough room, fail with ERR_RESOURCE. 1326 * have enough room, fail with ERR_RESOURCE.
1327 */ 1327 */
1328 slack_bytes = (char *)resp->end - (char *)resp->p; 1328 slack_bytes = (char *)resp->end - (char *)resp->p;
1329 if (slack_bytes < COMPOUND_SLACK_SPACE 1329 if (slack_bytes < COMPOUND_SLACK_SPACE
1330 + COMPOUND_ERR_SLACK_SPACE) { 1330 + COMPOUND_ERR_SLACK_SPACE) {
1331 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); 1331 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE);
1332 op->status = nfserr_resource; 1332 op->status = nfserr_resource;
1333 goto encode_op; 1333 goto encode_op;
1334 } 1334 }
1335 1335
1336 opdesc = OPDESC(op); 1336 opdesc = OPDESC(op);
1337 1337
1338 if (!cstate->current_fh.fh_dentry) { 1338 if (!cstate->current_fh.fh_dentry) {
1339 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1339 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
1340 op->status = nfserr_nofilehandle; 1340 op->status = nfserr_nofilehandle;
1341 goto encode_op; 1341 goto encode_op;
1342 } 1342 }
1343 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && 1343 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated &&
1344 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1344 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
1345 op->status = nfserr_moved; 1345 op->status = nfserr_moved;
1346 goto encode_op; 1346 goto encode_op;
1347 } 1347 }
1348 1348
1349 /* If op is non-idempotent */ 1349 /* If op is non-idempotent */
1350 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { 1350 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
1351 plen = opdesc->op_rsize_bop(rqstp, op); 1351 plen = opdesc->op_rsize_bop(rqstp, op);
1352 op->status = nfsd4_check_resp_size(resp, plen); 1352 op->status = nfsd4_check_resp_size(resp, plen);
1353 } 1353 }
1354 1354
1355 if (op->status) 1355 if (op->status)
1356 goto encode_op; 1356 goto encode_op;
1357 1357
1358 if (opdesc->op_get_currentstateid) 1358 if (opdesc->op_get_currentstateid)
1359 opdesc->op_get_currentstateid(cstate, &op->u); 1359 opdesc->op_get_currentstateid(cstate, &op->u);
1360 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1360 op->status = opdesc->op_func(rqstp, cstate, &op->u);
1361 1361
1362 if (!op->status) { 1362 if (!op->status) {
1363 if (opdesc->op_set_currentstateid) 1363 if (opdesc->op_set_currentstateid)
1364 opdesc->op_set_currentstateid(cstate, &op->u); 1364 opdesc->op_set_currentstateid(cstate, &op->u);
1365 1365
1366 if (opdesc->op_flags & OP_CLEAR_STATEID) 1366 if (opdesc->op_flags & OP_CLEAR_STATEID)
1367 clear_current_stateid(cstate); 1367 clear_current_stateid(cstate);
1368 1368
1369 if (need_wrongsec_check(rqstp)) 1369 if (need_wrongsec_check(rqstp))
1370 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); 1370 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp);
1371 } 1371 }
1372 1372
1373 encode_op: 1373 encode_op:
1374 /* Only from SEQUENCE */ 1374 /* Only from SEQUENCE */
1375 if (resp->cstate.status == nfserr_replay_cache) { 1375 if (resp->cstate.status == nfserr_replay_cache) {
1376 dprintk("%s NFS4.1 replay from cache\n", __func__); 1376 dprintk("%s NFS4.1 replay from cache\n", __func__);
1377 status = op->status; 1377 status = op->status;
1378 goto out; 1378 goto out;
1379 } 1379 }
1380 if (op->status == nfserr_replay_me) { 1380 if (op->status == nfserr_replay_me) {
1381 op->replay = &cstate->replay_owner->so_replay; 1381 op->replay = &cstate->replay_owner->so_replay;
1382 nfsd4_encode_replay(resp, op); 1382 nfsd4_encode_replay(resp, op);
1383 status = op->status = op->replay->rp_status; 1383 status = op->status = op->replay->rp_status;
1384 } else { 1384 } else {
1385 nfsd4_encode_operation(resp, op); 1385 nfsd4_encode_operation(resp, op);
1386 status = op->status; 1386 status = op->status;
1387 } 1387 }
1388 1388
1389 dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n", 1389 dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n",
1390 args->ops, args->opcnt, resp->opcnt, op->opnum, 1390 args->ops, args->opcnt, resp->opcnt, op->opnum,
1391 be32_to_cpu(status)); 1391 be32_to_cpu(status));
1392 1392
1393 if (cstate->replay_owner) { 1393 if (cstate->replay_owner) {
1394 nfs4_unlock_state(); 1394 nfs4_unlock_state();
1395 cstate->replay_owner = NULL; 1395 cstate->replay_owner = NULL;
1396 } 1396 }
1397 /* XXX Ugh, we need to get rid of this kind of special case: */ 1397 /* XXX Ugh, we need to get rid of this kind of special case: */
1398 if (op->opnum == OP_READ && op->u.read.rd_filp) 1398 if (op->opnum == OP_READ && op->u.read.rd_filp)
1399 fput(op->u.read.rd_filp); 1399 fput(op->u.read.rd_filp);
1400 1400
1401 nfsd4_increment_op_stats(op->opnum); 1401 nfsd4_increment_op_stats(op->opnum);
1402 } 1402 }
1403 1403
1404 resp->cstate.status = status; 1404 resp->cstate.status = status;
1405 fh_put(&resp->cstate.current_fh); 1405 fh_put(&resp->cstate.current_fh);
1406 fh_put(&resp->cstate.save_fh); 1406 fh_put(&resp->cstate.save_fh);
1407 BUG_ON(resp->cstate.replay_owner); 1407 BUG_ON(resp->cstate.replay_owner);
1408 out: 1408 out:
1409 /* Reset deferral mechanism for RPC deferrals */ 1409 /* Reset deferral mechanism for RPC deferrals */
1410 rqstp->rq_usedeferral = 1; 1410 rqstp->rq_usedeferral = 1;
1411 dprintk("nfsv4 compound returned %d\n", ntohl(status)); 1411 dprintk("nfsv4 compound returned %d\n", ntohl(status));
1412 return status; 1412 return status;
1413 } 1413 }
1414 1414
1415 #define op_encode_hdr_size (2) 1415 #define op_encode_hdr_size (2)
1416 #define op_encode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE)) 1416 #define op_encode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE))
1417 #define op_encode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 1417 #define op_encode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE))
1418 #define op_encode_change_info_maxsz (5) 1418 #define op_encode_change_info_maxsz (5)
1419 #define nfs4_fattr_bitmap_maxsz (4) 1419 #define nfs4_fattr_bitmap_maxsz (4)
1420 1420
1421 #define op_encode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 1421 #define op_encode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
1422 #define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz) 1422 #define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz)
1423 1423
1424 #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 1424 #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
1425 1425
1426 #define op_encode_ace_maxsz (3 + nfs4_owner_maxsz) 1426 #define op_encode_ace_maxsz (3 + nfs4_owner_maxsz)
1427 #define op_encode_delegation_maxsz (1 + op_encode_stateid_maxsz + 1 + \ 1427 #define op_encode_delegation_maxsz (1 + op_encode_stateid_maxsz + 1 + \
1428 op_encode_ace_maxsz) 1428 op_encode_ace_maxsz)
1429 1429
1430 #define op_encode_channel_attrs_maxsz (6 + 1 + 1) 1430 #define op_encode_channel_attrs_maxsz (6 + 1 + 1)
1431 1431
1432 static inline u32 nfsd4_only_status_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1432 static inline u32 nfsd4_only_status_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1433 { 1433 {
1434 return (op_encode_hdr_size) * sizeof(__be32); 1434 return (op_encode_hdr_size) * sizeof(__be32);
1435 } 1435 }
1436 1436
1437 static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1437 static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1438 { 1438 {
1439 return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32); 1439 return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32);
1440 } 1440 }
1441 1441
1442 static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1442 static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1443 { 1443 {
1444 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32); 1444 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
1445 } 1445 }
1446 1446
1447 static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1447 static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1448 { 1448 {
1449 return (op_encode_hdr_size + op_encode_change_info_maxsz 1449 return (op_encode_hdr_size + op_encode_change_info_maxsz
1450 + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); 1450 + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1451 } 1451 }
1452 1452
1453 static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1453 static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1454 { 1454 {
1455 return (op_encode_hdr_size + op_encode_change_info_maxsz) 1455 return (op_encode_hdr_size + op_encode_change_info_maxsz)
1456 * sizeof(__be32); 1456 * sizeof(__be32);
1457 } 1457 }
1458 1458
1459 static inline u32 nfsd4_lock_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1459 static inline u32 nfsd4_lock_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1460 { 1460 {
1461 return (op_encode_hdr_size + op_encode_lock_denied_maxsz) 1461 return (op_encode_hdr_size + op_encode_lock_denied_maxsz)
1462 * sizeof(__be32); 1462 * sizeof(__be32);
1463 } 1463 }
1464 1464
1465 static inline u32 nfsd4_open_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1465 static inline u32 nfsd4_open_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1466 { 1466 {
1467 return (op_encode_hdr_size + op_encode_stateid_maxsz 1467 return (op_encode_hdr_size + op_encode_stateid_maxsz
1468 + op_encode_change_info_maxsz + 1 1468 + op_encode_change_info_maxsz + 1
1469 + nfs4_fattr_bitmap_maxsz 1469 + nfs4_fattr_bitmap_maxsz
1470 + op_encode_delegation_maxsz) * sizeof(__be32); 1470 + op_encode_delegation_maxsz) * sizeof(__be32);
1471 } 1471 }
1472 1472
1473 static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1473 static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1474 { 1474 {
1475 u32 maxcount = 0, rlen = 0; 1475 u32 maxcount = 0, rlen = 0;
1476 1476
1477 maxcount = svc_max_payload(rqstp); 1477 maxcount = svc_max_payload(rqstp);
1478 rlen = op->u.read.rd_length; 1478 rlen = op->u.read.rd_length;
1479 1479
1480 if (rlen > maxcount) 1480 if (rlen > maxcount)
1481 rlen = maxcount; 1481 rlen = maxcount;
1482 1482
1483 return (op_encode_hdr_size + 2) * sizeof(__be32) + rlen; 1483 return (op_encode_hdr_size + 2) * sizeof(__be32) + rlen;
1484 } 1484 }
1485 1485
1486 static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1486 static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1487 { 1487 {
1488 u32 rlen = op->u.readdir.rd_maxcount; 1488 u32 rlen = op->u.readdir.rd_maxcount;
1489 1489
1490 if (rlen > PAGE_SIZE) 1490 if (rlen > PAGE_SIZE)
1491 rlen = PAGE_SIZE; 1491 rlen = PAGE_SIZE;
1492 1492
1493 return (op_encode_hdr_size + op_encode_verifier_maxsz) 1493 return (op_encode_hdr_size + op_encode_verifier_maxsz)
1494 * sizeof(__be32) + rlen; 1494 * sizeof(__be32) + rlen;
1495 } 1495 }
1496 1496
1497 static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1497 static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1498 { 1498 {
1499 return (op_encode_hdr_size + op_encode_change_info_maxsz) 1499 return (op_encode_hdr_size + op_encode_change_info_maxsz)
1500 * sizeof(__be32); 1500 * sizeof(__be32);
1501 } 1501 }
1502 1502
1503 static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1503 static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1504 { 1504 {
1505 return (op_encode_hdr_size + op_encode_change_info_maxsz 1505 return (op_encode_hdr_size + op_encode_change_info_maxsz
1506 + op_encode_change_info_maxsz) * sizeof(__be32); 1506 + op_encode_change_info_maxsz) * sizeof(__be32);
1507 } 1507 }
1508 1508
1509 static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1509 static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1510 { 1510 {
1511 return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); 1511 return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1512 } 1512 }
1513 1513
1514 static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1514 static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1515 { 1515 {
1516 return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32); 1516 return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32);
1517 } 1517 }
1518 1518
1519 static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1519 static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1520 { 1520 {
1521 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32); 1521 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
1522 } 1522 }
1523 1523
1524 static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1524 static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1525 { 1525 {
1526 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ 1526 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
1527 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\ 1527 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\
1528 2 + /*eir_server_owner.so_minor_id */\ 1528 2 + /*eir_server_owner.so_minor_id */\
1529 /* eir_server_owner.so_major_id<> */\ 1529 /* eir_server_owner.so_major_id<> */\
1530 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1530 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
1531 /* eir_server_scope<> */\ 1531 /* eir_server_scope<> */\
1532 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1532 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
1533 1 + /* eir_server_impl_id array length */\ 1533 1 + /* eir_server_impl_id array length */\
1534 0 /* ignored eir_server_impl_id contents */) * sizeof(__be32); 1534 0 /* ignored eir_server_impl_id contents */) * sizeof(__be32);
1535 } 1535 }
1536 1536
1537 static inline u32 nfsd4_bind_conn_to_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1537 static inline u32 nfsd4_bind_conn_to_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1538 { 1538 {
1539 return (op_encode_hdr_size + \ 1539 return (op_encode_hdr_size + \
1540 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* bctsr_sessid */\ 1540 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* bctsr_sessid */\
1541 2 /* bctsr_dir, use_conn_in_rdma_mode */) * sizeof(__be32); 1541 2 /* bctsr_dir, use_conn_in_rdma_mode */) * sizeof(__be32);
1542 } 1542 }
1543 1543
1544 static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1544 static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1545 { 1545 {
1546 return (op_encode_hdr_size + \ 1546 return (op_encode_hdr_size + \
1547 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* sessionid */\ 1547 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* sessionid */\
1548 2 + /* csr_sequence, csr_flags */\ 1548 2 + /* csr_sequence, csr_flags */\
1549 op_encode_channel_attrs_maxsz + \ 1549 op_encode_channel_attrs_maxsz + \
1550 op_encode_channel_attrs_maxsz) * sizeof(__be32); 1550 op_encode_channel_attrs_maxsz) * sizeof(__be32);
1551 } 1551 }
1552 1552
1553 static struct nfsd4_operation nfsd4_ops[] = { 1553 static struct nfsd4_operation nfsd4_ops[] = {
1554 [OP_ACCESS] = { 1554 [OP_ACCESS] = {
1555 .op_func = (nfsd4op_func)nfsd4_access, 1555 .op_func = (nfsd4op_func)nfsd4_access,
1556 .op_name = "OP_ACCESS", 1556 .op_name = "OP_ACCESS",
1557 }, 1557 },
1558 [OP_CLOSE] = { 1558 [OP_CLOSE] = {
1559 .op_func = (nfsd4op_func)nfsd4_close, 1559 .op_func = (nfsd4op_func)nfsd4_close,
1560 .op_flags = OP_MODIFIES_SOMETHING, 1560 .op_flags = OP_MODIFIES_SOMETHING,
1561 .op_name = "OP_CLOSE", 1561 .op_name = "OP_CLOSE",
1562 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1562 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1563 .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid, 1563 .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid,
1564 .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid, 1564 .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid,
1565 }, 1565 },
1566 [OP_COMMIT] = { 1566 [OP_COMMIT] = {
1567 .op_func = (nfsd4op_func)nfsd4_commit, 1567 .op_func = (nfsd4op_func)nfsd4_commit,
1568 .op_flags = OP_MODIFIES_SOMETHING, 1568 .op_flags = OP_MODIFIES_SOMETHING,
1569 .op_name = "OP_COMMIT", 1569 .op_name = "OP_COMMIT",
1570 .op_rsize_bop = (nfsd4op_rsize)nfsd4_commit_rsize, 1570 .op_rsize_bop = (nfsd4op_rsize)nfsd4_commit_rsize,
1571 }, 1571 },
1572 [OP_CREATE] = { 1572 [OP_CREATE] = {
1573 .op_func = (nfsd4op_func)nfsd4_create, 1573 .op_func = (nfsd4op_func)nfsd4_create,
1574 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID, 1574 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID,
1575 .op_name = "OP_CREATE", 1575 .op_name = "OP_CREATE",
1576 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize, 1576 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize,
1577 }, 1577 },
1578 [OP_DELEGRETURN] = { 1578 [OP_DELEGRETURN] = {
1579 .op_func = (nfsd4op_func)nfsd4_delegreturn, 1579 .op_func = (nfsd4op_func)nfsd4_delegreturn,
1580 .op_flags = OP_MODIFIES_SOMETHING, 1580 .op_flags = OP_MODIFIES_SOMETHING,
1581 .op_name = "OP_DELEGRETURN", 1581 .op_name = "OP_DELEGRETURN",
1582 .op_rsize_bop = nfsd4_only_status_rsize, 1582 .op_rsize_bop = nfsd4_only_status_rsize,
1583 .op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid, 1583 .op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid,
1584 }, 1584 },
1585 [OP_GETATTR] = { 1585 [OP_GETATTR] = {
1586 .op_func = (nfsd4op_func)nfsd4_getattr, 1586 .op_func = (nfsd4op_func)nfsd4_getattr,
1587 .op_flags = ALLOWED_ON_ABSENT_FS, 1587 .op_flags = ALLOWED_ON_ABSENT_FS,
1588 .op_name = "OP_GETATTR", 1588 .op_name = "OP_GETATTR",
1589 }, 1589 },
1590 [OP_GETFH] = { 1590 [OP_GETFH] = {
1591 .op_func = (nfsd4op_func)nfsd4_getfh, 1591 .op_func = (nfsd4op_func)nfsd4_getfh,
1592 .op_name = "OP_GETFH", 1592 .op_name = "OP_GETFH",
1593 }, 1593 },
1594 [OP_LINK] = { 1594 [OP_LINK] = {
1595 .op_func = (nfsd4op_func)nfsd4_link, 1595 .op_func = (nfsd4op_func)nfsd4_link,
1596 .op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING 1596 .op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING
1597 | OP_CACHEME, 1597 | OP_CACHEME,
1598 .op_name = "OP_LINK", 1598 .op_name = "OP_LINK",
1599 .op_rsize_bop = (nfsd4op_rsize)nfsd4_link_rsize, 1599 .op_rsize_bop = (nfsd4op_rsize)nfsd4_link_rsize,
1600 }, 1600 },
1601 [OP_LOCK] = { 1601 [OP_LOCK] = {
1602 .op_func = (nfsd4op_func)nfsd4_lock, 1602 .op_func = (nfsd4op_func)nfsd4_lock,
1603 .op_flags = OP_MODIFIES_SOMETHING, 1603 .op_flags = OP_MODIFIES_SOMETHING,
1604 .op_name = "OP_LOCK", 1604 .op_name = "OP_LOCK",
1605 .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, 1605 .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
1606 .op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid, 1606 .op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid,
1607 }, 1607 },
1608 [OP_LOCKT] = { 1608 [OP_LOCKT] = {
1609 .op_func = (nfsd4op_func)nfsd4_lockt, 1609 .op_func = (nfsd4op_func)nfsd4_lockt,
1610 .op_name = "OP_LOCKT", 1610 .op_name = "OP_LOCKT",
1611 }, 1611 },
1612 [OP_LOCKU] = { 1612 [OP_LOCKU] = {
1613 .op_func = (nfsd4op_func)nfsd4_locku, 1613 .op_func = (nfsd4op_func)nfsd4_locku,
1614 .op_flags = OP_MODIFIES_SOMETHING, 1614 .op_flags = OP_MODIFIES_SOMETHING,
1615 .op_name = "OP_LOCKU", 1615 .op_name = "OP_LOCKU",
1616 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1616 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1617 .op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid, 1617 .op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid,
1618 }, 1618 },
1619 [OP_LOOKUP] = { 1619 [OP_LOOKUP] = {
1620 .op_func = (nfsd4op_func)nfsd4_lookup, 1620 .op_func = (nfsd4op_func)nfsd4_lookup,
1621 .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, 1621 .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
1622 .op_name = "OP_LOOKUP", 1622 .op_name = "OP_LOOKUP",
1623 }, 1623 },
1624 [OP_LOOKUPP] = { 1624 [OP_LOOKUPP] = {
1625 .op_func = (nfsd4op_func)nfsd4_lookupp, 1625 .op_func = (nfsd4op_func)nfsd4_lookupp,
1626 .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, 1626 .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
1627 .op_name = "OP_LOOKUPP", 1627 .op_name = "OP_LOOKUPP",
1628 }, 1628 },
1629 [OP_NVERIFY] = { 1629 [OP_NVERIFY] = {
1630 .op_func = (nfsd4op_func)nfsd4_nverify, 1630 .op_func = (nfsd4op_func)nfsd4_nverify,
1631 .op_name = "OP_NVERIFY", 1631 .op_name = "OP_NVERIFY",
1632 }, 1632 },
1633 [OP_OPEN] = { 1633 [OP_OPEN] = {
1634 .op_func = (nfsd4op_func)nfsd4_open, 1634 .op_func = (nfsd4op_func)nfsd4_open,
1635 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, 1635 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
1636 .op_name = "OP_OPEN", 1636 .op_name = "OP_OPEN",
1637 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, 1637 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize,
1638 .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid, 1638 .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid,
1639 }, 1639 },
1640 [OP_OPEN_CONFIRM] = { 1640 [OP_OPEN_CONFIRM] = {
1641 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1641 .op_func = (nfsd4op_func)nfsd4_open_confirm,
1642 .op_flags = OP_MODIFIES_SOMETHING, 1642 .op_flags = OP_MODIFIES_SOMETHING,
1643 .op_name = "OP_OPEN_CONFIRM", 1643 .op_name = "OP_OPEN_CONFIRM",
1644 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1644 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1645 }, 1645 },
1646 [OP_OPEN_DOWNGRADE] = { 1646 [OP_OPEN_DOWNGRADE] = {
1647 .op_func = (nfsd4op_func)nfsd4_open_downgrade, 1647 .op_func = (nfsd4op_func)nfsd4_open_downgrade,
1648 .op_flags = OP_MODIFIES_SOMETHING, 1648 .op_flags = OP_MODIFIES_SOMETHING,
1649 .op_name = "OP_OPEN_DOWNGRADE", 1649 .op_name = "OP_OPEN_DOWNGRADE",
1650 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1650 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1651 .op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid, 1651 .op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid,
1652 .op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid, 1652 .op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid,
1653 }, 1653 },
1654 [OP_PUTFH] = { 1654 [OP_PUTFH] = {
1655 .op_func = (nfsd4op_func)nfsd4_putfh, 1655 .op_func = (nfsd4op_func)nfsd4_putfh,
1656 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1656 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1657 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING 1657 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
1658 | OP_CLEAR_STATEID, 1658 | OP_CLEAR_STATEID,
1659 .op_name = "OP_PUTFH", 1659 .op_name = "OP_PUTFH",
1660 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1660 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1661 }, 1661 },
1662 [OP_PUTPUBFH] = { 1662 [OP_PUTPUBFH] = {
1663 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1663 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1664 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1664 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1665 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING 1665 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
1666 | OP_CLEAR_STATEID, 1666 | OP_CLEAR_STATEID,
1667 .op_name = "OP_PUTPUBFH", 1667 .op_name = "OP_PUTPUBFH",
1668 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1668 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1669 }, 1669 },
1670 [OP_PUTROOTFH] = { 1670 [OP_PUTROOTFH] = {
1671 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1671 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1672 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1672 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1673 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING 1673 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
1674 | OP_CLEAR_STATEID, 1674 | OP_CLEAR_STATEID,
1675 .op_name = "OP_PUTROOTFH", 1675 .op_name = "OP_PUTROOTFH",
1676 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1676 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1677 }, 1677 },
1678 [OP_READ] = { 1678 [OP_READ] = {
1679 .op_func = (nfsd4op_func)nfsd4_read, 1679 .op_func = (nfsd4op_func)nfsd4_read,
1680 .op_flags = OP_MODIFIES_SOMETHING, 1680 .op_flags = OP_MODIFIES_SOMETHING,
1681 .op_name = "OP_READ", 1681 .op_name = "OP_READ",
1682 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, 1682 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize,
1683 .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid, 1683 .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid,
1684 }, 1684 },
1685 [OP_READDIR] = { 1685 [OP_READDIR] = {
1686 .op_func = (nfsd4op_func)nfsd4_readdir, 1686 .op_func = (nfsd4op_func)nfsd4_readdir,
1687 .op_flags = OP_MODIFIES_SOMETHING, 1687 .op_flags = OP_MODIFIES_SOMETHING,
1688 .op_name = "OP_READDIR", 1688 .op_name = "OP_READDIR",
1689 .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize, 1689 .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize,
1690 }, 1690 },
1691 [OP_READLINK] = { 1691 [OP_READLINK] = {
1692 .op_func = (nfsd4op_func)nfsd4_readlink, 1692 .op_func = (nfsd4op_func)nfsd4_readlink,
1693 .op_name = "OP_READLINK", 1693 .op_name = "OP_READLINK",
1694 }, 1694 },
1695 [OP_REMOVE] = { 1695 [OP_REMOVE] = {
1696 .op_func = (nfsd4op_func)nfsd4_remove, 1696 .op_func = (nfsd4op_func)nfsd4_remove,
1697 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1697 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1698 .op_name = "OP_REMOVE", 1698 .op_name = "OP_REMOVE",
1699 .op_rsize_bop = (nfsd4op_rsize)nfsd4_remove_rsize, 1699 .op_rsize_bop = (nfsd4op_rsize)nfsd4_remove_rsize,
1700 }, 1700 },
1701 [OP_RENAME] = { 1701 [OP_RENAME] = {
1702 .op_func = (nfsd4op_func)nfsd4_rename, 1702 .op_func = (nfsd4op_func)nfsd4_rename,
1703 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1703 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1704 .op_name = "OP_RENAME", 1704 .op_name = "OP_RENAME",
1705 .op_rsize_bop = (nfsd4op_rsize)nfsd4_rename_rsize, 1705 .op_rsize_bop = (nfsd4op_rsize)nfsd4_rename_rsize,
1706 }, 1706 },
1707 [OP_RENEW] = { 1707 [OP_RENEW] = {
1708 .op_func = (nfsd4op_func)nfsd4_renew, 1708 .op_func = (nfsd4op_func)nfsd4_renew,
1709 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1709 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1710 | OP_MODIFIES_SOMETHING, 1710 | OP_MODIFIES_SOMETHING,
1711 .op_name = "OP_RENEW", 1711 .op_name = "OP_RENEW",
1712 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1712 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1713 1713
1714 }, 1714 },
1715 [OP_RESTOREFH] = { 1715 [OP_RESTOREFH] = {
1716 .op_func = (nfsd4op_func)nfsd4_restorefh, 1716 .op_func = (nfsd4op_func)nfsd4_restorefh,
1717 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1717 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1718 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1718 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
1719 .op_name = "OP_RESTOREFH", 1719 .op_name = "OP_RESTOREFH",
1720 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1720 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1721 }, 1721 },
1722 [OP_SAVEFH] = { 1722 [OP_SAVEFH] = {
1723 .op_func = (nfsd4op_func)nfsd4_savefh, 1723 .op_func = (nfsd4op_func)nfsd4_savefh,
1724 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, 1724 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
1725 .op_name = "OP_SAVEFH", 1725 .op_name = "OP_SAVEFH",
1726 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1726 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1727 }, 1727 },
1728 [OP_SECINFO] = { 1728 [OP_SECINFO] = {
1729 .op_func = (nfsd4op_func)nfsd4_secinfo, 1729 .op_func = (nfsd4op_func)nfsd4_secinfo,
1730 .op_flags = OP_HANDLES_WRONGSEC, 1730 .op_flags = OP_HANDLES_WRONGSEC,
1731 .op_name = "OP_SECINFO", 1731 .op_name = "OP_SECINFO",
1732 }, 1732 },
1733 [OP_SETATTR] = { 1733 [OP_SETATTR] = {
1734 .op_func = (nfsd4op_func)nfsd4_setattr, 1734 .op_func = (nfsd4op_func)nfsd4_setattr,
1735 .op_name = "OP_SETATTR", 1735 .op_name = "OP_SETATTR",
1736 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1736 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1737 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize, 1737 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize,
1738 .op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid, 1738 .op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid,
1739 }, 1739 },
1740 [OP_SETCLIENTID] = { 1740 [OP_SETCLIENTID] = {
1741 .op_func = (nfsd4op_func)nfsd4_setclientid, 1741 .op_func = (nfsd4op_func)nfsd4_setclientid,
1742 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1742 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1743 | OP_MODIFIES_SOMETHING | OP_CACHEME, 1743 | OP_MODIFIES_SOMETHING | OP_CACHEME,
1744 .op_name = "OP_SETCLIENTID", 1744 .op_name = "OP_SETCLIENTID",
1745 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setclientid_rsize, 1745 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setclientid_rsize,
1746 }, 1746 },
1747 [OP_SETCLIENTID_CONFIRM] = { 1747 [OP_SETCLIENTID_CONFIRM] = {
1748 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, 1748 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm,
1749 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1749 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1750 | OP_MODIFIES_SOMETHING | OP_CACHEME, 1750 | OP_MODIFIES_SOMETHING | OP_CACHEME,
1751 .op_name = "OP_SETCLIENTID_CONFIRM", 1751 .op_name = "OP_SETCLIENTID_CONFIRM",
1752 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1752 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1753 }, 1753 },
1754 [OP_VERIFY] = { 1754 [OP_VERIFY] = {
1755 .op_func = (nfsd4op_func)nfsd4_verify, 1755 .op_func = (nfsd4op_func)nfsd4_verify,
1756 .op_name = "OP_VERIFY", 1756 .op_name = "OP_VERIFY",
1757 }, 1757 },
1758 [OP_WRITE] = { 1758 [OP_WRITE] = {
1759 .op_func = (nfsd4op_func)nfsd4_write, 1759 .op_func = (nfsd4op_func)nfsd4_write,
1760 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1760 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1761 .op_name = "OP_WRITE", 1761 .op_name = "OP_WRITE",
1762 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, 1762 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
1763 .op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid, 1763 .op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid,
1764 }, 1764 },
1765 [OP_RELEASE_LOCKOWNER] = { 1765 [OP_RELEASE_LOCKOWNER] = {
1766 .op_func = (nfsd4op_func)nfsd4_release_lockowner, 1766 .op_func = (nfsd4op_func)nfsd4_release_lockowner,
1767 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1767 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1768 | OP_MODIFIES_SOMETHING, 1768 | OP_MODIFIES_SOMETHING,
1769 .op_name = "OP_RELEASE_LOCKOWNER", 1769 .op_name = "OP_RELEASE_LOCKOWNER",
1770 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1770 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1771 }, 1771 },
1772 1772
1773 /* NFSv4.1 operations */ 1773 /* NFSv4.1 operations */
1774 [OP_EXCHANGE_ID] = { 1774 [OP_EXCHANGE_ID] = {
1775 .op_func = (nfsd4op_func)nfsd4_exchange_id, 1775 .op_func = (nfsd4op_func)nfsd4_exchange_id,
1776 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1776 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1777 | OP_MODIFIES_SOMETHING, 1777 | OP_MODIFIES_SOMETHING,
1778 .op_name = "OP_EXCHANGE_ID", 1778 .op_name = "OP_EXCHANGE_ID",
1779 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize, 1779 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize,
1780 }, 1780 },
1781 [OP_BACKCHANNEL_CTL] = { 1781 [OP_BACKCHANNEL_CTL] = {
1782 .op_func = (nfsd4op_func)nfsd4_backchannel_ctl, 1782 .op_func = (nfsd4op_func)nfsd4_backchannel_ctl,
1783 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, 1783 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1784 .op_name = "OP_BACKCHANNEL_CTL", 1784 .op_name = "OP_BACKCHANNEL_CTL",
1785 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1785 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1786 }, 1786 },
1787 [OP_BIND_CONN_TO_SESSION] = { 1787 [OP_BIND_CONN_TO_SESSION] = {
1788 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, 1788 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
1789 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1789 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1790 | OP_MODIFIES_SOMETHING, 1790 | OP_MODIFIES_SOMETHING,
1791 .op_name = "OP_BIND_CONN_TO_SESSION", 1791 .op_name = "OP_BIND_CONN_TO_SESSION",
1792 .op_rsize_bop = (nfsd4op_rsize)nfsd4_bind_conn_to_session_rsize, 1792 .op_rsize_bop = (nfsd4op_rsize)nfsd4_bind_conn_to_session_rsize,
1793 }, 1793 },
1794 [OP_CREATE_SESSION] = { 1794 [OP_CREATE_SESSION] = {
1795 .op_func = (nfsd4op_func)nfsd4_create_session, 1795 .op_func = (nfsd4op_func)nfsd4_create_session,
1796 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1796 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1797 | OP_MODIFIES_SOMETHING, 1797 | OP_MODIFIES_SOMETHING,
1798 .op_name = "OP_CREATE_SESSION", 1798 .op_name = "OP_CREATE_SESSION",
1799 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_session_rsize, 1799 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_session_rsize,
1800 }, 1800 },
1801 [OP_DESTROY_SESSION] = { 1801 [OP_DESTROY_SESSION] = {
1802 .op_func = (nfsd4op_func)nfsd4_destroy_session, 1802 .op_func = (nfsd4op_func)nfsd4_destroy_session,
1803 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1803 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1804 | OP_MODIFIES_SOMETHING, 1804 | OP_MODIFIES_SOMETHING,
1805 .op_name = "OP_DESTROY_SESSION", 1805 .op_name = "OP_DESTROY_SESSION",
1806 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1806 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1807 }, 1807 },
1808 [OP_SEQUENCE] = { 1808 [OP_SEQUENCE] = {
1809 .op_func = (nfsd4op_func)nfsd4_sequence, 1809 .op_func = (nfsd4op_func)nfsd4_sequence,
1810 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1810 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
1811 .op_name = "OP_SEQUENCE", 1811 .op_name = "OP_SEQUENCE",
1812 }, 1812 },
1813 [OP_DESTROY_CLIENTID] = { 1813 [OP_DESTROY_CLIENTID] = {
1814 .op_func = (nfsd4op_func)nfsd4_destroy_clientid, 1814 .op_func = (nfsd4op_func)nfsd4_destroy_clientid,
1815 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1815 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1816 | OP_MODIFIES_SOMETHING, 1816 | OP_MODIFIES_SOMETHING,
1817 .op_name = "OP_DESTROY_CLIENTID", 1817 .op_name = "OP_DESTROY_CLIENTID",
1818 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1818 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1819 }, 1819 },
1820 [OP_RECLAIM_COMPLETE] = { 1820 [OP_RECLAIM_COMPLETE] = {
1821 .op_func = (nfsd4op_func)nfsd4_reclaim_complete, 1821 .op_func = (nfsd4op_func)nfsd4_reclaim_complete,
1822 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, 1822 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1823 .op_name = "OP_RECLAIM_COMPLETE", 1823 .op_name = "OP_RECLAIM_COMPLETE",
1824 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1824 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1825 }, 1825 },
1826 [OP_SECINFO_NO_NAME] = { 1826 [OP_SECINFO_NO_NAME] = {
1827 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, 1827 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
1828 .op_flags = OP_HANDLES_WRONGSEC, 1828 .op_flags = OP_HANDLES_WRONGSEC,
1829 .op_name = "OP_SECINFO_NO_NAME", 1829 .op_name = "OP_SECINFO_NO_NAME",
1830 }, 1830 },
1831 [OP_TEST_STATEID] = { 1831 [OP_TEST_STATEID] = {
1832 .op_func = (nfsd4op_func)nfsd4_test_stateid, 1832 .op_func = (nfsd4op_func)nfsd4_test_stateid,
1833 .op_flags = ALLOWED_WITHOUT_FH, 1833 .op_flags = ALLOWED_WITHOUT_FH,
1834 .op_name = "OP_TEST_STATEID", 1834 .op_name = "OP_TEST_STATEID",
1835 }, 1835 },
1836 [OP_FREE_STATEID] = { 1836 [OP_FREE_STATEID] = {
1837 .op_func = (nfsd4op_func)nfsd4_free_stateid, 1837 .op_func = (nfsd4op_func)nfsd4_free_stateid,
1838 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, 1838 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1839 .op_name = "OP_FREE_STATEID", 1839 .op_name = "OP_FREE_STATEID",
1840 .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid, 1840 .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
1841 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1841 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1842 }, 1842 },
1843 }; 1843 };
1844 1844
1845 #ifdef NFSD_DEBUG 1845 #ifdef NFSD_DEBUG
1846 static const char *nfsd4_op_name(unsigned opnum) 1846 static const char *nfsd4_op_name(unsigned opnum)
1847 { 1847 {
1848 if (opnum < ARRAY_SIZE(nfsd4_ops)) 1848 if (opnum < ARRAY_SIZE(nfsd4_ops))
1849 return nfsd4_ops[opnum].op_name; 1849 return nfsd4_ops[opnum].op_name;
1850 return "unknown_operation"; 1850 return "unknown_operation";
1851 } 1851 }
1852 #endif 1852 #endif
1853 1853
1854 #define nfsd4_voidres nfsd4_voidargs 1854 #define nfsd4_voidres nfsd4_voidargs
1855 struct nfsd4_voidargs { int dummy; }; 1855 struct nfsd4_voidargs { int dummy; };
1856 1856
1857 static struct svc_procedure nfsd_procedures4[2] = { 1857 static struct svc_procedure nfsd_procedures4[2] = {
1858 [NFSPROC4_NULL] = { 1858 [NFSPROC4_NULL] = {
1859 .pc_func = (svc_procfunc) nfsd4_proc_null, 1859 .pc_func = (svc_procfunc) nfsd4_proc_null,
1860 .pc_encode = (kxdrproc_t) nfs4svc_encode_voidres, 1860 .pc_encode = (kxdrproc_t) nfs4svc_encode_voidres,
1861 .pc_argsize = sizeof(struct nfsd4_voidargs), 1861 .pc_argsize = sizeof(struct nfsd4_voidargs),
1862 .pc_ressize = sizeof(struct nfsd4_voidres), 1862 .pc_ressize = sizeof(struct nfsd4_voidres),
1863 .pc_cachetype = RC_NOCACHE, 1863 .pc_cachetype = RC_NOCACHE,
1864 .pc_xdrressize = 1, 1864 .pc_xdrressize = 1,
1865 }, 1865 },
1866 [NFSPROC4_COMPOUND] = { 1866 [NFSPROC4_COMPOUND] = {
1867 .pc_func = (svc_procfunc) nfsd4_proc_compound, 1867 .pc_func = (svc_procfunc) nfsd4_proc_compound,
1868 .pc_decode = (kxdrproc_t) nfs4svc_decode_compoundargs, 1868 .pc_decode = (kxdrproc_t) nfs4svc_decode_compoundargs,
1869 .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres, 1869 .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres,
1870 .pc_argsize = sizeof(struct nfsd4_compoundargs), 1870 .pc_argsize = sizeof(struct nfsd4_compoundargs),
1871 .pc_ressize = sizeof(struct nfsd4_compoundres), 1871 .pc_ressize = sizeof(struct nfsd4_compoundres),
1872 .pc_release = nfsd4_release_compoundargs, 1872 .pc_release = nfsd4_release_compoundargs,
1873 .pc_cachetype = RC_NOCACHE, 1873 .pc_cachetype = RC_NOCACHE,
1874 .pc_xdrressize = NFSD_BUFSIZE/4, 1874 .pc_xdrressize = NFSD_BUFSIZE/4,
1875 }, 1875 },
1876 }; 1876 };
1877 1877
1878 struct svc_version nfsd_version4 = { 1878 struct svc_version nfsd_version4 = {
1879 .vs_vers = 4, 1879 .vs_vers = 4,
1880 .vs_nproc = 2, 1880 .vs_nproc = 2,
1881 .vs_proc = nfsd_procedures4, 1881 .vs_proc = nfsd_procedures4,
1882 .vs_dispatch = nfsd_dispatch, 1882 .vs_dispatch = nfsd_dispatch,
1883 .vs_xdrsize = NFS4_SVC_XDRSIZE, 1883 .vs_xdrsize = NFS4_SVC_XDRSIZE,
1884 }; 1884 };
1885 1885
1886 /* 1886 /*
1887 * Local variables: 1887 * Local variables:
1888 * c-basic-offset: 8 1888 * c-basic-offset: 8
1889 * End: 1889 * End:
1890 */ 1890 */
1891 1891
1 /* 1 /*
2 * Hodge-podge collection of knfsd-related stuff. 2 * Hodge-podge collection of knfsd-related stuff.
3 * I will sort this out later. 3 * I will sort this out later.
4 * 4 *
5 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> 5 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
6 */ 6 */
7 7
8 #ifndef LINUX_NFSD_NFSD_H 8 #ifndef LINUX_NFSD_NFSD_H
9 #define LINUX_NFSD_NFSD_H 9 #define LINUX_NFSD_NFSD_H
10 10
11 #include <linux/types.h> 11 #include <linux/types.h>
12 #include <linux/mount.h> 12 #include <linux/mount.h>
13 13
14 #include <linux/nfs.h> 14 #include <linux/nfs.h>
15 #include <linux/nfs2.h> 15 #include <linux/nfs2.h>
16 #include <linux/nfs3.h> 16 #include <linux/nfs3.h>
17 #include <linux/nfs4.h> 17 #include <linux/nfs4.h>
18 #include <linux/sunrpc/msg_prot.h> 18 #include <linux/sunrpc/msg_prot.h>
19 19
20 #include <linux/nfsd/debug.h> 20 #include <linux/nfsd/debug.h>
21 #include <linux/nfsd/export.h> 21 #include <linux/nfsd/export.h>
22 #include <linux/nfsd/stats.h> 22 #include <linux/nfsd/stats.h>
23 23
24 /* 24 /*
25 * nfsd version 25 * nfsd version
26 */ 26 */
27 #define NFSD_SUPPORTED_MINOR_VERSION 2 27 #define NFSD_SUPPORTED_MINOR_VERSION 2
28 /* 28 /*
29 * Maximum blocksizes supported by daemon under various circumstances. 29 * Maximum blocksizes supported by daemon under various circumstances.
30 */ 30 */
31 #define NFSSVC_MAXBLKSIZE RPCSVC_MAXPAYLOAD 31 #define NFSSVC_MAXBLKSIZE RPCSVC_MAXPAYLOAD
32 /* NFSv2 is limited by the protocol specification, see RFC 1094 */ 32 /* NFSv2 is limited by the protocol specification, see RFC 1094 */
33 #define NFSSVC_MAXBLKSIZE_V2 (8*1024) 33 #define NFSSVC_MAXBLKSIZE_V2 (8*1024)
34 34
35 35
36 /* 36 /*
37 * Largest number of bytes we need to allocate for an NFS 37 * Largest number of bytes we need to allocate for an NFS
38 * call or reply. Used to control buffer sizes. We use 38 * call or reply. Used to control buffer sizes. We use
39 * the length of v3 WRITE, READDIR and READDIR replies 39 * the length of v3 WRITE, READDIR and READDIR replies
40 * which are an RPC header, up to 26 XDR units of reply 40 * which are an RPC header, up to 26 XDR units of reply
41 * data, and some page data. 41 * data, and some page data.
42 * 42 *
43 * Note that accuracy here doesn't matter too much as the 43 * Note that accuracy here doesn't matter too much as the
44 * size is rounded up to a page size when allocating space. 44 * size is rounded up to a page size when allocating space.
45 */ 45 */
46 #define NFSD_BUFSIZE ((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + NFSSVC_MAXBLKSIZE) 46 #define NFSD_BUFSIZE ((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + NFSSVC_MAXBLKSIZE)
47 47
48 struct readdir_cd { 48 struct readdir_cd {
49 __be32 err; /* 0, nfserr, or nfserr_eof */ 49 __be32 err; /* 0, nfserr, or nfserr_eof */
50 }; 50 };
51 51
52 52
53 extern struct svc_program nfsd_program; 53 extern struct svc_program nfsd_program;
54 extern struct svc_version nfsd_version2, nfsd_version3, 54 extern struct svc_version nfsd_version2, nfsd_version3,
55 nfsd_version4; 55 nfsd_version4;
56 extern u32 nfsd_supported_minorversion;
57 extern struct mutex nfsd_mutex; 56 extern struct mutex nfsd_mutex;
58 extern spinlock_t nfsd_drc_lock; 57 extern spinlock_t nfsd_drc_lock;
59 extern unsigned long nfsd_drc_max_mem; 58 extern unsigned long nfsd_drc_max_mem;
60 extern unsigned long nfsd_drc_mem_used; 59 extern unsigned long nfsd_drc_mem_used;
61 60
62 extern const struct seq_operations nfs_exports_op; 61 extern const struct seq_operations nfs_exports_op;
63 62
64 /* 63 /*
65 * Function prototypes. 64 * Function prototypes.
66 */ 65 */
67 int nfsd_svc(int nrservs, struct net *net); 66 int nfsd_svc(int nrservs, struct net *net);
68 int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); 67 int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
69 68
70 int nfsd_nrthreads(struct net *); 69 int nfsd_nrthreads(struct net *);
71 int nfsd_nrpools(struct net *); 70 int nfsd_nrpools(struct net *);
72 int nfsd_get_nrthreads(int n, int *, struct net *); 71 int nfsd_get_nrthreads(int n, int *, struct net *);
73 int nfsd_set_nrthreads(int n, int *, struct net *); 72 int nfsd_set_nrthreads(int n, int *, struct net *);
74 int nfsd_pool_stats_open(struct inode *, struct file *); 73 int nfsd_pool_stats_open(struct inode *, struct file *);
75 int nfsd_pool_stats_release(struct inode *, struct file *); 74 int nfsd_pool_stats_release(struct inode *, struct file *);
76 75
77 void nfsd_destroy(struct net *net); 76 void nfsd_destroy(struct net *net);
78 77
79 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 78 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
80 #ifdef CONFIG_NFSD_V2_ACL 79 #ifdef CONFIG_NFSD_V2_ACL
81 extern struct svc_version nfsd_acl_version2; 80 extern struct svc_version nfsd_acl_version2;
82 #else 81 #else
83 #define nfsd_acl_version2 NULL 82 #define nfsd_acl_version2 NULL
84 #endif 83 #endif
85 #ifdef CONFIG_NFSD_V3_ACL 84 #ifdef CONFIG_NFSD_V3_ACL
86 extern struct svc_version nfsd_acl_version3; 85 extern struct svc_version nfsd_acl_version3;
87 #else 86 #else
88 #define nfsd_acl_version3 NULL 87 #define nfsd_acl_version3 NULL
89 #endif 88 #endif
90 #endif 89 #endif
91 90
92 enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; 91 enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
93 int nfsd_vers(int vers, enum vers_op change); 92 int nfsd_vers(int vers, enum vers_op change);
94 int nfsd_minorversion(u32 minorversion, enum vers_op change); 93 int nfsd_minorversion(u32 minorversion, enum vers_op change);
95 void nfsd_reset_versions(void); 94 void nfsd_reset_versions(void);
96 int nfsd_create_serv(struct net *net); 95 int nfsd_create_serv(struct net *net);
97 96
98 extern int nfsd_max_blksize; 97 extern int nfsd_max_blksize;
99 98
100 static inline int nfsd_v4client(struct svc_rqst *rq) 99 static inline int nfsd_v4client(struct svc_rqst *rq)
101 { 100 {
102 return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4; 101 return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4;
103 } 102 }
104 103
105 /* 104 /*
106 * NFSv4 State 105 * NFSv4 State
107 */ 106 */
108 #ifdef CONFIG_NFSD_V4 107 #ifdef CONFIG_NFSD_V4
109 extern unsigned long max_delegations; 108 extern unsigned long max_delegations;
110 void nfs4_state_init(void); 109 void nfs4_state_init(void);
111 int nfsd4_init_slabs(void); 110 int nfsd4_init_slabs(void);
112 void nfsd4_free_slabs(void); 111 void nfsd4_free_slabs(void);
113 int nfs4_state_start(void); 112 int nfs4_state_start(void);
114 int nfs4_state_start_net(struct net *net); 113 int nfs4_state_start_net(struct net *net);
115 void nfs4_state_shutdown(void); 114 void nfs4_state_shutdown(void);
116 void nfs4_state_shutdown_net(struct net *net); 115 void nfs4_state_shutdown_net(struct net *net);
117 void nfs4_reset_lease(time_t leasetime); 116 void nfs4_reset_lease(time_t leasetime);
118 int nfs4_reset_recoverydir(char *recdir); 117 int nfs4_reset_recoverydir(char *recdir);
119 char * nfs4_recoverydir(void); 118 char * nfs4_recoverydir(void);
120 #else 119 #else
121 static inline void nfs4_state_init(void) { } 120 static inline void nfs4_state_init(void) { }
122 static inline int nfsd4_init_slabs(void) { return 0; } 121 static inline int nfsd4_init_slabs(void) { return 0; }
123 static inline void nfsd4_free_slabs(void) { } 122 static inline void nfsd4_free_slabs(void) { }
124 static inline int nfs4_state_start(void) { return 0; } 123 static inline int nfs4_state_start(void) { return 0; }
125 static inline int nfs4_state_start_net(struct net *net) { return 0; } 124 static inline int nfs4_state_start_net(struct net *net) { return 0; }
126 static inline void nfs4_state_shutdown(void) { } 125 static inline void nfs4_state_shutdown(void) { }
127 static inline void nfs4_state_shutdown_net(struct net *net) { } 126 static inline void nfs4_state_shutdown_net(struct net *net) { }
128 static inline void nfs4_reset_lease(time_t leasetime) { } 127 static inline void nfs4_reset_lease(time_t leasetime) { }
129 static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } 128 static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
130 static inline char * nfs4_recoverydir(void) {return NULL; } 129 static inline char * nfs4_recoverydir(void) {return NULL; }
131 #endif 130 #endif
132 131
133 /* 132 /*
134 * lockd binding 133 * lockd binding
135 */ 134 */
136 void nfsd_lockd_init(void); 135 void nfsd_lockd_init(void);
137 void nfsd_lockd_shutdown(void); 136 void nfsd_lockd_shutdown(void);
138 137
139 138
140 /* 139 /*
141 * These macros provide pre-xdr'ed values for faster operation. 140 * These macros provide pre-xdr'ed values for faster operation.
142 */ 141 */
143 #define nfs_ok cpu_to_be32(NFS_OK) 142 #define nfs_ok cpu_to_be32(NFS_OK)
144 #define nfserr_perm cpu_to_be32(NFSERR_PERM) 143 #define nfserr_perm cpu_to_be32(NFSERR_PERM)
145 #define nfserr_noent cpu_to_be32(NFSERR_NOENT) 144 #define nfserr_noent cpu_to_be32(NFSERR_NOENT)
146 #define nfserr_io cpu_to_be32(NFSERR_IO) 145 #define nfserr_io cpu_to_be32(NFSERR_IO)
147 #define nfserr_nxio cpu_to_be32(NFSERR_NXIO) 146 #define nfserr_nxio cpu_to_be32(NFSERR_NXIO)
148 #define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN) 147 #define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN)
149 #define nfserr_acces cpu_to_be32(NFSERR_ACCES) 148 #define nfserr_acces cpu_to_be32(NFSERR_ACCES)
150 #define nfserr_exist cpu_to_be32(NFSERR_EXIST) 149 #define nfserr_exist cpu_to_be32(NFSERR_EXIST)
151 #define nfserr_xdev cpu_to_be32(NFSERR_XDEV) 150 #define nfserr_xdev cpu_to_be32(NFSERR_XDEV)
152 #define nfserr_nodev cpu_to_be32(NFSERR_NODEV) 151 #define nfserr_nodev cpu_to_be32(NFSERR_NODEV)
153 #define nfserr_notdir cpu_to_be32(NFSERR_NOTDIR) 152 #define nfserr_notdir cpu_to_be32(NFSERR_NOTDIR)
154 #define nfserr_isdir cpu_to_be32(NFSERR_ISDIR) 153 #define nfserr_isdir cpu_to_be32(NFSERR_ISDIR)
155 #define nfserr_inval cpu_to_be32(NFSERR_INVAL) 154 #define nfserr_inval cpu_to_be32(NFSERR_INVAL)
156 #define nfserr_fbig cpu_to_be32(NFSERR_FBIG) 155 #define nfserr_fbig cpu_to_be32(NFSERR_FBIG)
157 #define nfserr_nospc cpu_to_be32(NFSERR_NOSPC) 156 #define nfserr_nospc cpu_to_be32(NFSERR_NOSPC)
158 #define nfserr_rofs cpu_to_be32(NFSERR_ROFS) 157 #define nfserr_rofs cpu_to_be32(NFSERR_ROFS)
159 #define nfserr_mlink cpu_to_be32(NFSERR_MLINK) 158 #define nfserr_mlink cpu_to_be32(NFSERR_MLINK)
160 #define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP) 159 #define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP)
161 #define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG) 160 #define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG)
162 #define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY) 161 #define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY)
163 #define nfserr_dquot cpu_to_be32(NFSERR_DQUOT) 162 #define nfserr_dquot cpu_to_be32(NFSERR_DQUOT)
164 #define nfserr_stale cpu_to_be32(NFSERR_STALE) 163 #define nfserr_stale cpu_to_be32(NFSERR_STALE)
165 #define nfserr_remote cpu_to_be32(NFSERR_REMOTE) 164 #define nfserr_remote cpu_to_be32(NFSERR_REMOTE)
166 #define nfserr_wflush cpu_to_be32(NFSERR_WFLUSH) 165 #define nfserr_wflush cpu_to_be32(NFSERR_WFLUSH)
167 #define nfserr_badhandle cpu_to_be32(NFSERR_BADHANDLE) 166 #define nfserr_badhandle cpu_to_be32(NFSERR_BADHANDLE)
168 #define nfserr_notsync cpu_to_be32(NFSERR_NOT_SYNC) 167 #define nfserr_notsync cpu_to_be32(NFSERR_NOT_SYNC)
169 #define nfserr_badcookie cpu_to_be32(NFSERR_BAD_COOKIE) 168 #define nfserr_badcookie cpu_to_be32(NFSERR_BAD_COOKIE)
170 #define nfserr_notsupp cpu_to_be32(NFSERR_NOTSUPP) 169 #define nfserr_notsupp cpu_to_be32(NFSERR_NOTSUPP)
171 #define nfserr_toosmall cpu_to_be32(NFSERR_TOOSMALL) 170 #define nfserr_toosmall cpu_to_be32(NFSERR_TOOSMALL)
172 #define nfserr_serverfault cpu_to_be32(NFSERR_SERVERFAULT) 171 #define nfserr_serverfault cpu_to_be32(NFSERR_SERVERFAULT)
173 #define nfserr_badtype cpu_to_be32(NFSERR_BADTYPE) 172 #define nfserr_badtype cpu_to_be32(NFSERR_BADTYPE)
174 #define nfserr_jukebox cpu_to_be32(NFSERR_JUKEBOX) 173 #define nfserr_jukebox cpu_to_be32(NFSERR_JUKEBOX)
175 #define nfserr_denied cpu_to_be32(NFSERR_DENIED) 174 #define nfserr_denied cpu_to_be32(NFSERR_DENIED)
176 #define nfserr_deadlock cpu_to_be32(NFSERR_DEADLOCK) 175 #define nfserr_deadlock cpu_to_be32(NFSERR_DEADLOCK)
177 #define nfserr_expired cpu_to_be32(NFSERR_EXPIRED) 176 #define nfserr_expired cpu_to_be32(NFSERR_EXPIRED)
178 #define nfserr_bad_cookie cpu_to_be32(NFSERR_BAD_COOKIE) 177 #define nfserr_bad_cookie cpu_to_be32(NFSERR_BAD_COOKIE)
179 #define nfserr_same cpu_to_be32(NFSERR_SAME) 178 #define nfserr_same cpu_to_be32(NFSERR_SAME)
180 #define nfserr_clid_inuse cpu_to_be32(NFSERR_CLID_INUSE) 179 #define nfserr_clid_inuse cpu_to_be32(NFSERR_CLID_INUSE)
181 #define nfserr_stale_clientid cpu_to_be32(NFSERR_STALE_CLIENTID) 180 #define nfserr_stale_clientid cpu_to_be32(NFSERR_STALE_CLIENTID)
182 #define nfserr_resource cpu_to_be32(NFSERR_RESOURCE) 181 #define nfserr_resource cpu_to_be32(NFSERR_RESOURCE)
183 #define nfserr_moved cpu_to_be32(NFSERR_MOVED) 182 #define nfserr_moved cpu_to_be32(NFSERR_MOVED)
184 #define nfserr_nofilehandle cpu_to_be32(NFSERR_NOFILEHANDLE) 183 #define nfserr_nofilehandle cpu_to_be32(NFSERR_NOFILEHANDLE)
185 #define nfserr_minor_vers_mismatch cpu_to_be32(NFSERR_MINOR_VERS_MISMATCH) 184 #define nfserr_minor_vers_mismatch cpu_to_be32(NFSERR_MINOR_VERS_MISMATCH)
186 #define nfserr_share_denied cpu_to_be32(NFSERR_SHARE_DENIED) 185 #define nfserr_share_denied cpu_to_be32(NFSERR_SHARE_DENIED)
187 #define nfserr_stale_stateid cpu_to_be32(NFSERR_STALE_STATEID) 186 #define nfserr_stale_stateid cpu_to_be32(NFSERR_STALE_STATEID)
188 #define nfserr_old_stateid cpu_to_be32(NFSERR_OLD_STATEID) 187 #define nfserr_old_stateid cpu_to_be32(NFSERR_OLD_STATEID)
189 #define nfserr_bad_stateid cpu_to_be32(NFSERR_BAD_STATEID) 188 #define nfserr_bad_stateid cpu_to_be32(NFSERR_BAD_STATEID)
190 #define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID) 189 #define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID)
191 #define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK) 190 #define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK)
192 #define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME) 191 #define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME)
193 #define nfserr_lock_range cpu_to_be32(NFSERR_LOCK_RANGE) 192 #define nfserr_lock_range cpu_to_be32(NFSERR_LOCK_RANGE)
194 #define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH) 193 #define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH)
195 #define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) 194 #define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP)
196 #define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) 195 #define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR)
197 #define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) 196 #define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE)
198 #define nfserr_badowner cpu_to_be32(NFSERR_BADOWNER) 197 #define nfserr_badowner cpu_to_be32(NFSERR_BADOWNER)
199 #define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) 198 #define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD)
200 #define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) 199 #define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL)
201 #define nfserr_grace cpu_to_be32(NFSERR_GRACE) 200 #define nfserr_grace cpu_to_be32(NFSERR_GRACE)
202 #define nfserr_no_grace cpu_to_be32(NFSERR_NO_GRACE) 201 #define nfserr_no_grace cpu_to_be32(NFSERR_NO_GRACE)
203 #define nfserr_reclaim_bad cpu_to_be32(NFSERR_RECLAIM_BAD) 202 #define nfserr_reclaim_bad cpu_to_be32(NFSERR_RECLAIM_BAD)
204 #define nfserr_badname cpu_to_be32(NFSERR_BADNAME) 203 #define nfserr_badname cpu_to_be32(NFSERR_BADNAME)
205 #define nfserr_cb_path_down cpu_to_be32(NFSERR_CB_PATH_DOWN) 204 #define nfserr_cb_path_down cpu_to_be32(NFSERR_CB_PATH_DOWN)
206 #define nfserr_locked cpu_to_be32(NFSERR_LOCKED) 205 #define nfserr_locked cpu_to_be32(NFSERR_LOCKED)
207 #define nfserr_wrongsec cpu_to_be32(NFSERR_WRONGSEC) 206 #define nfserr_wrongsec cpu_to_be32(NFSERR_WRONGSEC)
208 #define nfserr_badiomode cpu_to_be32(NFS4ERR_BADIOMODE) 207 #define nfserr_badiomode cpu_to_be32(NFS4ERR_BADIOMODE)
209 #define nfserr_badlayout cpu_to_be32(NFS4ERR_BADLAYOUT) 208 #define nfserr_badlayout cpu_to_be32(NFS4ERR_BADLAYOUT)
210 #define nfserr_bad_session_digest cpu_to_be32(NFS4ERR_BAD_SESSION_DIGEST) 209 #define nfserr_bad_session_digest cpu_to_be32(NFS4ERR_BAD_SESSION_DIGEST)
211 #define nfserr_badsession cpu_to_be32(NFS4ERR_BADSESSION) 210 #define nfserr_badsession cpu_to_be32(NFS4ERR_BADSESSION)
212 #define nfserr_badslot cpu_to_be32(NFS4ERR_BADSLOT) 211 #define nfserr_badslot cpu_to_be32(NFS4ERR_BADSLOT)
213 #define nfserr_complete_already cpu_to_be32(NFS4ERR_COMPLETE_ALREADY) 212 #define nfserr_complete_already cpu_to_be32(NFS4ERR_COMPLETE_ALREADY)
214 #define nfserr_conn_not_bound_to_session cpu_to_be32(NFS4ERR_CONN_NOT_BOUND_TO_SESSION) 213 #define nfserr_conn_not_bound_to_session cpu_to_be32(NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
215 #define nfserr_deleg_already_wanted cpu_to_be32(NFS4ERR_DELEG_ALREADY_WANTED) 214 #define nfserr_deleg_already_wanted cpu_to_be32(NFS4ERR_DELEG_ALREADY_WANTED)
216 #define nfserr_back_chan_busy cpu_to_be32(NFS4ERR_BACK_CHAN_BUSY) 215 #define nfserr_back_chan_busy cpu_to_be32(NFS4ERR_BACK_CHAN_BUSY)
217 #define nfserr_layouttrylater cpu_to_be32(NFS4ERR_LAYOUTTRYLATER) 216 #define nfserr_layouttrylater cpu_to_be32(NFS4ERR_LAYOUTTRYLATER)
218 #define nfserr_layoutunavailable cpu_to_be32(NFS4ERR_LAYOUTUNAVAILABLE) 217 #define nfserr_layoutunavailable cpu_to_be32(NFS4ERR_LAYOUTUNAVAILABLE)
219 #define nfserr_nomatching_layout cpu_to_be32(NFS4ERR_NOMATCHING_LAYOUT) 218 #define nfserr_nomatching_layout cpu_to_be32(NFS4ERR_NOMATCHING_LAYOUT)
220 #define nfserr_recallconflict cpu_to_be32(NFS4ERR_RECALLCONFLICT) 219 #define nfserr_recallconflict cpu_to_be32(NFS4ERR_RECALLCONFLICT)
221 #define nfserr_unknown_layouttype cpu_to_be32(NFS4ERR_UNKNOWN_LAYOUTTYPE) 220 #define nfserr_unknown_layouttype cpu_to_be32(NFS4ERR_UNKNOWN_LAYOUTTYPE)
222 #define nfserr_seq_misordered cpu_to_be32(NFS4ERR_SEQ_MISORDERED) 221 #define nfserr_seq_misordered cpu_to_be32(NFS4ERR_SEQ_MISORDERED)
223 #define nfserr_sequence_pos cpu_to_be32(NFS4ERR_SEQUENCE_POS) 222 #define nfserr_sequence_pos cpu_to_be32(NFS4ERR_SEQUENCE_POS)
224 #define nfserr_req_too_big cpu_to_be32(NFS4ERR_REQ_TOO_BIG) 223 #define nfserr_req_too_big cpu_to_be32(NFS4ERR_REQ_TOO_BIG)
225 #define nfserr_rep_too_big cpu_to_be32(NFS4ERR_REP_TOO_BIG) 224 #define nfserr_rep_too_big cpu_to_be32(NFS4ERR_REP_TOO_BIG)
226 #define nfserr_rep_too_big_to_cache cpu_to_be32(NFS4ERR_REP_TOO_BIG_TO_CACHE) 225 #define nfserr_rep_too_big_to_cache cpu_to_be32(NFS4ERR_REP_TOO_BIG_TO_CACHE)
227 #define nfserr_retry_uncached_rep cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP) 226 #define nfserr_retry_uncached_rep cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP)
228 #define nfserr_unsafe_compound cpu_to_be32(NFS4ERR_UNSAFE_COMPOUND) 227 #define nfserr_unsafe_compound cpu_to_be32(NFS4ERR_UNSAFE_COMPOUND)
229 #define nfserr_too_many_ops cpu_to_be32(NFS4ERR_TOO_MANY_OPS) 228 #define nfserr_too_many_ops cpu_to_be32(NFS4ERR_TOO_MANY_OPS)
230 #define nfserr_op_not_in_session cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION) 229 #define nfserr_op_not_in_session cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION)
231 #define nfserr_hash_alg_unsupp cpu_to_be32(NFS4ERR_HASH_ALG_UNSUPP) 230 #define nfserr_hash_alg_unsupp cpu_to_be32(NFS4ERR_HASH_ALG_UNSUPP)
232 #define nfserr_clientid_busy cpu_to_be32(NFS4ERR_CLIENTID_BUSY) 231 #define nfserr_clientid_busy cpu_to_be32(NFS4ERR_CLIENTID_BUSY)
233 #define nfserr_pnfs_io_hole cpu_to_be32(NFS4ERR_PNFS_IO_HOLE) 232 #define nfserr_pnfs_io_hole cpu_to_be32(NFS4ERR_PNFS_IO_HOLE)
234 #define nfserr_seq_false_retry cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY) 233 #define nfserr_seq_false_retry cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY)
235 #define nfserr_bad_high_slot cpu_to_be32(NFS4ERR_BAD_HIGH_SLOT) 234 #define nfserr_bad_high_slot cpu_to_be32(NFS4ERR_BAD_HIGH_SLOT)
236 #define nfserr_deadsession cpu_to_be32(NFS4ERR_DEADSESSION) 235 #define nfserr_deadsession cpu_to_be32(NFS4ERR_DEADSESSION)
237 #define nfserr_encr_alg_unsupp cpu_to_be32(NFS4ERR_ENCR_ALG_UNSUPP) 236 #define nfserr_encr_alg_unsupp cpu_to_be32(NFS4ERR_ENCR_ALG_UNSUPP)
238 #define nfserr_pnfs_no_layout cpu_to_be32(NFS4ERR_PNFS_NO_LAYOUT) 237 #define nfserr_pnfs_no_layout cpu_to_be32(NFS4ERR_PNFS_NO_LAYOUT)
239 #define nfserr_not_only_op cpu_to_be32(NFS4ERR_NOT_ONLY_OP) 238 #define nfserr_not_only_op cpu_to_be32(NFS4ERR_NOT_ONLY_OP)
240 #define nfserr_wrong_cred cpu_to_be32(NFS4ERR_WRONG_CRED) 239 #define nfserr_wrong_cred cpu_to_be32(NFS4ERR_WRONG_CRED)
241 #define nfserr_wrong_type cpu_to_be32(NFS4ERR_WRONG_TYPE) 240 #define nfserr_wrong_type cpu_to_be32(NFS4ERR_WRONG_TYPE)
242 #define nfserr_dirdeleg_unavail cpu_to_be32(NFS4ERR_DIRDELEG_UNAVAIL) 241 #define nfserr_dirdeleg_unavail cpu_to_be32(NFS4ERR_DIRDELEG_UNAVAIL)
243 #define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG) 242 #define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG)
244 #define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT) 243 #define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT)
245 #define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED) 244 #define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED)
246 #define nfserr_partner_notsupp cpu_to_be32(NFS4ERR_PARTNER_NOTSUPP) 245 #define nfserr_partner_notsupp cpu_to_be32(NFS4ERR_PARTNER_NOTSUPP)
247 #define nfserr_partner_no_auth cpu_to_be32(NFS4ERR_PARTNER_NO_AUTH) 246 #define nfserr_partner_no_auth cpu_to_be32(NFS4ERR_PARTNER_NO_AUTH)
248 #define nfserr_metadata_notsupp cpu_to_be32(NFS4ERR_METADATA_NOTSUPP) 247 #define nfserr_metadata_notsupp cpu_to_be32(NFS4ERR_METADATA_NOTSUPP)
249 #define nfserr_offload_denied cpu_to_be32(NFS4ERR_OFFLOAD_DENIED) 248 #define nfserr_offload_denied cpu_to_be32(NFS4ERR_OFFLOAD_DENIED)
250 #define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS) 249 #define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS)
251 #define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL) 250 #define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL)
252 251
253 /* error codes for internal use */ 252 /* error codes for internal use */
254 /* if a request fails due to kmalloc failure, it gets dropped. 253 /* if a request fails due to kmalloc failure, it gets dropped.
255 * Client should resend eventually 254 * Client should resend eventually
256 */ 255 */
257 #define nfserr_dropit cpu_to_be32(30000) 256 #define nfserr_dropit cpu_to_be32(30000)
258 /* end-of-file indicator in readdir */ 257 /* end-of-file indicator in readdir */
259 #define nfserr_eof cpu_to_be32(30001) 258 #define nfserr_eof cpu_to_be32(30001)
260 /* replay detected */ 259 /* replay detected */
261 #define nfserr_replay_me cpu_to_be32(11001) 260 #define nfserr_replay_me cpu_to_be32(11001)
262 /* nfs41 replay detected */ 261 /* nfs41 replay detected */
263 #define nfserr_replay_cache cpu_to_be32(11002) 262 #define nfserr_replay_cache cpu_to_be32(11002)
264 263
265 /* Check for dir entries '.' and '..' */ 264 /* Check for dir entries '.' and '..' */
266 #define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.')) 265 #define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.'))
267 266
268 #ifdef CONFIG_NFSD_V4 267 #ifdef CONFIG_NFSD_V4
269 268
270 /* before processing a COMPOUND operation, we have to check that there 269 /* before processing a COMPOUND operation, we have to check that there
271 * is enough space in the buffer for XDR encode to succeed. otherwise, 270 * is enough space in the buffer for XDR encode to succeed. otherwise,
272 * we might process an operation with side effects, and be unable to 271 * we might process an operation with side effects, and be unable to
273 * tell the client that the operation succeeded. 272 * tell the client that the operation succeeded.
274 * 273 *
275 * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space 274 * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space
276 * needed to encode an "ordinary" _successful_ operation. (GETATTR, 275 * needed to encode an "ordinary" _successful_ operation. (GETATTR,
277 * READ, READDIR, and READLINK have their own buffer checks.) if we 276 * READ, READDIR, and READLINK have their own buffer checks.) if we
278 * fall below this level, we fail the next operation with NFS4ERR_RESOURCE. 277 * fall below this level, we fail the next operation with NFS4ERR_RESOURCE.
279 * 278 *
280 * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space 279 * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space
281 * needed to encode an operation which has failed with NFS4ERR_RESOURCE. 280 * needed to encode an operation which has failed with NFS4ERR_RESOURCE.
282 * care is taken to ensure that we never fall below this level for any 281 * care is taken to ensure that we never fall below this level for any
283 * reason. 282 * reason.
284 */ 283 */
285 #define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ 284 #define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */
286 #define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ 285 #define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */
287 286
288 #define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */ 287 #define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */
289 288
290 /* 289 /*
291 * The following attributes are currently not supported by the NFSv4 server: 290 * The following attributes are currently not supported by the NFSv4 server:
292 * ARCHIVE (deprecated anyway) 291 * ARCHIVE (deprecated anyway)
293 * HIDDEN (unlikely to be supported any time soon) 292 * HIDDEN (unlikely to be supported any time soon)
294 * MIMETYPE (unlikely to be supported any time soon) 293 * MIMETYPE (unlikely to be supported any time soon)
295 * QUOTA_* (will be supported in a forthcoming patch) 294 * QUOTA_* (will be supported in a forthcoming patch)
296 * SYSTEM (unlikely to be supported any time soon) 295 * SYSTEM (unlikely to be supported any time soon)
297 * TIME_BACKUP (unlikely to be supported any time soon) 296 * TIME_BACKUP (unlikely to be supported any time soon)
298 * TIME_CREATE (unlikely to be supported any time soon) 297 * TIME_CREATE (unlikely to be supported any time soon)
299 */ 298 */
300 #define NFSD4_SUPPORTED_ATTRS_WORD0 \ 299 #define NFSD4_SUPPORTED_ATTRS_WORD0 \
301 (FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \ 300 (FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \
302 | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \ 301 | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \
303 | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \ 302 | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \
304 | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \ 303 | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \
305 | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \ 304 | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \
306 | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \ 305 | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \
307 | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \ 306 | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \
308 | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS \ 307 | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS \
309 | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \ 308 | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \
310 | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL) 309 | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL)
311 310
312 #define NFSD4_SUPPORTED_ATTRS_WORD1 \ 311 #define NFSD4_SUPPORTED_ATTRS_WORD1 \
313 (FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \ 312 (FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \
314 | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \ 313 | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \
315 | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \ 314 | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \
316 | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \ 315 | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \
317 | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \ 316 | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \
318 | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID) 317 | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
319 318
320 #define NFSD4_SUPPORTED_ATTRS_WORD2 0 319 #define NFSD4_SUPPORTED_ATTRS_WORD2 0
321 320
322 #define NFSD4_1_SUPPORTED_ATTRS_WORD0 \ 321 #define NFSD4_1_SUPPORTED_ATTRS_WORD0 \
323 NFSD4_SUPPORTED_ATTRS_WORD0 322 NFSD4_SUPPORTED_ATTRS_WORD0
324 323
325 #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ 324 #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \
326 NFSD4_SUPPORTED_ATTRS_WORD1 325 NFSD4_SUPPORTED_ATTRS_WORD1
327 326
328 #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ 327 #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \
329 (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) 328 (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT)
330 329
331 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL 330 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
332 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ 331 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
333 (NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL) 332 (NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL)
334 #else 333 #else
335 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 0 334 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 0
336 #endif 335 #endif
337 336
338 static inline u32 nfsd_suppattrs0(u32 minorversion) 337 static inline u32 nfsd_suppattrs0(u32 minorversion)
339 { 338 {
340 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 339 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
341 : NFSD4_SUPPORTED_ATTRS_WORD0; 340 : NFSD4_SUPPORTED_ATTRS_WORD0;
342 } 341 }
343 342
344 static inline u32 nfsd_suppattrs1(u32 minorversion) 343 static inline u32 nfsd_suppattrs1(u32 minorversion)
345 { 344 {
346 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1 345 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1
347 : NFSD4_SUPPORTED_ATTRS_WORD1; 346 : NFSD4_SUPPORTED_ATTRS_WORD1;
348 } 347 }
349 348
350 static inline u32 nfsd_suppattrs2(u32 minorversion) 349 static inline u32 nfsd_suppattrs2(u32 minorversion)
351 { 350 {
352 switch (minorversion) { 351 switch (minorversion) {
353 default: return NFSD4_2_SUPPORTED_ATTRS_WORD2; 352 default: return NFSD4_2_SUPPORTED_ATTRS_WORD2;
354 case 1: return NFSD4_1_SUPPORTED_ATTRS_WORD2; 353 case 1: return NFSD4_1_SUPPORTED_ATTRS_WORD2;
355 case 0: return NFSD4_SUPPORTED_ATTRS_WORD2; 354 case 0: return NFSD4_SUPPORTED_ATTRS_WORD2;
356 } 355 }
357 } 356 }
358 357
359 /* These will return ERR_INVAL if specified in GETATTR or READDIR. */ 358 /* These will return ERR_INVAL if specified in GETATTR or READDIR. */
360 #define NFSD_WRITEONLY_ATTRS_WORD1 \ 359 #define NFSD_WRITEONLY_ATTRS_WORD1 \
361 (FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) 360 (FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
362 361
363 /* These are the only attrs allowed in CREATE/OPEN/SETATTR. */ 362 /* These are the only attrs allowed in CREATE/OPEN/SETATTR. */
364 #define NFSD_WRITEABLE_ATTRS_WORD0 \ 363 #define NFSD_WRITEABLE_ATTRS_WORD0 \
365 (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) 364 (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL)
366 #define NFSD_WRITEABLE_ATTRS_WORD1 \ 365 #define NFSD_WRITEABLE_ATTRS_WORD1 \
367 (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ 366 (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
368 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) 367 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
369 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL 368 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
370 #define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL 369 #define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL
371 #else 370 #else
372 #define NFSD_WRITEABLE_ATTRS_WORD2 0 371 #define NFSD_WRITEABLE_ATTRS_WORD2 0
373 #endif 372 #endif
374 373
375 #define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ 374 #define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
376 NFSD_WRITEABLE_ATTRS_WORD0 375 NFSD_WRITEABLE_ATTRS_WORD0
377 /* 376 /*
378 * we currently store the exclusive create verifier in the v_{a,m}time 377 * we currently store the exclusive create verifier in the v_{a,m}time
379 * attributes so the client can't set these at create time using EXCLUSIVE4_1 378 * attributes so the client can't set these at create time using EXCLUSIVE4_1
380 */ 379 */
381 #define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ 380 #define NFSD_SUPPATTR_EXCLCREAT_WORD1 \
382 (NFSD_WRITEABLE_ATTRS_WORD1 & \ 381 (NFSD_WRITEABLE_ATTRS_WORD1 & \
383 ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) 382 ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET))
384 #define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ 383 #define NFSD_SUPPATTR_EXCLCREAT_WORD2 \
385 NFSD_WRITEABLE_ATTRS_WORD2 384 NFSD_WRITEABLE_ATTRS_WORD2
386 385
387 extern int nfsd4_is_junction(struct dentry *dentry); 386 extern int nfsd4_is_junction(struct dentry *dentry);
388 extern int register_cld_notifier(void); 387 extern int register_cld_notifier(void);
389 extern void unregister_cld_notifier(void); 388 extern void unregister_cld_notifier(void);
390 #else /* CONFIG_NFSD_V4 */ 389 #else /* CONFIG_NFSD_V4 */
391 static inline int nfsd4_is_junction(struct dentry *dentry) 390 static inline int nfsd4_is_junction(struct dentry *dentry)
392 { 391 {
393 return 0; 392 return 0;
394 } 393 }
395 394
396 #define register_cld_notifier() 0 395 #define register_cld_notifier() 0
397 #define unregister_cld_notifier() do { } while(0) 396 #define unregister_cld_notifier() do { } while(0)
398 397
399 #endif /* CONFIG_NFSD_V4 */ 398 #endif /* CONFIG_NFSD_V4 */
400 399
401 #endif /* LINUX_NFSD_NFSD_H */ 400 #endif /* LINUX_NFSD_NFSD_H */
402 401
1 /* 1 /*
2 * Central processing for nfsd. 2 * Central processing for nfsd.
3 * 3 *
4 * Authors: Olaf Kirch (okir@monad.swb.de) 4 * Authors: Olaf Kirch (okir@monad.swb.de)
5 * 5 *
6 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9 #include <linux/sched.h> 9 #include <linux/sched.h>
10 #include <linux/freezer.h> 10 #include <linux/freezer.h>
11 #include <linux/module.h> 11 #include <linux/module.h>
12 #include <linux/fs_struct.h> 12 #include <linux/fs_struct.h>
13 #include <linux/swap.h> 13 #include <linux/swap.h>
14 14
15 #include <linux/sunrpc/stats.h> 15 #include <linux/sunrpc/stats.h>
16 #include <linux/sunrpc/svcsock.h> 16 #include <linux/sunrpc/svcsock.h>
17 #include <linux/lockd/bind.h> 17 #include <linux/lockd/bind.h>
18 #include <linux/nfsacl.h> 18 #include <linux/nfsacl.h>
19 #include <linux/seq_file.h> 19 #include <linux/seq_file.h>
20 #include <net/net_namespace.h> 20 #include <net/net_namespace.h>
21 #include "nfsd.h" 21 #include "nfsd.h"
22 #include "cache.h" 22 #include "cache.h"
23 #include "vfs.h" 23 #include "vfs.h"
24 #include "netns.h" 24 #include "netns.h"
25 25
26 #define NFSDDBG_FACILITY NFSDDBG_SVC 26 #define NFSDDBG_FACILITY NFSDDBG_SVC
27 27
28 extern struct svc_program nfsd_program; 28 extern struct svc_program nfsd_program;
29 static int nfsd(void *vrqstp); 29 static int nfsd(void *vrqstp);
30 30
31 /* 31 /*
32 * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and the members 32 * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and the members
33 * of the svc_serv struct. In particular, ->sv_nrthreads but also to some 33 * of the svc_serv struct. In particular, ->sv_nrthreads but also to some
34 * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt 34 * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt
35 * 35 *
36 * If (out side the lock) nn->nfsd_serv is non-NULL, then it must point to a 36 * If (out side the lock) nn->nfsd_serv is non-NULL, then it must point to a
37 * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number 37 * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number
38 * of nfsd threads must exist and each must listed in ->sp_all_threads in each 38 * of nfsd threads must exist and each must listed in ->sp_all_threads in each
39 * entry of ->sv_pools[]. 39 * entry of ->sv_pools[].
40 * 40 *
41 * Transitions of the thread count between zero and non-zero are of particular 41 * Transitions of the thread count between zero and non-zero are of particular
42 * interest since the svc_serv needs to be created and initialized at that 42 * interest since the svc_serv needs to be created and initialized at that
43 * point, or freed. 43 * point, or freed.
44 * 44 *
45 * Finally, the nfsd_mutex also protects some of the global variables that are 45 * Finally, the nfsd_mutex also protects some of the global variables that are
46 * accessed when nfsd starts and that are settable via the write_* routines in 46 * accessed when nfsd starts and that are settable via the write_* routines in
47 * nfsctl.c. In particular: 47 * nfsctl.c. In particular:
48 * 48 *
49 * user_recovery_dirname 49 * user_recovery_dirname
50 * user_lease_time 50 * user_lease_time
51 * nfsd_versions 51 * nfsd_versions
52 */ 52 */
53 DEFINE_MUTEX(nfsd_mutex); 53 DEFINE_MUTEX(nfsd_mutex);
54 54
55 /* 55 /*
56 * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used. 56 * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used.
57 * nfsd_drc_max_pages limits the total amount of memory available for 57 * nfsd_drc_max_pages limits the total amount of memory available for
58 * version 4.1 DRC caches. 58 * version 4.1 DRC caches.
59 * nfsd_drc_pages_used tracks the current version 4.1 DRC memory usage. 59 * nfsd_drc_pages_used tracks the current version 4.1 DRC memory usage.
60 */ 60 */
61 spinlock_t nfsd_drc_lock; 61 spinlock_t nfsd_drc_lock;
62 unsigned long nfsd_drc_max_mem; 62 unsigned long nfsd_drc_max_mem;
63 unsigned long nfsd_drc_mem_used; 63 unsigned long nfsd_drc_mem_used;
64 64
65 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 65 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
66 static struct svc_stat nfsd_acl_svcstats; 66 static struct svc_stat nfsd_acl_svcstats;
67 static struct svc_version * nfsd_acl_version[] = { 67 static struct svc_version * nfsd_acl_version[] = {
68 [2] = &nfsd_acl_version2, 68 [2] = &nfsd_acl_version2,
69 [3] = &nfsd_acl_version3, 69 [3] = &nfsd_acl_version3,
70 }; 70 };
71 71
72 #define NFSD_ACL_MINVERS 2 72 #define NFSD_ACL_MINVERS 2
73 #define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version) 73 #define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version)
74 static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS]; 74 static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS];
75 75
76 static struct svc_program nfsd_acl_program = { 76 static struct svc_program nfsd_acl_program = {
77 .pg_prog = NFS_ACL_PROGRAM, 77 .pg_prog = NFS_ACL_PROGRAM,
78 .pg_nvers = NFSD_ACL_NRVERS, 78 .pg_nvers = NFSD_ACL_NRVERS,
79 .pg_vers = nfsd_acl_versions, 79 .pg_vers = nfsd_acl_versions,
80 .pg_name = "nfsacl", 80 .pg_name = "nfsacl",
81 .pg_class = "nfsd", 81 .pg_class = "nfsd",
82 .pg_stats = &nfsd_acl_svcstats, 82 .pg_stats = &nfsd_acl_svcstats,
83 .pg_authenticate = &svc_set_client, 83 .pg_authenticate = &svc_set_client,
84 }; 84 };
85 85
86 static struct svc_stat nfsd_acl_svcstats = { 86 static struct svc_stat nfsd_acl_svcstats = {
87 .program = &nfsd_acl_program, 87 .program = &nfsd_acl_program,
88 }; 88 };
89 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ 89 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
90 90
91 static struct svc_version * nfsd_version[] = { 91 static struct svc_version * nfsd_version[] = {
92 [2] = &nfsd_version2, 92 [2] = &nfsd_version2,
93 #if defined(CONFIG_NFSD_V3) 93 #if defined(CONFIG_NFSD_V3)
94 [3] = &nfsd_version3, 94 [3] = &nfsd_version3,
95 #endif 95 #endif
96 #if defined(CONFIG_NFSD_V4) 96 #if defined(CONFIG_NFSD_V4)
97 [4] = &nfsd_version4, 97 [4] = &nfsd_version4,
98 #endif 98 #endif
99 }; 99 };
100 100
101 #define NFSD_MINVERS 2 101 #define NFSD_MINVERS 2
102 #define NFSD_NRVERS ARRAY_SIZE(nfsd_version) 102 #define NFSD_NRVERS ARRAY_SIZE(nfsd_version)
103 static struct svc_version *nfsd_versions[NFSD_NRVERS]; 103 static struct svc_version *nfsd_versions[NFSD_NRVERS];
104 104
105 struct svc_program nfsd_program = { 105 struct svc_program nfsd_program = {
106 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 106 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
107 .pg_next = &nfsd_acl_program, 107 .pg_next = &nfsd_acl_program,
108 #endif 108 #endif
109 .pg_prog = NFS_PROGRAM, /* program number */ 109 .pg_prog = NFS_PROGRAM, /* program number */
110 .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ 110 .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
111 .pg_vers = nfsd_versions, /* version table */ 111 .pg_vers = nfsd_versions, /* version table */
112 .pg_name = "nfsd", /* program name */ 112 .pg_name = "nfsd", /* program name */
113 .pg_class = "nfsd", /* authentication class */ 113 .pg_class = "nfsd", /* authentication class */
114 .pg_stats = &nfsd_svcstats, /* version table */ 114 .pg_stats = &nfsd_svcstats, /* version table */
115 .pg_authenticate = &svc_set_client, /* export authentication */ 115 .pg_authenticate = &svc_set_client, /* export authentication */
116 116
117 }; 117 };
118 118
119 u32 nfsd_supported_minorversion = 1; 119 static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
120 [0] = 1,
121 [1] = 1,
122 };
120 123
121 int nfsd_vers(int vers, enum vers_op change) 124 int nfsd_vers(int vers, enum vers_op change)
122 { 125 {
123 if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS) 126 if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
124 return 0; 127 return 0;
125 switch(change) { 128 switch(change) {
126 case NFSD_SET: 129 case NFSD_SET:
127 nfsd_versions[vers] = nfsd_version[vers]; 130 nfsd_versions[vers] = nfsd_version[vers];
128 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 131 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
129 if (vers < NFSD_ACL_NRVERS) 132 if (vers < NFSD_ACL_NRVERS)
130 nfsd_acl_versions[vers] = nfsd_acl_version[vers]; 133 nfsd_acl_versions[vers] = nfsd_acl_version[vers];
131 #endif 134 #endif
132 break; 135 break;
133 case NFSD_CLEAR: 136 case NFSD_CLEAR:
134 nfsd_versions[vers] = NULL; 137 nfsd_versions[vers] = NULL;
135 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 138 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
136 if (vers < NFSD_ACL_NRVERS) 139 if (vers < NFSD_ACL_NRVERS)
137 nfsd_acl_versions[vers] = NULL; 140 nfsd_acl_versions[vers] = NULL;
138 #endif 141 #endif
139 break; 142 break;
140 case NFSD_TEST: 143 case NFSD_TEST:
141 return nfsd_versions[vers] != NULL; 144 return nfsd_versions[vers] != NULL;
142 case NFSD_AVAIL: 145 case NFSD_AVAIL:
143 return nfsd_version[vers] != NULL; 146 return nfsd_version[vers] != NULL;
144 } 147 }
145 return 0; 148 return 0;
146 } 149 }
147 150
148 int nfsd_minorversion(u32 minorversion, enum vers_op change) 151 int nfsd_minorversion(u32 minorversion, enum vers_op change)
149 { 152 {
150 if (minorversion > NFSD_SUPPORTED_MINOR_VERSION) 153 if (minorversion > NFSD_SUPPORTED_MINOR_VERSION)
151 return -1; 154 return -1;
152 switch(change) { 155 switch(change) {
153 case NFSD_SET: 156 case NFSD_SET:
154 nfsd_supported_minorversion = minorversion; 157 nfsd_supported_minorversions[minorversion] = true;
155 break; 158 break;
156 case NFSD_CLEAR: 159 case NFSD_CLEAR:
157 if (minorversion == 0) 160 nfsd_supported_minorversions[minorversion] = false;
158 return -1;
159 nfsd_supported_minorversion = minorversion - 1;
160 break; 161 break;
161 case NFSD_TEST: 162 case NFSD_TEST:
162 return minorversion <= nfsd_supported_minorversion; 163 return nfsd_supported_minorversions[minorversion];
163 case NFSD_AVAIL: 164 case NFSD_AVAIL:
164 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION; 165 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
165 } 166 }
166 return 0; 167 return 0;
167 } 168 }
168 169
169 /* 170 /*
170 * Maximum number of nfsd processes 171 * Maximum number of nfsd processes
171 */ 172 */
172 #define NFSD_MAXSERVS 8192 173 #define NFSD_MAXSERVS 8192
173 174
174 int nfsd_nrthreads(struct net *net) 175 int nfsd_nrthreads(struct net *net)
175 { 176 {
176 int rv = 0; 177 int rv = 0;
177 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 178 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
178 179
179 mutex_lock(&nfsd_mutex); 180 mutex_lock(&nfsd_mutex);
180 if (nn->nfsd_serv) 181 if (nn->nfsd_serv)
181 rv = nn->nfsd_serv->sv_nrthreads; 182 rv = nn->nfsd_serv->sv_nrthreads;
182 mutex_unlock(&nfsd_mutex); 183 mutex_unlock(&nfsd_mutex);
183 return rv; 184 return rv;
184 } 185 }
185 186
186 static int nfsd_init_socks(struct net *net) 187 static int nfsd_init_socks(struct net *net)
187 { 188 {
188 int error; 189 int error;
189 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 190 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
190 191
191 if (!list_empty(&nn->nfsd_serv->sv_permsocks)) 192 if (!list_empty(&nn->nfsd_serv->sv_permsocks))
192 return 0; 193 return 0;
193 194
194 error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT, 195 error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT,
195 SVC_SOCK_DEFAULTS); 196 SVC_SOCK_DEFAULTS);
196 if (error < 0) 197 if (error < 0)
197 return error; 198 return error;
198 199
199 error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT, 200 error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT,
200 SVC_SOCK_DEFAULTS); 201 SVC_SOCK_DEFAULTS);
201 if (error < 0) 202 if (error < 0)
202 return error; 203 return error;
203 204
204 return 0; 205 return 0;
205 } 206 }
206 207
207 static int nfsd_users = 0; 208 static int nfsd_users = 0;
208 209
209 static int nfsd_startup_generic(int nrservs) 210 static int nfsd_startup_generic(int nrservs)
210 { 211 {
211 int ret; 212 int ret;
212 213
213 if (nfsd_users++) 214 if (nfsd_users++)
214 return 0; 215 return 0;
215 216
216 /* 217 /*
217 * Readahead param cache - will no-op if it already exists. 218 * Readahead param cache - will no-op if it already exists.
218 * (Note therefore results will be suboptimal if number of 219 * (Note therefore results will be suboptimal if number of
219 * threads is modified after nfsd start.) 220 * threads is modified after nfsd start.)
220 */ 221 */
221 ret = nfsd_racache_init(2*nrservs); 222 ret = nfsd_racache_init(2*nrservs);
222 if (ret) 223 if (ret)
223 return ret; 224 return ret;
224 ret = nfs4_state_start(); 225 ret = nfs4_state_start();
225 if (ret) 226 if (ret)
226 goto out_racache; 227 goto out_racache;
227 return 0; 228 return 0;
228 229
229 out_racache: 230 out_racache:
230 nfsd_racache_shutdown(); 231 nfsd_racache_shutdown();
231 return ret; 232 return ret;
232 } 233 }
233 234
234 static void nfsd_shutdown_generic(void) 235 static void nfsd_shutdown_generic(void)
235 { 236 {
236 if (--nfsd_users) 237 if (--nfsd_users)
237 return; 238 return;
238 239
239 nfs4_state_shutdown(); 240 nfs4_state_shutdown();
240 nfsd_racache_shutdown(); 241 nfsd_racache_shutdown();
241 } 242 }
242 243
243 static int nfsd_startup_net(int nrservs, struct net *net) 244 static int nfsd_startup_net(int nrservs, struct net *net)
244 { 245 {
245 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 246 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
246 int ret; 247 int ret;
247 248
248 if (nn->nfsd_net_up) 249 if (nn->nfsd_net_up)
249 return 0; 250 return 0;
250 251
251 ret = nfsd_startup_generic(nrservs); 252 ret = nfsd_startup_generic(nrservs);
252 if (ret) 253 if (ret)
253 return ret; 254 return ret;
254 ret = nfsd_init_socks(net); 255 ret = nfsd_init_socks(net);
255 if (ret) 256 if (ret)
256 goto out_socks; 257 goto out_socks;
257 ret = lockd_up(net); 258 ret = lockd_up(net);
258 if (ret) 259 if (ret)
259 goto out_socks; 260 goto out_socks;
260 ret = nfs4_state_start_net(net); 261 ret = nfs4_state_start_net(net);
261 if (ret) 262 if (ret)
262 goto out_lockd; 263 goto out_lockd;
263 264
264 nn->nfsd_net_up = true; 265 nn->nfsd_net_up = true;
265 return 0; 266 return 0;
266 267
267 out_lockd: 268 out_lockd:
268 lockd_down(net); 269 lockd_down(net);
269 out_socks: 270 out_socks:
270 nfsd_shutdown_generic(); 271 nfsd_shutdown_generic();
271 return ret; 272 return ret;
272 } 273 }
273 274
274 static void nfsd_shutdown_net(struct net *net) 275 static void nfsd_shutdown_net(struct net *net)
275 { 276 {
276 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 277 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
277 278
278 nfs4_state_shutdown_net(net); 279 nfs4_state_shutdown_net(net);
279 lockd_down(net); 280 lockd_down(net);
280 nn->nfsd_net_up = false; 281 nn->nfsd_net_up = false;
281 nfsd_shutdown_generic(); 282 nfsd_shutdown_generic();
282 } 283 }
283 284
284 static void nfsd_last_thread(struct svc_serv *serv, struct net *net) 285 static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
285 { 286 {
286 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 287 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
287 288
288 /* 289 /*
289 * write_ports can create the server without actually starting 290 * write_ports can create the server without actually starting
290 * any threads--if we get shut down before any threads are 291 * any threads--if we get shut down before any threads are
291 * started, then nfsd_last_thread will be run before any of this 292 * started, then nfsd_last_thread will be run before any of this
292 * other initialization has been done. 293 * other initialization has been done.
293 */ 294 */
294 if (!nn->nfsd_net_up) 295 if (!nn->nfsd_net_up)
295 return; 296 return;
296 nfsd_shutdown_net(net); 297 nfsd_shutdown_net(net);
297 298
298 svc_rpcb_cleanup(serv, net); 299 svc_rpcb_cleanup(serv, net);
299 300
300 printk(KERN_WARNING "nfsd: last server has exited, flushing export " 301 printk(KERN_WARNING "nfsd: last server has exited, flushing export "
301 "cache\n"); 302 "cache\n");
302 nfsd_export_flush(net); 303 nfsd_export_flush(net);
303 } 304 }
304 305
305 void nfsd_reset_versions(void) 306 void nfsd_reset_versions(void)
306 { 307 {
307 int found_one = 0; 308 int found_one = 0;
308 int i; 309 int i;
309 310
310 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { 311 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
311 if (nfsd_program.pg_vers[i]) 312 if (nfsd_program.pg_vers[i])
312 found_one = 1; 313 found_one = 1;
313 } 314 }
314 315
315 if (!found_one) { 316 if (!found_one) {
316 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) 317 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
317 nfsd_program.pg_vers[i] = nfsd_version[i]; 318 nfsd_program.pg_vers[i] = nfsd_version[i];
318 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 319 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
319 for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) 320 for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
320 nfsd_acl_program.pg_vers[i] = 321 nfsd_acl_program.pg_vers[i] =
321 nfsd_acl_version[i]; 322 nfsd_acl_version[i];
322 #endif 323 #endif
323 } 324 }
324 } 325 }
325 326
326 /* 327 /*
327 * Each session guarantees a negotiated per slot memory cache for replies 328 * Each session guarantees a negotiated per slot memory cache for replies
328 * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated 329 * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated
329 * NFSv4.1 server might want to use more memory for a DRC than a machine 330 * NFSv4.1 server might want to use more memory for a DRC than a machine
330 * with mutiple services. 331 * with mutiple services.
331 * 332 *
332 * Impose a hard limit on the number of pages for the DRC which varies 333 * Impose a hard limit on the number of pages for the DRC which varies
333 * according to the machines free pages. This is of course only a default. 334 * according to the machines free pages. This is of course only a default.
334 * 335 *
335 * For now this is a #defined shift which could be under admin control 336 * For now this is a #defined shift which could be under admin control
336 * in the future. 337 * in the future.
337 */ 338 */
338 static void set_max_drc(void) 339 static void set_max_drc(void)
339 { 340 {
340 #define NFSD_DRC_SIZE_SHIFT 10 341 #define NFSD_DRC_SIZE_SHIFT 10
341 nfsd_drc_max_mem = (nr_free_buffer_pages() 342 nfsd_drc_max_mem = (nr_free_buffer_pages()
342 >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE; 343 >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE;
343 nfsd_drc_mem_used = 0; 344 nfsd_drc_mem_used = 0;
344 spin_lock_init(&nfsd_drc_lock); 345 spin_lock_init(&nfsd_drc_lock);
345 dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem); 346 dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem);
346 } 347 }
347 348
348 static int nfsd_get_default_max_blksize(void) 349 static int nfsd_get_default_max_blksize(void)
349 { 350 {
350 struct sysinfo i; 351 struct sysinfo i;
351 unsigned long long target; 352 unsigned long long target;
352 unsigned long ret; 353 unsigned long ret;
353 354
354 si_meminfo(&i); 355 si_meminfo(&i);
355 target = (i.totalram - i.totalhigh) << PAGE_SHIFT; 356 target = (i.totalram - i.totalhigh) << PAGE_SHIFT;
356 /* 357 /*
357 * Aim for 1/4096 of memory per thread This gives 1MB on 4Gig 358 * Aim for 1/4096 of memory per thread This gives 1MB on 4Gig
358 * machines, but only uses 32K on 128M machines. Bottom out at 359 * machines, but only uses 32K on 128M machines. Bottom out at
359 * 8K on 32M and smaller. Of course, this is only a default. 360 * 8K on 32M and smaller. Of course, this is only a default.
360 */ 361 */
361 target >>= 12; 362 target >>= 12;
362 363
363 ret = NFSSVC_MAXBLKSIZE; 364 ret = NFSSVC_MAXBLKSIZE;
364 while (ret > target && ret >= 8*1024*2) 365 while (ret > target && ret >= 8*1024*2)
365 ret /= 2; 366 ret /= 2;
366 return ret; 367 return ret;
367 } 368 }
368 369
369 int nfsd_create_serv(struct net *net) 370 int nfsd_create_serv(struct net *net)
370 { 371 {
371 int error; 372 int error;
372 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 373 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
373 374
374 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 375 WARN_ON(!mutex_is_locked(&nfsd_mutex));
375 if (nn->nfsd_serv) { 376 if (nn->nfsd_serv) {
376 svc_get(nn->nfsd_serv); 377 svc_get(nn->nfsd_serv);
377 return 0; 378 return 0;
378 } 379 }
379 if (nfsd_max_blksize == 0) 380 if (nfsd_max_blksize == 0)
380 nfsd_max_blksize = nfsd_get_default_max_blksize(); 381 nfsd_max_blksize = nfsd_get_default_max_blksize();
381 nfsd_reset_versions(); 382 nfsd_reset_versions();
382 nn->nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, 383 nn->nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
383 nfsd_last_thread, nfsd, THIS_MODULE); 384 nfsd_last_thread, nfsd, THIS_MODULE);
384 if (nn->nfsd_serv == NULL) 385 if (nn->nfsd_serv == NULL)
385 return -ENOMEM; 386 return -ENOMEM;
386 387
387 error = svc_bind(nn->nfsd_serv, net); 388 error = svc_bind(nn->nfsd_serv, net);
388 if (error < 0) { 389 if (error < 0) {
389 svc_destroy(nn->nfsd_serv); 390 svc_destroy(nn->nfsd_serv);
390 return error; 391 return error;
391 } 392 }
392 393
393 set_max_drc(); 394 set_max_drc();
394 do_gettimeofday(&nn->nfssvc_boot); /* record boot time */ 395 do_gettimeofday(&nn->nfssvc_boot); /* record boot time */
395 return 0; 396 return 0;
396 } 397 }
397 398
398 int nfsd_nrpools(struct net *net) 399 int nfsd_nrpools(struct net *net)
399 { 400 {
400 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 401 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
401 402
402 if (nn->nfsd_serv == NULL) 403 if (nn->nfsd_serv == NULL)
403 return 0; 404 return 0;
404 else 405 else
405 return nn->nfsd_serv->sv_nrpools; 406 return nn->nfsd_serv->sv_nrpools;
406 } 407 }
407 408
408 int nfsd_get_nrthreads(int n, int *nthreads, struct net *net) 409 int nfsd_get_nrthreads(int n, int *nthreads, struct net *net)
409 { 410 {
410 int i = 0; 411 int i = 0;
411 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 412 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
412 413
413 if (nn->nfsd_serv != NULL) { 414 if (nn->nfsd_serv != NULL) {
414 for (i = 0; i < nn->nfsd_serv->sv_nrpools && i < n; i++) 415 for (i = 0; i < nn->nfsd_serv->sv_nrpools && i < n; i++)
415 nthreads[i] = nn->nfsd_serv->sv_pools[i].sp_nrthreads; 416 nthreads[i] = nn->nfsd_serv->sv_pools[i].sp_nrthreads;
416 } 417 }
417 418
418 return 0; 419 return 0;
419 } 420 }
420 421
421 void nfsd_destroy(struct net *net) 422 void nfsd_destroy(struct net *net)
422 { 423 {
423 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 424 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
424 int destroy = (nn->nfsd_serv->sv_nrthreads == 1); 425 int destroy = (nn->nfsd_serv->sv_nrthreads == 1);
425 426
426 if (destroy) 427 if (destroy)
427 svc_shutdown_net(nn->nfsd_serv, net); 428 svc_shutdown_net(nn->nfsd_serv, net);
428 svc_destroy(nn->nfsd_serv); 429 svc_destroy(nn->nfsd_serv);
429 if (destroy) 430 if (destroy)
430 nn->nfsd_serv = NULL; 431 nn->nfsd_serv = NULL;
431 } 432 }
432 433
433 int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) 434 int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
434 { 435 {
435 int i = 0; 436 int i = 0;
436 int tot = 0; 437 int tot = 0;
437 int err = 0; 438 int err = 0;
438 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 439 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
439 440
440 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 441 WARN_ON(!mutex_is_locked(&nfsd_mutex));
441 442
442 if (nn->nfsd_serv == NULL || n <= 0) 443 if (nn->nfsd_serv == NULL || n <= 0)
443 return 0; 444 return 0;
444 445
445 if (n > nn->nfsd_serv->sv_nrpools) 446 if (n > nn->nfsd_serv->sv_nrpools)
446 n = nn->nfsd_serv->sv_nrpools; 447 n = nn->nfsd_serv->sv_nrpools;
447 448
448 /* enforce a global maximum number of threads */ 449 /* enforce a global maximum number of threads */
449 tot = 0; 450 tot = 0;
450 for (i = 0; i < n; i++) { 451 for (i = 0; i < n; i++) {
451 if (nthreads[i] > NFSD_MAXSERVS) 452 if (nthreads[i] > NFSD_MAXSERVS)
452 nthreads[i] = NFSD_MAXSERVS; 453 nthreads[i] = NFSD_MAXSERVS;
453 tot += nthreads[i]; 454 tot += nthreads[i];
454 } 455 }
455 if (tot > NFSD_MAXSERVS) { 456 if (tot > NFSD_MAXSERVS) {
456 /* total too large: scale down requested numbers */ 457 /* total too large: scale down requested numbers */
457 for (i = 0; i < n && tot > 0; i++) { 458 for (i = 0; i < n && tot > 0; i++) {
458 int new = nthreads[i] * NFSD_MAXSERVS / tot; 459 int new = nthreads[i] * NFSD_MAXSERVS / tot;
459 tot -= (nthreads[i] - new); 460 tot -= (nthreads[i] - new);
460 nthreads[i] = new; 461 nthreads[i] = new;
461 } 462 }
462 for (i = 0; i < n && tot > 0; i++) { 463 for (i = 0; i < n && tot > 0; i++) {
463 nthreads[i]--; 464 nthreads[i]--;
464 tot--; 465 tot--;
465 } 466 }
466 } 467 }
467 468
468 /* 469 /*
469 * There must always be a thread in pool 0; the admin 470 * There must always be a thread in pool 0; the admin
470 * can't shut down NFS completely using pool_threads. 471 * can't shut down NFS completely using pool_threads.
471 */ 472 */
472 if (nthreads[0] == 0) 473 if (nthreads[0] == 0)
473 nthreads[0] = 1; 474 nthreads[0] = 1;
474 475
475 /* apply the new numbers */ 476 /* apply the new numbers */
476 svc_get(nn->nfsd_serv); 477 svc_get(nn->nfsd_serv);
477 for (i = 0; i < n; i++) { 478 for (i = 0; i < n; i++) {
478 err = svc_set_num_threads(nn->nfsd_serv, &nn->nfsd_serv->sv_pools[i], 479 err = svc_set_num_threads(nn->nfsd_serv, &nn->nfsd_serv->sv_pools[i],
479 nthreads[i]); 480 nthreads[i]);
480 if (err) 481 if (err)
481 break; 482 break;
482 } 483 }
483 nfsd_destroy(net); 484 nfsd_destroy(net);
484 return err; 485 return err;
485 } 486 }
486 487
487 /* 488 /*
488 * Adjust the number of threads and return the new number of threads. 489 * Adjust the number of threads and return the new number of threads.
489 * This is also the function that starts the server if necessary, if 490 * This is also the function that starts the server if necessary, if
490 * this is the first time nrservs is nonzero. 491 * this is the first time nrservs is nonzero.
491 */ 492 */
492 int 493 int
493 nfsd_svc(int nrservs, struct net *net) 494 nfsd_svc(int nrservs, struct net *net)
494 { 495 {
495 int error; 496 int error;
496 bool nfsd_up_before; 497 bool nfsd_up_before;
497 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 498 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
498 499
499 mutex_lock(&nfsd_mutex); 500 mutex_lock(&nfsd_mutex);
500 dprintk("nfsd: creating service\n"); 501 dprintk("nfsd: creating service\n");
501 if (nrservs <= 0) 502 if (nrservs <= 0)
502 nrservs = 0; 503 nrservs = 0;
503 if (nrservs > NFSD_MAXSERVS) 504 if (nrservs > NFSD_MAXSERVS)
504 nrservs = NFSD_MAXSERVS; 505 nrservs = NFSD_MAXSERVS;
505 error = 0; 506 error = 0;
506 if (nrservs == 0 && nn->nfsd_serv == NULL) 507 if (nrservs == 0 && nn->nfsd_serv == NULL)
507 goto out; 508 goto out;
508 509
509 error = nfsd_create_serv(net); 510 error = nfsd_create_serv(net);
510 if (error) 511 if (error)
511 goto out; 512 goto out;
512 513
513 nfsd_up_before = nn->nfsd_net_up; 514 nfsd_up_before = nn->nfsd_net_up;
514 515
515 error = nfsd_startup_net(nrservs, net); 516 error = nfsd_startup_net(nrservs, net);
516 if (error) 517 if (error)
517 goto out_destroy; 518 goto out_destroy;
518 error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs); 519 error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs);
519 if (error) 520 if (error)
520 goto out_shutdown; 521 goto out_shutdown;
521 /* We are holding a reference to nn->nfsd_serv which 522 /* We are holding a reference to nn->nfsd_serv which
522 * we don't want to count in the return value, 523 * we don't want to count in the return value,
523 * so subtract 1 524 * so subtract 1
524 */ 525 */
525 error = nn->nfsd_serv->sv_nrthreads - 1; 526 error = nn->nfsd_serv->sv_nrthreads - 1;
526 out_shutdown: 527 out_shutdown:
527 if (error < 0 && !nfsd_up_before) 528 if (error < 0 && !nfsd_up_before)
528 nfsd_shutdown_net(net); 529 nfsd_shutdown_net(net);
529 out_destroy: 530 out_destroy:
530 nfsd_destroy(net); /* Release server */ 531 nfsd_destroy(net); /* Release server */
531 out: 532 out:
532 mutex_unlock(&nfsd_mutex); 533 mutex_unlock(&nfsd_mutex);
533 return error; 534 return error;
534 } 535 }
535 536
536 537
537 /* 538 /*
538 * This is the NFS server kernel thread 539 * This is the NFS server kernel thread
539 */ 540 */
540 static int 541 static int
541 nfsd(void *vrqstp) 542 nfsd(void *vrqstp)
542 { 543 {
543 struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp; 544 struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
544 struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list); 545 struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
545 struct net *net = perm_sock->xpt_net; 546 struct net *net = perm_sock->xpt_net;
546 int err; 547 int err;
547 548
548 /* Lock module and set up kernel thread */ 549 /* Lock module and set up kernel thread */
549 mutex_lock(&nfsd_mutex); 550 mutex_lock(&nfsd_mutex);
550 551
551 /* At this point, the thread shares current->fs 552 /* At this point, the thread shares current->fs
552 * with the init process. We need to create files with a 553 * with the init process. We need to create files with a
553 * umask of 0 instead of init's umask. */ 554 * umask of 0 instead of init's umask. */
554 if (unshare_fs_struct() < 0) { 555 if (unshare_fs_struct() < 0) {
555 printk("Unable to start nfsd thread: out of memory\n"); 556 printk("Unable to start nfsd thread: out of memory\n");
556 goto out; 557 goto out;
557 } 558 }
558 559
559 current->fs->umask = 0; 560 current->fs->umask = 0;
560 561
561 /* 562 /*
562 * thread is spawned with all signals set to SIG_IGN, re-enable 563 * thread is spawned with all signals set to SIG_IGN, re-enable
563 * the ones that will bring down the thread 564 * the ones that will bring down the thread
564 */ 565 */
565 allow_signal(SIGKILL); 566 allow_signal(SIGKILL);
566 allow_signal(SIGHUP); 567 allow_signal(SIGHUP);
567 allow_signal(SIGINT); 568 allow_signal(SIGINT);
568 allow_signal(SIGQUIT); 569 allow_signal(SIGQUIT);
569 570
570 nfsdstats.th_cnt++; 571 nfsdstats.th_cnt++;
571 mutex_unlock(&nfsd_mutex); 572 mutex_unlock(&nfsd_mutex);
572 573
573 /* 574 /*
574 * We want less throttling in balance_dirty_pages() so that nfs to 575 * We want less throttling in balance_dirty_pages() so that nfs to
575 * localhost doesn't cause nfsd to lock up due to all the client's 576 * localhost doesn't cause nfsd to lock up due to all the client's
576 * dirty pages. 577 * dirty pages.
577 */ 578 */
578 current->flags |= PF_LESS_THROTTLE; 579 current->flags |= PF_LESS_THROTTLE;
579 set_freezable(); 580 set_freezable();
580 581
581 /* 582 /*
582 * The main request loop 583 * The main request loop
583 */ 584 */
584 for (;;) { 585 for (;;) {
585 /* 586 /*
586 * Find a socket with data available and call its 587 * Find a socket with data available and call its
587 * recvfrom routine. 588 * recvfrom routine.
588 */ 589 */
589 while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN) 590 while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
590 ; 591 ;
591 if (err == -EINTR) 592 if (err == -EINTR)
592 break; 593 break;
593 validate_process_creds(); 594 validate_process_creds();
594 svc_process(rqstp); 595 svc_process(rqstp);
595 validate_process_creds(); 596 validate_process_creds();
596 } 597 }
597 598
598 /* Clear signals before calling svc_exit_thread() */ 599 /* Clear signals before calling svc_exit_thread() */
599 flush_signals(current); 600 flush_signals(current);
600 601
601 mutex_lock(&nfsd_mutex); 602 mutex_lock(&nfsd_mutex);
602 nfsdstats.th_cnt --; 603 nfsdstats.th_cnt --;
603 604
604 out: 605 out:
605 rqstp->rq_server = NULL; 606 rqstp->rq_server = NULL;
606 607
607 /* Release the thread */ 608 /* Release the thread */
608 svc_exit_thread(rqstp); 609 svc_exit_thread(rqstp);
609 610
610 nfsd_destroy(net); 611 nfsd_destroy(net);
611 612
612 /* Release module */ 613 /* Release module */
613 mutex_unlock(&nfsd_mutex); 614 mutex_unlock(&nfsd_mutex);
614 module_put_and_exit(0); 615 module_put_and_exit(0);
615 return 0; 616 return 0;
616 } 617 }
617 618
618 static __be32 map_new_errors(u32 vers, __be32 nfserr) 619 static __be32 map_new_errors(u32 vers, __be32 nfserr)
619 { 620 {
620 if (nfserr == nfserr_jukebox && vers == 2) 621 if (nfserr == nfserr_jukebox && vers == 2)
621 return nfserr_dropit; 622 return nfserr_dropit;
622 if (nfserr == nfserr_wrongsec && vers < 4) 623 if (nfserr == nfserr_wrongsec && vers < 4)
623 return nfserr_acces; 624 return nfserr_acces;
624 return nfserr; 625 return nfserr;
625 } 626 }
626 627
627 int 628 int
628 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) 629 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
629 { 630 {
630 struct svc_procedure *proc; 631 struct svc_procedure *proc;
631 kxdrproc_t xdr; 632 kxdrproc_t xdr;
632 __be32 nfserr; 633 __be32 nfserr;
633 __be32 *nfserrp; 634 __be32 *nfserrp;
634 635
635 dprintk("nfsd_dispatch: vers %d proc %d\n", 636 dprintk("nfsd_dispatch: vers %d proc %d\n",
636 rqstp->rq_vers, rqstp->rq_proc); 637 rqstp->rq_vers, rqstp->rq_proc);
637 proc = rqstp->rq_procinfo; 638 proc = rqstp->rq_procinfo;
638 639
639 /* 640 /*
640 * Give the xdr decoder a chance to change this if it wants 641 * Give the xdr decoder a chance to change this if it wants
641 * (necessary in the NFSv4.0 compound case) 642 * (necessary in the NFSv4.0 compound case)
642 */ 643 */
643 rqstp->rq_cachetype = proc->pc_cachetype; 644 rqstp->rq_cachetype = proc->pc_cachetype;
644 /* Decode arguments */ 645 /* Decode arguments */
645 xdr = proc->pc_decode; 646 xdr = proc->pc_decode;
646 if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base, 647 if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base,
647 rqstp->rq_argp)) { 648 rqstp->rq_argp)) {
648 dprintk("nfsd: failed to decode arguments!\n"); 649 dprintk("nfsd: failed to decode arguments!\n");
649 *statp = rpc_garbage_args; 650 *statp = rpc_garbage_args;
650 return 1; 651 return 1;
651 } 652 }
652 653
653 /* Check whether we have this call in the cache. */ 654 /* Check whether we have this call in the cache. */
654 switch (nfsd_cache_lookup(rqstp)) { 655 switch (nfsd_cache_lookup(rqstp)) {
655 case RC_DROPIT: 656 case RC_DROPIT:
656 return 0; 657 return 0;
657 case RC_REPLY: 658 case RC_REPLY:
658 return 1; 659 return 1;
659 case RC_DOIT:; 660 case RC_DOIT:;
660 /* do it */ 661 /* do it */
661 } 662 }
662 663
663 /* need to grab the location to store the status, as 664 /* need to grab the location to store the status, as
664 * nfsv4 does some encoding while processing 665 * nfsv4 does some encoding while processing
665 */ 666 */
666 nfserrp = rqstp->rq_res.head[0].iov_base 667 nfserrp = rqstp->rq_res.head[0].iov_base
667 + rqstp->rq_res.head[0].iov_len; 668 + rqstp->rq_res.head[0].iov_len;
668 rqstp->rq_res.head[0].iov_len += sizeof(__be32); 669 rqstp->rq_res.head[0].iov_len += sizeof(__be32);
669 670
670 /* Now call the procedure handler, and encode NFS status. */ 671 /* Now call the procedure handler, and encode NFS status. */
671 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); 672 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
672 nfserr = map_new_errors(rqstp->rq_vers, nfserr); 673 nfserr = map_new_errors(rqstp->rq_vers, nfserr);
673 if (nfserr == nfserr_dropit || rqstp->rq_dropme) { 674 if (nfserr == nfserr_dropit || rqstp->rq_dropme) {
674 dprintk("nfsd: Dropping request; may be revisited later\n"); 675 dprintk("nfsd: Dropping request; may be revisited later\n");
675 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 676 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
676 return 0; 677 return 0;
677 } 678 }
678 679
679 if (rqstp->rq_proc != 0) 680 if (rqstp->rq_proc != 0)
680 *nfserrp++ = nfserr; 681 *nfserrp++ = nfserr;
681 682
682 /* Encode result. 683 /* Encode result.
683 * For NFSv2, additional info is never returned in case of an error. 684 * For NFSv2, additional info is never returned in case of an error.
684 */ 685 */
685 if (!(nfserr && rqstp->rq_vers == 2)) { 686 if (!(nfserr && rqstp->rq_vers == 2)) {
686 xdr = proc->pc_encode; 687 xdr = proc->pc_encode;
687 if (xdr && !xdr(rqstp, nfserrp, 688 if (xdr && !xdr(rqstp, nfserrp,
688 rqstp->rq_resp)) { 689 rqstp->rq_resp)) {
689 /* Failed to encode result. Release cache entry */ 690 /* Failed to encode result. Release cache entry */
690 dprintk("nfsd: failed to encode result!\n"); 691 dprintk("nfsd: failed to encode result!\n");
691 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 692 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
692 *statp = rpc_system_err; 693 *statp = rpc_system_err;
693 return 1; 694 return 1;
694 } 695 }
695 } 696 }
696 697
697 /* Store reply in cache. */ 698 /* Store reply in cache. */
698 nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1); 699 nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
699 return 1; 700 return 1;
700 } 701 }
701 702
702 int nfsd_pool_stats_open(struct inode *inode, struct file *file) 703 int nfsd_pool_stats_open(struct inode *inode, struct file *file)
703 { 704 {
704 int ret; 705 int ret;
705 struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id); 706 struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
706 707
707 mutex_lock(&nfsd_mutex); 708 mutex_lock(&nfsd_mutex);
708 if (nn->nfsd_serv == NULL) { 709 if (nn->nfsd_serv == NULL) {
709 mutex_unlock(&nfsd_mutex); 710 mutex_unlock(&nfsd_mutex);
710 return -ENODEV; 711 return -ENODEV;
711 } 712 }
712 /* bump up the psudo refcount while traversing */ 713 /* bump up the psudo refcount while traversing */
713 svc_get(nn->nfsd_serv); 714 svc_get(nn->nfsd_serv);
714 ret = svc_pool_stats_open(nn->nfsd_serv, file); 715 ret = svc_pool_stats_open(nn->nfsd_serv, file);
715 mutex_unlock(&nfsd_mutex); 716 mutex_unlock(&nfsd_mutex);
716 return ret; 717 return ret;
717 } 718 }
718 719
719 int nfsd_pool_stats_release(struct inode *inode, struct file *file) 720 int nfsd_pool_stats_release(struct inode *inode, struct file *file)
720 { 721 {
721 int ret = seq_release(inode, file); 722 int ret = seq_release(inode, file);
722 struct net *net = inode->i_sb->s_fs_info; 723 struct net *net = inode->i_sb->s_fs_info;
723 724
724 mutex_lock(&nfsd_mutex); 725 mutex_lock(&nfsd_mutex);
725 /* this function really, really should have been called svc_put() */ 726 /* this function really, really should have been called svc_put() */
726 nfsd_destroy(net); 727 nfsd_destroy(net);
727 mutex_unlock(&nfsd_mutex); 728 mutex_unlock(&nfsd_mutex);
728 return ret; 729 return ret;