Commit 57b7b43b403136dc18d067909050e8677f97aeed

Authored by J. Bruce Fields
1 parent bc1b542be9

nfsd4: int/__be32 fixes

In each of these cases there's a simple unambiguous correct choice, and
no actual bug.

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

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

1 /* 1 /*
2 * Copyright (c) 2001 The Regents of the University of Michigan. 2 * Copyright (c) 2001 The Regents of the University of Michigan.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Kendrick Smith <kmsmith@umich.edu> 5 * Kendrick Smith <kmsmith@umich.edu>
6 * Andy Adamson <kandros@umich.edu> 6 * Andy Adamson <kandros@umich.edu>
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its 17 * 3. Neither the name of the University nor the names of its
18 * contributors may be used to endorse or promote products derived 18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission. 19 * from this software without specific prior written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * 32 *
33 */ 33 */
34 34
35 #include <linux/file.h> 35 #include <linux/file.h>
36 #include <linux/fs.h> 36 #include <linux/fs.h>
37 #include <linux/slab.h> 37 #include <linux/slab.h>
38 #include <linux/namei.h> 38 #include <linux/namei.h>
39 #include <linux/swap.h> 39 #include <linux/swap.h>
40 #include <linux/pagemap.h> 40 #include <linux/pagemap.h>
41 #include <linux/sunrpc/svcauth_gss.h> 41 #include <linux/sunrpc/svcauth_gss.h>
42 #include <linux/sunrpc/clnt.h> 42 #include <linux/sunrpc/clnt.h>
43 #include "xdr4.h" 43 #include "xdr4.h"
44 #include "vfs.h" 44 #include "vfs.h"
45 #include "current_stateid.h" 45 #include "current_stateid.h"
46 46
47 #define NFSDDBG_FACILITY NFSDDBG_PROC 47 #define NFSDDBG_FACILITY NFSDDBG_PROC
48 48
49 /* Globals */ 49 /* Globals */
50 time_t nfsd4_lease = 90; /* default lease time */ 50 time_t nfsd4_lease = 90; /* default lease time */
51 time_t nfsd4_grace = 90; 51 time_t nfsd4_grace = 90;
52 static time_t boot_time; 52 static time_t boot_time;
53 53
54 #define all_ones {{~0,~0},~0} 54 #define all_ones {{~0,~0},~0}
55 static const stateid_t one_stateid = { 55 static const stateid_t one_stateid = {
56 .si_generation = ~0, 56 .si_generation = ~0,
57 .si_opaque = all_ones, 57 .si_opaque = all_ones,
58 }; 58 };
59 static const stateid_t zero_stateid = { 59 static const stateid_t zero_stateid = {
60 /* all fields zero */ 60 /* all fields zero */
61 }; 61 };
62 static const stateid_t currentstateid = { 62 static const stateid_t currentstateid = {
63 .si_generation = 1, 63 .si_generation = 1,
64 }; 64 };
65 65
66 static u64 current_sessionid = 1; 66 static u64 current_sessionid = 1;
67 67
68 #define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t))) 68 #define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t)))
69 #define ONE_STATEID(stateid) (!memcmp((stateid), &one_stateid, sizeof(stateid_t))) 69 #define ONE_STATEID(stateid) (!memcmp((stateid), &one_stateid, sizeof(stateid_t)))
70 #define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t))) 70 #define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t)))
71 71
72 /* forward declarations */ 72 /* forward declarations */
73 static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner); 73 static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
74 74
75 /* Locking: */ 75 /* Locking: */
76 76
77 /* Currently used for almost all code touching nfsv4 state: */ 77 /* Currently used for almost all code touching nfsv4 state: */
78 static DEFINE_MUTEX(client_mutex); 78 static DEFINE_MUTEX(client_mutex);
79 79
80 /* 80 /*
81 * Currently used for the del_recall_lru and file hash table. In an 81 * Currently used for the del_recall_lru and file hash table. In an
82 * effort to decrease the scope of the client_mutex, this spinlock may 82 * effort to decrease the scope of the client_mutex, this spinlock may
83 * eventually cover more: 83 * eventually cover more:
84 */ 84 */
85 static DEFINE_SPINLOCK(recall_lock); 85 static DEFINE_SPINLOCK(recall_lock);
86 86
87 static struct kmem_cache *openowner_slab = NULL; 87 static struct kmem_cache *openowner_slab = NULL;
88 static struct kmem_cache *lockowner_slab = NULL; 88 static struct kmem_cache *lockowner_slab = NULL;
89 static struct kmem_cache *file_slab = NULL; 89 static struct kmem_cache *file_slab = NULL;
90 static struct kmem_cache *stateid_slab = NULL; 90 static struct kmem_cache *stateid_slab = NULL;
91 static struct kmem_cache *deleg_slab = NULL; 91 static struct kmem_cache *deleg_slab = NULL;
92 92
93 void 93 void
94 nfs4_lock_state(void) 94 nfs4_lock_state(void)
95 { 95 {
96 mutex_lock(&client_mutex); 96 mutex_lock(&client_mutex);
97 } 97 }
98 98
99 static void free_session(struct kref *); 99 static void free_session(struct kref *);
100 100
101 /* Must be called under the client_lock */ 101 /* Must be called under the client_lock */
102 static void nfsd4_put_session_locked(struct nfsd4_session *ses) 102 static void nfsd4_put_session_locked(struct nfsd4_session *ses)
103 { 103 {
104 kref_put(&ses->se_ref, free_session); 104 kref_put(&ses->se_ref, free_session);
105 } 105 }
106 106
107 static void nfsd4_get_session(struct nfsd4_session *ses) 107 static void nfsd4_get_session(struct nfsd4_session *ses)
108 { 108 {
109 kref_get(&ses->se_ref); 109 kref_get(&ses->se_ref);
110 } 110 }
111 111
112 void 112 void
113 nfs4_unlock_state(void) 113 nfs4_unlock_state(void)
114 { 114 {
115 mutex_unlock(&client_mutex); 115 mutex_unlock(&client_mutex);
116 } 116 }
117 117
118 static inline u32 118 static inline u32
119 opaque_hashval(const void *ptr, int nbytes) 119 opaque_hashval(const void *ptr, int nbytes)
120 { 120 {
121 unsigned char *cptr = (unsigned char *) ptr; 121 unsigned char *cptr = (unsigned char *) ptr;
122 122
123 u32 x = 0; 123 u32 x = 0;
124 while (nbytes--) { 124 while (nbytes--) {
125 x *= 37; 125 x *= 37;
126 x += *cptr++; 126 x += *cptr++;
127 } 127 }
128 return x; 128 return x;
129 } 129 }
130 130
131 static struct list_head del_recall_lru; 131 static struct list_head del_recall_lru;
132 132
133 static void nfsd4_free_file(struct nfs4_file *f) 133 static void nfsd4_free_file(struct nfs4_file *f)
134 { 134 {
135 kmem_cache_free(file_slab, f); 135 kmem_cache_free(file_slab, f);
136 } 136 }
137 137
138 static inline void 138 static inline void
139 put_nfs4_file(struct nfs4_file *fi) 139 put_nfs4_file(struct nfs4_file *fi)
140 { 140 {
141 if (atomic_dec_and_lock(&fi->fi_ref, &recall_lock)) { 141 if (atomic_dec_and_lock(&fi->fi_ref, &recall_lock)) {
142 list_del(&fi->fi_hash); 142 list_del(&fi->fi_hash);
143 spin_unlock(&recall_lock); 143 spin_unlock(&recall_lock);
144 iput(fi->fi_inode); 144 iput(fi->fi_inode);
145 nfsd4_free_file(fi); 145 nfsd4_free_file(fi);
146 } 146 }
147 } 147 }
148 148
149 static inline void 149 static inline void
150 get_nfs4_file(struct nfs4_file *fi) 150 get_nfs4_file(struct nfs4_file *fi)
151 { 151 {
152 atomic_inc(&fi->fi_ref); 152 atomic_inc(&fi->fi_ref);
153 } 153 }
154 154
155 static int num_delegations; 155 static int num_delegations;
156 unsigned int max_delegations; 156 unsigned int max_delegations;
157 157
158 /* 158 /*
159 * Open owner state (share locks) 159 * Open owner state (share locks)
160 */ 160 */
161 161
162 /* hash tables for lock and open owners */ 162 /* hash tables for lock and open owners */
163 #define OWNER_HASH_BITS 8 163 #define OWNER_HASH_BITS 8
164 #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS) 164 #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS)
165 #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1) 165 #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1)
166 166
167 static unsigned int ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername) 167 static unsigned int ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
168 { 168 {
169 unsigned int ret; 169 unsigned int ret;
170 170
171 ret = opaque_hashval(ownername->data, ownername->len); 171 ret = opaque_hashval(ownername->data, ownername->len);
172 ret += clientid; 172 ret += clientid;
173 return ret & OWNER_HASH_MASK; 173 return ret & OWNER_HASH_MASK;
174 } 174 }
175 175
176 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; 176 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
177 177
178 /* hash table for nfs4_file */ 178 /* hash table for nfs4_file */
179 #define FILE_HASH_BITS 8 179 #define FILE_HASH_BITS 8
180 #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) 180 #define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
181 181
182 static unsigned int file_hashval(struct inode *ino) 182 static unsigned int file_hashval(struct inode *ino)
183 { 183 {
184 /* XXX: why are we hashing on inode pointer, anyway? */ 184 /* XXX: why are we hashing on inode pointer, anyway? */
185 return hash_ptr(ino, FILE_HASH_BITS); 185 return hash_ptr(ino, FILE_HASH_BITS);
186 } 186 }
187 187
188 static struct list_head file_hashtbl[FILE_HASH_SIZE]; 188 static struct list_head file_hashtbl[FILE_HASH_SIZE];
189 189
190 static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag) 190 static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag)
191 { 191 {
192 BUG_ON(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR])); 192 BUG_ON(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR]));
193 atomic_inc(&fp->fi_access[oflag]); 193 atomic_inc(&fp->fi_access[oflag]);
194 } 194 }
195 195
196 static void nfs4_file_get_access(struct nfs4_file *fp, int oflag) 196 static void nfs4_file_get_access(struct nfs4_file *fp, int oflag)
197 { 197 {
198 if (oflag == O_RDWR) { 198 if (oflag == O_RDWR) {
199 __nfs4_file_get_access(fp, O_RDONLY); 199 __nfs4_file_get_access(fp, O_RDONLY);
200 __nfs4_file_get_access(fp, O_WRONLY); 200 __nfs4_file_get_access(fp, O_WRONLY);
201 } else 201 } else
202 __nfs4_file_get_access(fp, oflag); 202 __nfs4_file_get_access(fp, oflag);
203 } 203 }
204 204
205 static void nfs4_file_put_fd(struct nfs4_file *fp, int oflag) 205 static void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
206 { 206 {
207 if (fp->fi_fds[oflag]) { 207 if (fp->fi_fds[oflag]) {
208 fput(fp->fi_fds[oflag]); 208 fput(fp->fi_fds[oflag]);
209 fp->fi_fds[oflag] = NULL; 209 fp->fi_fds[oflag] = NULL;
210 } 210 }
211 } 211 }
212 212
213 static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag) 213 static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
214 { 214 {
215 if (atomic_dec_and_test(&fp->fi_access[oflag])) { 215 if (atomic_dec_and_test(&fp->fi_access[oflag])) {
216 nfs4_file_put_fd(fp, oflag); 216 nfs4_file_put_fd(fp, oflag);
217 /* 217 /*
218 * It's also safe to get rid of the RDWR open *if* 218 * It's also safe to get rid of the RDWR open *if*
219 * we no longer have need of the other kind of access 219 * we no longer have need of the other kind of access
220 * or if we already have the other kind of open: 220 * or if we already have the other kind of open:
221 */ 221 */
222 if (fp->fi_fds[1-oflag] 222 if (fp->fi_fds[1-oflag]
223 || atomic_read(&fp->fi_access[1 - oflag]) == 0) 223 || atomic_read(&fp->fi_access[1 - oflag]) == 0)
224 nfs4_file_put_fd(fp, O_RDWR); 224 nfs4_file_put_fd(fp, O_RDWR);
225 } 225 }
226 } 226 }
227 227
228 static void nfs4_file_put_access(struct nfs4_file *fp, int oflag) 228 static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
229 { 229 {
230 if (oflag == O_RDWR) { 230 if (oflag == O_RDWR) {
231 __nfs4_file_put_access(fp, O_RDONLY); 231 __nfs4_file_put_access(fp, O_RDONLY);
232 __nfs4_file_put_access(fp, O_WRONLY); 232 __nfs4_file_put_access(fp, O_WRONLY);
233 } else 233 } else
234 __nfs4_file_put_access(fp, oflag); 234 __nfs4_file_put_access(fp, oflag);
235 } 235 }
236 236
237 static inline int get_new_stid(struct nfs4_stid *stid) 237 static inline int get_new_stid(struct nfs4_stid *stid)
238 { 238 {
239 static int min_stateid = 0; 239 static int min_stateid = 0;
240 struct idr *stateids = &stid->sc_client->cl_stateids; 240 struct idr *stateids = &stid->sc_client->cl_stateids;
241 int new_stid; 241 int new_stid;
242 int error; 242 int error;
243 243
244 error = idr_get_new_above(stateids, stid, min_stateid, &new_stid); 244 error = idr_get_new_above(stateids, stid, min_stateid, &new_stid);
245 /* 245 /*
246 * Note: the necessary preallocation was done in 246 * Note: the necessary preallocation was done in
247 * nfs4_alloc_stateid(). The idr code caps the number of 247 * nfs4_alloc_stateid(). The idr code caps the number of
248 * preallocations that can exist at a time, but the state lock 248 * preallocations that can exist at a time, but the state lock
249 * prevents anyone from using ours before we get here: 249 * prevents anyone from using ours before we get here:
250 */ 250 */
251 BUG_ON(error); 251 BUG_ON(error);
252 /* 252 /*
253 * It shouldn't be a problem to reuse an opaque stateid value. 253 * It shouldn't be a problem to reuse an opaque stateid value.
254 * I don't think it is for 4.1. But with 4.0 I worry that, for 254 * I don't think it is for 4.1. But with 4.0 I worry that, for
255 * example, a stray write retransmission could be accepted by 255 * example, a stray write retransmission could be accepted by
256 * the server when it should have been rejected. Therefore, 256 * the server when it should have been rejected. Therefore,
257 * adopt a trick from the sctp code to attempt to maximize the 257 * adopt a trick from the sctp code to attempt to maximize the
258 * amount of time until an id is reused, by ensuring they always 258 * amount of time until an id is reused, by ensuring they always
259 * "increase" (mod INT_MAX): 259 * "increase" (mod INT_MAX):
260 */ 260 */
261 261
262 min_stateid = new_stid+1; 262 min_stateid = new_stid+1;
263 if (min_stateid == INT_MAX) 263 if (min_stateid == INT_MAX)
264 min_stateid = 0; 264 min_stateid = 0;
265 return new_stid; 265 return new_stid;
266 } 266 }
267 267
268 static void init_stid(struct nfs4_stid *stid, struct nfs4_client *cl, unsigned char type) 268 static void init_stid(struct nfs4_stid *stid, struct nfs4_client *cl, unsigned char type)
269 { 269 {
270 stateid_t *s = &stid->sc_stateid; 270 stateid_t *s = &stid->sc_stateid;
271 int new_id; 271 int new_id;
272 272
273 stid->sc_type = type; 273 stid->sc_type = type;
274 stid->sc_client = cl; 274 stid->sc_client = cl;
275 s->si_opaque.so_clid = cl->cl_clientid; 275 s->si_opaque.so_clid = cl->cl_clientid;
276 new_id = get_new_stid(stid); 276 new_id = get_new_stid(stid);
277 s->si_opaque.so_id = (u32)new_id; 277 s->si_opaque.so_id = (u32)new_id;
278 /* Will be incremented before return to client: */ 278 /* Will be incremented before return to client: */
279 s->si_generation = 0; 279 s->si_generation = 0;
280 } 280 }
281 281
282 static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab) 282 static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab)
283 { 283 {
284 struct idr *stateids = &cl->cl_stateids; 284 struct idr *stateids = &cl->cl_stateids;
285 285
286 if (!idr_pre_get(stateids, GFP_KERNEL)) 286 if (!idr_pre_get(stateids, GFP_KERNEL))
287 return NULL; 287 return NULL;
288 /* 288 /*
289 * Note: if we fail here (or any time between now and the time 289 * Note: if we fail here (or any time between now and the time
290 * we actually get the new idr), we won't need to undo the idr 290 * we actually get the new idr), we won't need to undo the idr
291 * preallocation, since the idr code caps the number of 291 * preallocation, since the idr code caps the number of
292 * preallocated entries. 292 * preallocated entries.
293 */ 293 */
294 return kmem_cache_alloc(slab, GFP_KERNEL); 294 return kmem_cache_alloc(slab, GFP_KERNEL);
295 } 295 }
296 296
297 static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp) 297 static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
298 { 298 {
299 return openlockstateid(nfs4_alloc_stid(clp, stateid_slab)); 299 return openlockstateid(nfs4_alloc_stid(clp, stateid_slab));
300 } 300 }
301 301
302 static struct nfs4_delegation * 302 static struct nfs4_delegation *
303 alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) 303 alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type)
304 { 304 {
305 struct nfs4_delegation *dp; 305 struct nfs4_delegation *dp;
306 struct nfs4_file *fp = stp->st_file; 306 struct nfs4_file *fp = stp->st_file;
307 307
308 dprintk("NFSD alloc_init_deleg\n"); 308 dprintk("NFSD alloc_init_deleg\n");
309 /* 309 /*
310 * Major work on the lease subsystem (for example, to support 310 * Major work on the lease subsystem (for example, to support
311 * calbacks on stat) will be required before we can support 311 * calbacks on stat) will be required before we can support
312 * write delegations properly. 312 * write delegations properly.
313 */ 313 */
314 if (type != NFS4_OPEN_DELEGATE_READ) 314 if (type != NFS4_OPEN_DELEGATE_READ)
315 return NULL; 315 return NULL;
316 if (fp->fi_had_conflict) 316 if (fp->fi_had_conflict)
317 return NULL; 317 return NULL;
318 if (num_delegations > max_delegations) 318 if (num_delegations > max_delegations)
319 return NULL; 319 return NULL;
320 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab)); 320 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
321 if (dp == NULL) 321 if (dp == NULL)
322 return dp; 322 return dp;
323 init_stid(&dp->dl_stid, clp, NFS4_DELEG_STID); 323 init_stid(&dp->dl_stid, clp, NFS4_DELEG_STID);
324 /* 324 /*
325 * delegation seqid's are never incremented. The 4.1 special 325 * delegation seqid's are never incremented. The 4.1 special
326 * meaning of seqid 0 isn't meaningful, really, but let's avoid 326 * meaning of seqid 0 isn't meaningful, really, but let's avoid
327 * 0 anyway just for consistency and use 1: 327 * 0 anyway just for consistency and use 1:
328 */ 328 */
329 dp->dl_stid.sc_stateid.si_generation = 1; 329 dp->dl_stid.sc_stateid.si_generation = 1;
330 num_delegations++; 330 num_delegations++;
331 INIT_LIST_HEAD(&dp->dl_perfile); 331 INIT_LIST_HEAD(&dp->dl_perfile);
332 INIT_LIST_HEAD(&dp->dl_perclnt); 332 INIT_LIST_HEAD(&dp->dl_perclnt);
333 INIT_LIST_HEAD(&dp->dl_recall_lru); 333 INIT_LIST_HEAD(&dp->dl_recall_lru);
334 get_nfs4_file(fp); 334 get_nfs4_file(fp);
335 dp->dl_file = fp; 335 dp->dl_file = fp;
336 dp->dl_type = type; 336 dp->dl_type = type;
337 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); 337 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
338 dp->dl_time = 0; 338 dp->dl_time = 0;
339 atomic_set(&dp->dl_count, 1); 339 atomic_set(&dp->dl_count, 1);
340 INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc); 340 INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc);
341 return dp; 341 return dp;
342 } 342 }
343 343
344 void 344 void
345 nfs4_put_delegation(struct nfs4_delegation *dp) 345 nfs4_put_delegation(struct nfs4_delegation *dp)
346 { 346 {
347 if (atomic_dec_and_test(&dp->dl_count)) { 347 if (atomic_dec_and_test(&dp->dl_count)) {
348 dprintk("NFSD: freeing dp %p\n",dp); 348 dprintk("NFSD: freeing dp %p\n",dp);
349 put_nfs4_file(dp->dl_file); 349 put_nfs4_file(dp->dl_file);
350 kmem_cache_free(deleg_slab, dp); 350 kmem_cache_free(deleg_slab, dp);
351 num_delegations--; 351 num_delegations--;
352 } 352 }
353 } 353 }
354 354
355 static void nfs4_put_deleg_lease(struct nfs4_file *fp) 355 static void nfs4_put_deleg_lease(struct nfs4_file *fp)
356 { 356 {
357 if (atomic_dec_and_test(&fp->fi_delegees)) { 357 if (atomic_dec_and_test(&fp->fi_delegees)) {
358 vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); 358 vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease);
359 fp->fi_lease = NULL; 359 fp->fi_lease = NULL;
360 fput(fp->fi_deleg_file); 360 fput(fp->fi_deleg_file);
361 fp->fi_deleg_file = NULL; 361 fp->fi_deleg_file = NULL;
362 } 362 }
363 } 363 }
364 364
365 static void unhash_stid(struct nfs4_stid *s) 365 static void unhash_stid(struct nfs4_stid *s)
366 { 366 {
367 struct idr *stateids = &s->sc_client->cl_stateids; 367 struct idr *stateids = &s->sc_client->cl_stateids;
368 368
369 idr_remove(stateids, s->sc_stateid.si_opaque.so_id); 369 idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
370 } 370 }
371 371
372 /* Called under the state lock. */ 372 /* Called under the state lock. */
373 static void 373 static void
374 unhash_delegation(struct nfs4_delegation *dp) 374 unhash_delegation(struct nfs4_delegation *dp)
375 { 375 {
376 unhash_stid(&dp->dl_stid); 376 unhash_stid(&dp->dl_stid);
377 list_del_init(&dp->dl_perclnt); 377 list_del_init(&dp->dl_perclnt);
378 spin_lock(&recall_lock); 378 spin_lock(&recall_lock);
379 list_del_init(&dp->dl_perfile); 379 list_del_init(&dp->dl_perfile);
380 list_del_init(&dp->dl_recall_lru); 380 list_del_init(&dp->dl_recall_lru);
381 spin_unlock(&recall_lock); 381 spin_unlock(&recall_lock);
382 nfs4_put_deleg_lease(dp->dl_file); 382 nfs4_put_deleg_lease(dp->dl_file);
383 nfs4_put_delegation(dp); 383 nfs4_put_delegation(dp);
384 } 384 }
385 385
386 /* 386 /*
387 * SETCLIENTID state 387 * SETCLIENTID state
388 */ 388 */
389 389
390 /* client_lock protects the client lru list and session hash table */ 390 /* client_lock protects the client lru list and session hash table */
391 static DEFINE_SPINLOCK(client_lock); 391 static DEFINE_SPINLOCK(client_lock);
392 392
393 /* Hash tables for nfs4_clientid state */ 393 /* Hash tables for nfs4_clientid state */
394 #define CLIENT_HASH_BITS 4 394 #define CLIENT_HASH_BITS 4
395 #define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS) 395 #define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
396 #define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1) 396 #define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
397 397
398 static unsigned int clientid_hashval(u32 id) 398 static unsigned int clientid_hashval(u32 id)
399 { 399 {
400 return id & CLIENT_HASH_MASK; 400 return id & CLIENT_HASH_MASK;
401 } 401 }
402 402
403 static unsigned int clientstr_hashval(const char *name) 403 static unsigned int clientstr_hashval(const char *name)
404 { 404 {
405 return opaque_hashval(name, 8) & CLIENT_HASH_MASK; 405 return opaque_hashval(name, 8) & CLIENT_HASH_MASK;
406 } 406 }
407 407
408 /* 408 /*
409 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot 409 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
410 * used in reboot/reset lease grace period processing 410 * used in reboot/reset lease grace period processing
411 * 411 *
412 * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed 412 * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
413 * setclientid_confirmed info. 413 * setclientid_confirmed info.
414 * 414 *
415 * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed 415 * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed
416 * setclientid info. 416 * setclientid info.
417 * 417 *
418 * client_lru holds client queue ordered by nfs4_client.cl_time 418 * client_lru holds client queue ordered by nfs4_client.cl_time
419 * for lease renewal. 419 * for lease renewal.
420 * 420 *
421 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time 421 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
422 * for last close replay. 422 * for last close replay.
423 */ 423 */
424 static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE]; 424 static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
425 static int reclaim_str_hashtbl_size = 0; 425 static int reclaim_str_hashtbl_size = 0;
426 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; 426 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
427 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE]; 427 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
428 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE]; 428 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
429 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; 429 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
430 static struct list_head client_lru; 430 static struct list_head client_lru;
431 static struct list_head close_lru; 431 static struct list_head close_lru;
432 432
433 /* 433 /*
434 * We store the NONE, READ, WRITE, and BOTH bits separately in the 434 * We store the NONE, READ, WRITE, and BOTH bits separately in the
435 * st_{access,deny}_bmap field of the stateid, in order to track not 435 * st_{access,deny}_bmap field of the stateid, in order to track not
436 * only what share bits are currently in force, but also what 436 * only what share bits are currently in force, but also what
437 * combinations of share bits previous opens have used. This allows us 437 * combinations of share bits previous opens have used. This allows us
438 * to enforce the recommendation of rfc 3530 14.2.19 that the server 438 * to enforce the recommendation of rfc 3530 14.2.19 that the server
439 * return an error if the client attempt to downgrade to a combination 439 * return an error if the client attempt to downgrade to a combination
440 * of share bits not explicable by closing some of its previous opens. 440 * of share bits not explicable by closing some of its previous opens.
441 * 441 *
442 * XXX: This enforcement is actually incomplete, since we don't keep 442 * XXX: This enforcement is actually incomplete, since we don't keep
443 * track of access/deny bit combinations; so, e.g., we allow: 443 * track of access/deny bit combinations; so, e.g., we allow:
444 * 444 *
445 * OPEN allow read, deny write 445 * OPEN allow read, deny write
446 * OPEN allow both, deny none 446 * OPEN allow both, deny none
447 * DOWNGRADE allow read, deny none 447 * DOWNGRADE allow read, deny none
448 * 448 *
449 * which we should reject. 449 * which we should reject.
450 */ 450 */
451 static void 451 static void
452 set_access(unsigned int *access, unsigned long bmap) { 452 set_access(unsigned int *access, unsigned long bmap) {
453 int i; 453 int i;
454 454
455 *access = 0; 455 *access = 0;
456 for (i = 1; i < 4; i++) { 456 for (i = 1; i < 4; i++) {
457 if (test_bit(i, &bmap)) 457 if (test_bit(i, &bmap))
458 *access |= i; 458 *access |= i;
459 } 459 }
460 } 460 }
461 461
462 static void 462 static void
463 set_deny(unsigned int *deny, unsigned long bmap) { 463 set_deny(unsigned int *deny, unsigned long bmap) {
464 int i; 464 int i;
465 465
466 *deny = 0; 466 *deny = 0;
467 for (i = 0; i < 4; i++) { 467 for (i = 0; i < 4; i++) {
468 if (test_bit(i, &bmap)) 468 if (test_bit(i, &bmap))
469 *deny |= i ; 469 *deny |= i ;
470 } 470 }
471 } 471 }
472 472
473 static int 473 static int
474 test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) { 474 test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
475 unsigned int access, deny; 475 unsigned int access, deny;
476 476
477 set_access(&access, stp->st_access_bmap); 477 set_access(&access, stp->st_access_bmap);
478 set_deny(&deny, stp->st_deny_bmap); 478 set_deny(&deny, stp->st_deny_bmap);
479 if ((access & open->op_share_deny) || (deny & open->op_share_access)) 479 if ((access & open->op_share_deny) || (deny & open->op_share_access))
480 return 0; 480 return 0;
481 return 1; 481 return 1;
482 } 482 }
483 483
484 static int nfs4_access_to_omode(u32 access) 484 static int nfs4_access_to_omode(u32 access)
485 { 485 {
486 switch (access & NFS4_SHARE_ACCESS_BOTH) { 486 switch (access & NFS4_SHARE_ACCESS_BOTH) {
487 case NFS4_SHARE_ACCESS_READ: 487 case NFS4_SHARE_ACCESS_READ:
488 return O_RDONLY; 488 return O_RDONLY;
489 case NFS4_SHARE_ACCESS_WRITE: 489 case NFS4_SHARE_ACCESS_WRITE:
490 return O_WRONLY; 490 return O_WRONLY;
491 case NFS4_SHARE_ACCESS_BOTH: 491 case NFS4_SHARE_ACCESS_BOTH:
492 return O_RDWR; 492 return O_RDWR;
493 } 493 }
494 BUG(); 494 BUG();
495 } 495 }
496 496
497 static void unhash_generic_stateid(struct nfs4_ol_stateid *stp) 497 static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
498 { 498 {
499 list_del(&stp->st_perfile); 499 list_del(&stp->st_perfile);
500 list_del(&stp->st_perstateowner); 500 list_del(&stp->st_perstateowner);
501 } 501 }
502 502
503 static void close_generic_stateid(struct nfs4_ol_stateid *stp) 503 static void close_generic_stateid(struct nfs4_ol_stateid *stp)
504 { 504 {
505 int i; 505 int i;
506 506
507 if (stp->st_access_bmap) { 507 if (stp->st_access_bmap) {
508 for (i = 1; i < 4; i++) { 508 for (i = 1; i < 4; i++) {
509 if (test_bit(i, &stp->st_access_bmap)) 509 if (test_bit(i, &stp->st_access_bmap))
510 nfs4_file_put_access(stp->st_file, 510 nfs4_file_put_access(stp->st_file,
511 nfs4_access_to_omode(i)); 511 nfs4_access_to_omode(i));
512 __clear_bit(i, &stp->st_access_bmap); 512 __clear_bit(i, &stp->st_access_bmap);
513 } 513 }
514 } 514 }
515 put_nfs4_file(stp->st_file); 515 put_nfs4_file(stp->st_file);
516 stp->st_file = NULL; 516 stp->st_file = NULL;
517 } 517 }
518 518
519 static void free_generic_stateid(struct nfs4_ol_stateid *stp) 519 static void free_generic_stateid(struct nfs4_ol_stateid *stp)
520 { 520 {
521 kmem_cache_free(stateid_slab, stp); 521 kmem_cache_free(stateid_slab, stp);
522 } 522 }
523 523
524 static void release_lock_stateid(struct nfs4_ol_stateid *stp) 524 static void release_lock_stateid(struct nfs4_ol_stateid *stp)
525 { 525 {
526 struct file *file; 526 struct file *file;
527 527
528 unhash_generic_stateid(stp); 528 unhash_generic_stateid(stp);
529 unhash_stid(&stp->st_stid); 529 unhash_stid(&stp->st_stid);
530 file = find_any_file(stp->st_file); 530 file = find_any_file(stp->st_file);
531 if (file) 531 if (file)
532 locks_remove_posix(file, (fl_owner_t)lockowner(stp->st_stateowner)); 532 locks_remove_posix(file, (fl_owner_t)lockowner(stp->st_stateowner));
533 close_generic_stateid(stp); 533 close_generic_stateid(stp);
534 free_generic_stateid(stp); 534 free_generic_stateid(stp);
535 } 535 }
536 536
537 static void unhash_lockowner(struct nfs4_lockowner *lo) 537 static void unhash_lockowner(struct nfs4_lockowner *lo)
538 { 538 {
539 struct nfs4_ol_stateid *stp; 539 struct nfs4_ol_stateid *stp;
540 540
541 list_del(&lo->lo_owner.so_strhash); 541 list_del(&lo->lo_owner.so_strhash);
542 list_del(&lo->lo_perstateid); 542 list_del(&lo->lo_perstateid);
543 list_del(&lo->lo_owner_ino_hash); 543 list_del(&lo->lo_owner_ino_hash);
544 while (!list_empty(&lo->lo_owner.so_stateids)) { 544 while (!list_empty(&lo->lo_owner.so_stateids)) {
545 stp = list_first_entry(&lo->lo_owner.so_stateids, 545 stp = list_first_entry(&lo->lo_owner.so_stateids,
546 struct nfs4_ol_stateid, st_perstateowner); 546 struct nfs4_ol_stateid, st_perstateowner);
547 release_lock_stateid(stp); 547 release_lock_stateid(stp);
548 } 548 }
549 } 549 }
550 550
551 static void release_lockowner(struct nfs4_lockowner *lo) 551 static void release_lockowner(struct nfs4_lockowner *lo)
552 { 552 {
553 unhash_lockowner(lo); 553 unhash_lockowner(lo);
554 nfs4_free_lockowner(lo); 554 nfs4_free_lockowner(lo);
555 } 555 }
556 556
557 static void 557 static void
558 release_stateid_lockowners(struct nfs4_ol_stateid *open_stp) 558 release_stateid_lockowners(struct nfs4_ol_stateid *open_stp)
559 { 559 {
560 struct nfs4_lockowner *lo; 560 struct nfs4_lockowner *lo;
561 561
562 while (!list_empty(&open_stp->st_lockowners)) { 562 while (!list_empty(&open_stp->st_lockowners)) {
563 lo = list_entry(open_stp->st_lockowners.next, 563 lo = list_entry(open_stp->st_lockowners.next,
564 struct nfs4_lockowner, lo_perstateid); 564 struct nfs4_lockowner, lo_perstateid);
565 release_lockowner(lo); 565 release_lockowner(lo);
566 } 566 }
567 } 567 }
568 568
569 static void unhash_open_stateid(struct nfs4_ol_stateid *stp) 569 static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
570 { 570 {
571 unhash_generic_stateid(stp); 571 unhash_generic_stateid(stp);
572 release_stateid_lockowners(stp); 572 release_stateid_lockowners(stp);
573 close_generic_stateid(stp); 573 close_generic_stateid(stp);
574 } 574 }
575 575
576 static void release_open_stateid(struct nfs4_ol_stateid *stp) 576 static void release_open_stateid(struct nfs4_ol_stateid *stp)
577 { 577 {
578 unhash_open_stateid(stp); 578 unhash_open_stateid(stp);
579 unhash_stid(&stp->st_stid); 579 unhash_stid(&stp->st_stid);
580 free_generic_stateid(stp); 580 free_generic_stateid(stp);
581 } 581 }
582 582
583 static void unhash_openowner(struct nfs4_openowner *oo) 583 static void unhash_openowner(struct nfs4_openowner *oo)
584 { 584 {
585 struct nfs4_ol_stateid *stp; 585 struct nfs4_ol_stateid *stp;
586 586
587 list_del(&oo->oo_owner.so_strhash); 587 list_del(&oo->oo_owner.so_strhash);
588 list_del(&oo->oo_perclient); 588 list_del(&oo->oo_perclient);
589 while (!list_empty(&oo->oo_owner.so_stateids)) { 589 while (!list_empty(&oo->oo_owner.so_stateids)) {
590 stp = list_first_entry(&oo->oo_owner.so_stateids, 590 stp = list_first_entry(&oo->oo_owner.so_stateids,
591 struct nfs4_ol_stateid, st_perstateowner); 591 struct nfs4_ol_stateid, st_perstateowner);
592 release_open_stateid(stp); 592 release_open_stateid(stp);
593 } 593 }
594 } 594 }
595 595
596 static void release_last_closed_stateid(struct nfs4_openowner *oo) 596 static void release_last_closed_stateid(struct nfs4_openowner *oo)
597 { 597 {
598 struct nfs4_ol_stateid *s = oo->oo_last_closed_stid; 598 struct nfs4_ol_stateid *s = oo->oo_last_closed_stid;
599 599
600 if (s) { 600 if (s) {
601 unhash_stid(&s->st_stid); 601 unhash_stid(&s->st_stid);
602 free_generic_stateid(s); 602 free_generic_stateid(s);
603 oo->oo_last_closed_stid = NULL; 603 oo->oo_last_closed_stid = NULL;
604 } 604 }
605 } 605 }
606 606
607 static void release_openowner(struct nfs4_openowner *oo) 607 static void release_openowner(struct nfs4_openowner *oo)
608 { 608 {
609 unhash_openowner(oo); 609 unhash_openowner(oo);
610 list_del(&oo->oo_close_lru); 610 list_del(&oo->oo_close_lru);
611 release_last_closed_stateid(oo); 611 release_last_closed_stateid(oo);
612 nfs4_free_openowner(oo); 612 nfs4_free_openowner(oo);
613 } 613 }
614 614
615 #define SESSION_HASH_SIZE 512 615 #define SESSION_HASH_SIZE 512
616 static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE]; 616 static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
617 617
618 static inline int 618 static inline int
619 hash_sessionid(struct nfs4_sessionid *sessionid) 619 hash_sessionid(struct nfs4_sessionid *sessionid)
620 { 620 {
621 struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid; 621 struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid;
622 622
623 return sid->sequence % SESSION_HASH_SIZE; 623 return sid->sequence % SESSION_HASH_SIZE;
624 } 624 }
625 625
626 #ifdef NFSD_DEBUG 626 #ifdef NFSD_DEBUG
627 static inline void 627 static inline void
628 dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid) 628 dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
629 { 629 {
630 u32 *ptr = (u32 *)(&sessionid->data[0]); 630 u32 *ptr = (u32 *)(&sessionid->data[0]);
631 dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]); 631 dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]);
632 } 632 }
633 #else 633 #else
634 static inline void 634 static inline void
635 dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid) 635 dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
636 { 636 {
637 } 637 }
638 #endif 638 #endif
639 639
640 640
641 static void 641 static void
642 gen_sessionid(struct nfsd4_session *ses) 642 gen_sessionid(struct nfsd4_session *ses)
643 { 643 {
644 struct nfs4_client *clp = ses->se_client; 644 struct nfs4_client *clp = ses->se_client;
645 struct nfsd4_sessionid *sid; 645 struct nfsd4_sessionid *sid;
646 646
647 sid = (struct nfsd4_sessionid *)ses->se_sessionid.data; 647 sid = (struct nfsd4_sessionid *)ses->se_sessionid.data;
648 sid->clientid = clp->cl_clientid; 648 sid->clientid = clp->cl_clientid;
649 sid->sequence = current_sessionid++; 649 sid->sequence = current_sessionid++;
650 sid->reserved = 0; 650 sid->reserved = 0;
651 } 651 }
652 652
653 /* 653 /*
654 * The protocol defines ca_maxresponssize_cached to include the size of 654 * The protocol defines ca_maxresponssize_cached to include the size of
655 * the rpc header, but all we need to cache is the data starting after 655 * the rpc header, but all we need to cache is the data starting after
656 * the end of the initial SEQUENCE operation--the rest we regenerate 656 * the end of the initial SEQUENCE operation--the rest we regenerate
657 * each time. Therefore we can advertise a ca_maxresponssize_cached 657 * each time. Therefore we can advertise a ca_maxresponssize_cached
658 * value that is the number of bytes in our cache plus a few additional 658 * value that is the number of bytes in our cache plus a few additional
659 * bytes. In order to stay on the safe side, and not promise more than 659 * bytes. In order to stay on the safe side, and not promise more than
660 * we can cache, those additional bytes must be the minimum possible: 24 660 * we can cache, those additional bytes must be the minimum possible: 24
661 * bytes of rpc header (xid through accept state, with AUTH_NULL 661 * bytes of rpc header (xid through accept state, with AUTH_NULL
662 * verifier), 12 for the compound header (with zero-length tag), and 44 662 * verifier), 12 for the compound header (with zero-length tag), and 44
663 * for the SEQUENCE op response: 663 * for the SEQUENCE op response:
664 */ 664 */
665 #define NFSD_MIN_HDR_SEQ_SZ (24 + 12 + 44) 665 #define NFSD_MIN_HDR_SEQ_SZ (24 + 12 + 44)
666 666
667 static void 667 static void
668 free_session_slots(struct nfsd4_session *ses) 668 free_session_slots(struct nfsd4_session *ses)
669 { 669 {
670 int i; 670 int i;
671 671
672 for (i = 0; i < ses->se_fchannel.maxreqs; i++) 672 for (i = 0; i < ses->se_fchannel.maxreqs; i++)
673 kfree(ses->se_slots[i]); 673 kfree(ses->se_slots[i]);
674 } 674 }
675 675
676 /* 676 /*
677 * We don't actually need to cache the rpc and session headers, so we 677 * We don't actually need to cache the rpc and session headers, so we
678 * can allocate a little less for each slot: 678 * can allocate a little less for each slot:
679 */ 679 */
680 static inline int slot_bytes(struct nfsd4_channel_attrs *ca) 680 static inline int slot_bytes(struct nfsd4_channel_attrs *ca)
681 { 681 {
682 return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; 682 return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
683 } 683 }
684 684
685 static int nfsd4_sanitize_slot_size(u32 size) 685 static int nfsd4_sanitize_slot_size(u32 size)
686 { 686 {
687 size -= NFSD_MIN_HDR_SEQ_SZ; /* We don't cache the rpc header */ 687 size -= NFSD_MIN_HDR_SEQ_SZ; /* We don't cache the rpc header */
688 size = min_t(u32, size, NFSD_SLOT_CACHE_SIZE); 688 size = min_t(u32, size, NFSD_SLOT_CACHE_SIZE);
689 689
690 return size; 690 return size;
691 } 691 }
692 692
693 /* 693 /*
694 * XXX: If we run out of reserved DRC memory we could (up to a point) 694 * XXX: If we run out of reserved DRC memory we could (up to a point)
695 * re-negotiate active sessions and reduce their slot usage to make 695 * re-negotiate active sessions and reduce their slot usage to make
696 * room for new connections. For now we just fail the create session. 696 * room for new connections. For now we just fail the create session.
697 */ 697 */
698 static int nfsd4_get_drc_mem(int slotsize, u32 num) 698 static int nfsd4_get_drc_mem(int slotsize, u32 num)
699 { 699 {
700 int avail; 700 int avail;
701 701
702 num = min_t(u32, num, NFSD_MAX_SLOTS_PER_SESSION); 702 num = min_t(u32, num, NFSD_MAX_SLOTS_PER_SESSION);
703 703
704 spin_lock(&nfsd_drc_lock); 704 spin_lock(&nfsd_drc_lock);
705 avail = min_t(int, NFSD_MAX_MEM_PER_SESSION, 705 avail = min_t(int, NFSD_MAX_MEM_PER_SESSION,
706 nfsd_drc_max_mem - nfsd_drc_mem_used); 706 nfsd_drc_max_mem - nfsd_drc_mem_used);
707 num = min_t(int, num, avail / slotsize); 707 num = min_t(int, num, avail / slotsize);
708 nfsd_drc_mem_used += num * slotsize; 708 nfsd_drc_mem_used += num * slotsize;
709 spin_unlock(&nfsd_drc_lock); 709 spin_unlock(&nfsd_drc_lock);
710 710
711 return num; 711 return num;
712 } 712 }
713 713
714 static void nfsd4_put_drc_mem(int slotsize, int num) 714 static void nfsd4_put_drc_mem(int slotsize, int num)
715 { 715 {
716 spin_lock(&nfsd_drc_lock); 716 spin_lock(&nfsd_drc_lock);
717 nfsd_drc_mem_used -= slotsize * num; 717 nfsd_drc_mem_used -= slotsize * num;
718 spin_unlock(&nfsd_drc_lock); 718 spin_unlock(&nfsd_drc_lock);
719 } 719 }
720 720
721 static struct nfsd4_session *alloc_session(int slotsize, int numslots) 721 static struct nfsd4_session *alloc_session(int slotsize, int numslots)
722 { 722 {
723 struct nfsd4_session *new; 723 struct nfsd4_session *new;
724 int mem, i; 724 int mem, i;
725 725
726 BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot *) 726 BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot *)
727 + sizeof(struct nfsd4_session) > PAGE_SIZE); 727 + sizeof(struct nfsd4_session) > PAGE_SIZE);
728 mem = numslots * sizeof(struct nfsd4_slot *); 728 mem = numslots * sizeof(struct nfsd4_slot *);
729 729
730 new = kzalloc(sizeof(*new) + mem, GFP_KERNEL); 730 new = kzalloc(sizeof(*new) + mem, GFP_KERNEL);
731 if (!new) 731 if (!new)
732 return NULL; 732 return NULL;
733 /* allocate each struct nfsd4_slot and data cache in one piece */ 733 /* allocate each struct nfsd4_slot and data cache in one piece */
734 for (i = 0; i < numslots; i++) { 734 for (i = 0; i < numslots; i++) {
735 mem = sizeof(struct nfsd4_slot) + slotsize; 735 mem = sizeof(struct nfsd4_slot) + slotsize;
736 new->se_slots[i] = kzalloc(mem, GFP_KERNEL); 736 new->se_slots[i] = kzalloc(mem, GFP_KERNEL);
737 if (!new->se_slots[i]) 737 if (!new->se_slots[i])
738 goto out_free; 738 goto out_free;
739 } 739 }
740 return new; 740 return new;
741 out_free: 741 out_free:
742 while (i--) 742 while (i--)
743 kfree(new->se_slots[i]); 743 kfree(new->se_slots[i]);
744 kfree(new); 744 kfree(new);
745 return NULL; 745 return NULL;
746 } 746 }
747 747
748 static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4_channel_attrs *req, int numslots, int slotsize) 748 static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4_channel_attrs *req, int numslots, int slotsize)
749 { 749 {
750 u32 maxrpc = nfsd_serv->sv_max_mesg; 750 u32 maxrpc = nfsd_serv->sv_max_mesg;
751 751
752 new->maxreqs = numslots; 752 new->maxreqs = numslots;
753 new->maxresp_cached = min_t(u32, req->maxresp_cached, 753 new->maxresp_cached = min_t(u32, req->maxresp_cached,
754 slotsize + NFSD_MIN_HDR_SEQ_SZ); 754 slotsize + NFSD_MIN_HDR_SEQ_SZ);
755 new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc); 755 new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc);
756 new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc); 756 new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc);
757 new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND); 757 new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND);
758 } 758 }
759 759
760 static void free_conn(struct nfsd4_conn *c) 760 static void free_conn(struct nfsd4_conn *c)
761 { 761 {
762 svc_xprt_put(c->cn_xprt); 762 svc_xprt_put(c->cn_xprt);
763 kfree(c); 763 kfree(c);
764 } 764 }
765 765
766 static void nfsd4_conn_lost(struct svc_xpt_user *u) 766 static void nfsd4_conn_lost(struct svc_xpt_user *u)
767 { 767 {
768 struct nfsd4_conn *c = container_of(u, struct nfsd4_conn, cn_xpt_user); 768 struct nfsd4_conn *c = container_of(u, struct nfsd4_conn, cn_xpt_user);
769 struct nfs4_client *clp = c->cn_session->se_client; 769 struct nfs4_client *clp = c->cn_session->se_client;
770 770
771 spin_lock(&clp->cl_lock); 771 spin_lock(&clp->cl_lock);
772 if (!list_empty(&c->cn_persession)) { 772 if (!list_empty(&c->cn_persession)) {
773 list_del(&c->cn_persession); 773 list_del(&c->cn_persession);
774 free_conn(c); 774 free_conn(c);
775 } 775 }
776 spin_unlock(&clp->cl_lock); 776 spin_unlock(&clp->cl_lock);
777 nfsd4_probe_callback(clp); 777 nfsd4_probe_callback(clp);
778 } 778 }
779 779
780 static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags) 780 static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
781 { 781 {
782 struct nfsd4_conn *conn; 782 struct nfsd4_conn *conn;
783 783
784 conn = kmalloc(sizeof(struct nfsd4_conn), GFP_KERNEL); 784 conn = kmalloc(sizeof(struct nfsd4_conn), GFP_KERNEL);
785 if (!conn) 785 if (!conn)
786 return NULL; 786 return NULL;
787 svc_xprt_get(rqstp->rq_xprt); 787 svc_xprt_get(rqstp->rq_xprt);
788 conn->cn_xprt = rqstp->rq_xprt; 788 conn->cn_xprt = rqstp->rq_xprt;
789 conn->cn_flags = flags; 789 conn->cn_flags = flags;
790 INIT_LIST_HEAD(&conn->cn_xpt_user.list); 790 INIT_LIST_HEAD(&conn->cn_xpt_user.list);
791 return conn; 791 return conn;
792 } 792 }
793 793
794 static void __nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) 794 static void __nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
795 { 795 {
796 conn->cn_session = ses; 796 conn->cn_session = ses;
797 list_add(&conn->cn_persession, &ses->se_conns); 797 list_add(&conn->cn_persession, &ses->se_conns);
798 } 798 }
799 799
800 static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) 800 static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
801 { 801 {
802 struct nfs4_client *clp = ses->se_client; 802 struct nfs4_client *clp = ses->se_client;
803 803
804 spin_lock(&clp->cl_lock); 804 spin_lock(&clp->cl_lock);
805 __nfsd4_hash_conn(conn, ses); 805 __nfsd4_hash_conn(conn, ses);
806 spin_unlock(&clp->cl_lock); 806 spin_unlock(&clp->cl_lock);
807 } 807 }
808 808
809 static int nfsd4_register_conn(struct nfsd4_conn *conn) 809 static int nfsd4_register_conn(struct nfsd4_conn *conn)
810 { 810 {
811 conn->cn_xpt_user.callback = nfsd4_conn_lost; 811 conn->cn_xpt_user.callback = nfsd4_conn_lost;
812 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); 812 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
813 } 813 }
814 814
815 static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir) 815 static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir)
816 { 816 {
817 struct nfsd4_conn *conn; 817 struct nfsd4_conn *conn;
818 int ret; 818 int ret;
819 819
820 conn = alloc_conn(rqstp, dir); 820 conn = alloc_conn(rqstp, dir);
821 if (!conn) 821 if (!conn)
822 return nfserr_jukebox; 822 return nfserr_jukebox;
823 nfsd4_hash_conn(conn, ses); 823 nfsd4_hash_conn(conn, ses);
824 ret = nfsd4_register_conn(conn); 824 ret = nfsd4_register_conn(conn);
825 if (ret) 825 if (ret)
826 /* oops; xprt is already down: */ 826 /* oops; xprt is already down: */
827 nfsd4_conn_lost(&conn->cn_xpt_user); 827 nfsd4_conn_lost(&conn->cn_xpt_user);
828 return nfs_ok; 828 return nfs_ok;
829 } 829 }
830 830
831 static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses) 831 static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses)
832 { 832 {
833 u32 dir = NFS4_CDFC4_FORE; 833 u32 dir = NFS4_CDFC4_FORE;
834 834
835 if (ses->se_flags & SESSION4_BACK_CHAN) 835 if (ses->se_flags & SESSION4_BACK_CHAN)
836 dir |= NFS4_CDFC4_BACK; 836 dir |= NFS4_CDFC4_BACK;
837 837
838 return nfsd4_new_conn(rqstp, ses, dir); 838 return nfsd4_new_conn(rqstp, ses, dir);
839 } 839 }
840 840
841 /* must be called under client_lock */ 841 /* must be called under client_lock */
842 static void nfsd4_del_conns(struct nfsd4_session *s) 842 static void nfsd4_del_conns(struct nfsd4_session *s)
843 { 843 {
844 struct nfs4_client *clp = s->se_client; 844 struct nfs4_client *clp = s->se_client;
845 struct nfsd4_conn *c; 845 struct nfsd4_conn *c;
846 846
847 spin_lock(&clp->cl_lock); 847 spin_lock(&clp->cl_lock);
848 while (!list_empty(&s->se_conns)) { 848 while (!list_empty(&s->se_conns)) {
849 c = list_first_entry(&s->se_conns, struct nfsd4_conn, cn_persession); 849 c = list_first_entry(&s->se_conns, struct nfsd4_conn, cn_persession);
850 list_del_init(&c->cn_persession); 850 list_del_init(&c->cn_persession);
851 spin_unlock(&clp->cl_lock); 851 spin_unlock(&clp->cl_lock);
852 852
853 unregister_xpt_user(c->cn_xprt, &c->cn_xpt_user); 853 unregister_xpt_user(c->cn_xprt, &c->cn_xpt_user);
854 free_conn(c); 854 free_conn(c);
855 855
856 spin_lock(&clp->cl_lock); 856 spin_lock(&clp->cl_lock);
857 } 857 }
858 spin_unlock(&clp->cl_lock); 858 spin_unlock(&clp->cl_lock);
859 } 859 }
860 860
861 static void free_session(struct kref *kref) 861 static void free_session(struct kref *kref)
862 { 862 {
863 struct nfsd4_session *ses; 863 struct nfsd4_session *ses;
864 int mem; 864 int mem;
865 865
866 BUG_ON(!spin_is_locked(&client_lock)); 866 BUG_ON(!spin_is_locked(&client_lock));
867 ses = container_of(kref, struct nfsd4_session, se_ref); 867 ses = container_of(kref, struct nfsd4_session, se_ref);
868 nfsd4_del_conns(ses); 868 nfsd4_del_conns(ses);
869 spin_lock(&nfsd_drc_lock); 869 spin_lock(&nfsd_drc_lock);
870 mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel); 870 mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel);
871 nfsd_drc_mem_used -= mem; 871 nfsd_drc_mem_used -= mem;
872 spin_unlock(&nfsd_drc_lock); 872 spin_unlock(&nfsd_drc_lock);
873 free_session_slots(ses); 873 free_session_slots(ses);
874 kfree(ses); 874 kfree(ses);
875 } 875 }
876 876
877 void nfsd4_put_session(struct nfsd4_session *ses) 877 void nfsd4_put_session(struct nfsd4_session *ses)
878 { 878 {
879 spin_lock(&client_lock); 879 spin_lock(&client_lock);
880 nfsd4_put_session_locked(ses); 880 nfsd4_put_session_locked(ses);
881 spin_unlock(&client_lock); 881 spin_unlock(&client_lock);
882 } 882 }
883 883
884 static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses) 884 static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses)
885 { 885 {
886 struct nfsd4_session *new; 886 struct nfsd4_session *new;
887 struct nfsd4_channel_attrs *fchan = &cses->fore_channel; 887 struct nfsd4_channel_attrs *fchan = &cses->fore_channel;
888 int numslots, slotsize; 888 int numslots, slotsize;
889 int status; 889 __be32 status;
890 int idx; 890 int idx;
891 891
892 /* 892 /*
893 * Note decreasing slot size below client's request may 893 * Note decreasing slot size below client's request may
894 * make it difficult for client to function correctly, whereas 894 * make it difficult for client to function correctly, whereas
895 * decreasing the number of slots will (just?) affect 895 * decreasing the number of slots will (just?) affect
896 * performance. When short on memory we therefore prefer to 896 * performance. When short on memory we therefore prefer to
897 * decrease number of slots instead of their size. 897 * decrease number of slots instead of their size.
898 */ 898 */
899 slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached); 899 slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached);
900 numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs); 900 numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs);
901 if (numslots < 1) 901 if (numslots < 1)
902 return NULL; 902 return NULL;
903 903
904 new = alloc_session(slotsize, numslots); 904 new = alloc_session(slotsize, numslots);
905 if (!new) { 905 if (!new) {
906 nfsd4_put_drc_mem(slotsize, fchan->maxreqs); 906 nfsd4_put_drc_mem(slotsize, fchan->maxreqs);
907 return NULL; 907 return NULL;
908 } 908 }
909 init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize); 909 init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize);
910 910
911 new->se_client = clp; 911 new->se_client = clp;
912 gen_sessionid(new); 912 gen_sessionid(new);
913 913
914 INIT_LIST_HEAD(&new->se_conns); 914 INIT_LIST_HEAD(&new->se_conns);
915 915
916 new->se_cb_seq_nr = 1; 916 new->se_cb_seq_nr = 1;
917 new->se_flags = cses->flags; 917 new->se_flags = cses->flags;
918 new->se_cb_prog = cses->callback_prog; 918 new->se_cb_prog = cses->callback_prog;
919 kref_init(&new->se_ref); 919 kref_init(&new->se_ref);
920 idx = hash_sessionid(&new->se_sessionid); 920 idx = hash_sessionid(&new->se_sessionid);
921 spin_lock(&client_lock); 921 spin_lock(&client_lock);
922 list_add(&new->se_hash, &sessionid_hashtbl[idx]); 922 list_add(&new->se_hash, &sessionid_hashtbl[idx]);
923 spin_lock(&clp->cl_lock); 923 spin_lock(&clp->cl_lock);
924 list_add(&new->se_perclnt, &clp->cl_sessions); 924 list_add(&new->se_perclnt, &clp->cl_sessions);
925 spin_unlock(&clp->cl_lock); 925 spin_unlock(&clp->cl_lock);
926 spin_unlock(&client_lock); 926 spin_unlock(&client_lock);
927 927
928 status = nfsd4_new_conn_from_crses(rqstp, new); 928 status = nfsd4_new_conn_from_crses(rqstp, new);
929 /* whoops: benny points out, status is ignored! (err, or bogus) */ 929 /* whoops: benny points out, status is ignored! (err, or bogus) */
930 if (status) { 930 if (status) {
931 spin_lock(&client_lock); 931 spin_lock(&client_lock);
932 free_session(&new->se_ref); 932 free_session(&new->se_ref);
933 spin_unlock(&client_lock); 933 spin_unlock(&client_lock);
934 return NULL; 934 return NULL;
935 } 935 }
936 if (cses->flags & SESSION4_BACK_CHAN) { 936 if (cses->flags & SESSION4_BACK_CHAN) {
937 struct sockaddr *sa = svc_addr(rqstp); 937 struct sockaddr *sa = svc_addr(rqstp);
938 /* 938 /*
939 * This is a little silly; with sessions there's no real 939 * This is a little silly; with sessions there's no real
940 * use for the callback address. Use the peer address 940 * use for the callback address. Use the peer address
941 * as a reasonable default for now, but consider fixing 941 * as a reasonable default for now, but consider fixing
942 * the rpc client not to require an address in the 942 * the rpc client not to require an address in the
943 * future: 943 * future:
944 */ 944 */
945 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa); 945 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
946 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa); 946 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
947 } 947 }
948 nfsd4_probe_callback(clp); 948 nfsd4_probe_callback(clp);
949 return new; 949 return new;
950 } 950 }
951 951
952 /* caller must hold client_lock */ 952 /* caller must hold client_lock */
953 static struct nfsd4_session * 953 static struct nfsd4_session *
954 find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid) 954 find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
955 { 955 {
956 struct nfsd4_session *elem; 956 struct nfsd4_session *elem;
957 int idx; 957 int idx;
958 958
959 dump_sessionid(__func__, sessionid); 959 dump_sessionid(__func__, sessionid);
960 idx = hash_sessionid(sessionid); 960 idx = hash_sessionid(sessionid);
961 /* Search in the appropriate list */ 961 /* Search in the appropriate list */
962 list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) { 962 list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) {
963 if (!memcmp(elem->se_sessionid.data, sessionid->data, 963 if (!memcmp(elem->se_sessionid.data, sessionid->data,
964 NFS4_MAX_SESSIONID_LEN)) { 964 NFS4_MAX_SESSIONID_LEN)) {
965 return elem; 965 return elem;
966 } 966 }
967 } 967 }
968 968
969 dprintk("%s: session not found\n", __func__); 969 dprintk("%s: session not found\n", __func__);
970 return NULL; 970 return NULL;
971 } 971 }
972 972
973 /* caller must hold client_lock */ 973 /* caller must hold client_lock */
974 static void 974 static void
975 unhash_session(struct nfsd4_session *ses) 975 unhash_session(struct nfsd4_session *ses)
976 { 976 {
977 list_del(&ses->se_hash); 977 list_del(&ses->se_hash);
978 spin_lock(&ses->se_client->cl_lock); 978 spin_lock(&ses->se_client->cl_lock);
979 list_del(&ses->se_perclnt); 979 list_del(&ses->se_perclnt);
980 spin_unlock(&ses->se_client->cl_lock); 980 spin_unlock(&ses->se_client->cl_lock);
981 } 981 }
982 982
983 /* must be called under the client_lock */ 983 /* must be called under the client_lock */
984 static inline void 984 static inline void
985 renew_client_locked(struct nfs4_client *clp) 985 renew_client_locked(struct nfs4_client *clp)
986 { 986 {
987 if (is_client_expired(clp)) { 987 if (is_client_expired(clp)) {
988 dprintk("%s: client (clientid %08x/%08x) already expired\n", 988 dprintk("%s: client (clientid %08x/%08x) already expired\n",
989 __func__, 989 __func__,
990 clp->cl_clientid.cl_boot, 990 clp->cl_clientid.cl_boot,
991 clp->cl_clientid.cl_id); 991 clp->cl_clientid.cl_id);
992 return; 992 return;
993 } 993 }
994 994
995 dprintk("renewing client (clientid %08x/%08x)\n", 995 dprintk("renewing client (clientid %08x/%08x)\n",
996 clp->cl_clientid.cl_boot, 996 clp->cl_clientid.cl_boot,
997 clp->cl_clientid.cl_id); 997 clp->cl_clientid.cl_id);
998 list_move_tail(&clp->cl_lru, &client_lru); 998 list_move_tail(&clp->cl_lru, &client_lru);
999 clp->cl_time = get_seconds(); 999 clp->cl_time = get_seconds();
1000 } 1000 }
1001 1001
1002 static inline void 1002 static inline void
1003 renew_client(struct nfs4_client *clp) 1003 renew_client(struct nfs4_client *clp)
1004 { 1004 {
1005 spin_lock(&client_lock); 1005 spin_lock(&client_lock);
1006 renew_client_locked(clp); 1006 renew_client_locked(clp);
1007 spin_unlock(&client_lock); 1007 spin_unlock(&client_lock);
1008 } 1008 }
1009 1009
1010 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */ 1010 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
1011 static int 1011 static int
1012 STALE_CLIENTID(clientid_t *clid) 1012 STALE_CLIENTID(clientid_t *clid)
1013 { 1013 {
1014 if (clid->cl_boot == boot_time) 1014 if (clid->cl_boot == boot_time)
1015 return 0; 1015 return 0;
1016 dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n", 1016 dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
1017 clid->cl_boot, clid->cl_id, boot_time); 1017 clid->cl_boot, clid->cl_id, boot_time);
1018 return 1; 1018 return 1;
1019 } 1019 }
1020 1020
1021 /* 1021 /*
1022 * XXX Should we use a slab cache ? 1022 * XXX Should we use a slab cache ?
1023 * This type of memory management is somewhat inefficient, but we use it 1023 * This type of memory management is somewhat inefficient, but we use it
1024 * anyway since SETCLIENTID is not a common operation. 1024 * anyway since SETCLIENTID is not a common operation.
1025 */ 1025 */
1026 static struct nfs4_client *alloc_client(struct xdr_netobj name) 1026 static struct nfs4_client *alloc_client(struct xdr_netobj name)
1027 { 1027 {
1028 struct nfs4_client *clp; 1028 struct nfs4_client *clp;
1029 1029
1030 clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL); 1030 clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL);
1031 if (clp == NULL) 1031 if (clp == NULL)
1032 return NULL; 1032 return NULL;
1033 clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL); 1033 clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL);
1034 if (clp->cl_name.data == NULL) { 1034 if (clp->cl_name.data == NULL) {
1035 kfree(clp); 1035 kfree(clp);
1036 return NULL; 1036 return NULL;
1037 } 1037 }
1038 clp->cl_name.len = name.len; 1038 clp->cl_name.len = name.len;
1039 return clp; 1039 return clp;
1040 } 1040 }
1041 1041
1042 static inline void 1042 static inline void
1043 free_client(struct nfs4_client *clp) 1043 free_client(struct nfs4_client *clp)
1044 { 1044 {
1045 BUG_ON(!spin_is_locked(&client_lock)); 1045 BUG_ON(!spin_is_locked(&client_lock));
1046 while (!list_empty(&clp->cl_sessions)) { 1046 while (!list_empty(&clp->cl_sessions)) {
1047 struct nfsd4_session *ses; 1047 struct nfsd4_session *ses;
1048 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session, 1048 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
1049 se_perclnt); 1049 se_perclnt);
1050 list_del(&ses->se_perclnt); 1050 list_del(&ses->se_perclnt);
1051 nfsd4_put_session_locked(ses); 1051 nfsd4_put_session_locked(ses);
1052 } 1052 }
1053 if (clp->cl_cred.cr_group_info) 1053 if (clp->cl_cred.cr_group_info)
1054 put_group_info(clp->cl_cred.cr_group_info); 1054 put_group_info(clp->cl_cred.cr_group_info);
1055 kfree(clp->cl_principal); 1055 kfree(clp->cl_principal);
1056 kfree(clp->cl_name.data); 1056 kfree(clp->cl_name.data);
1057 kfree(clp); 1057 kfree(clp);
1058 } 1058 }
1059 1059
1060 void 1060 void
1061 release_session_client(struct nfsd4_session *session) 1061 release_session_client(struct nfsd4_session *session)
1062 { 1062 {
1063 struct nfs4_client *clp = session->se_client; 1063 struct nfs4_client *clp = session->se_client;
1064 1064
1065 if (!atomic_dec_and_lock(&clp->cl_refcount, &client_lock)) 1065 if (!atomic_dec_and_lock(&clp->cl_refcount, &client_lock))
1066 return; 1066 return;
1067 if (is_client_expired(clp)) { 1067 if (is_client_expired(clp)) {
1068 free_client(clp); 1068 free_client(clp);
1069 session->se_client = NULL; 1069 session->se_client = NULL;
1070 } else 1070 } else
1071 renew_client_locked(clp); 1071 renew_client_locked(clp);
1072 spin_unlock(&client_lock); 1072 spin_unlock(&client_lock);
1073 } 1073 }
1074 1074
1075 /* must be called under the client_lock */ 1075 /* must be called under the client_lock */
1076 static inline void 1076 static inline void
1077 unhash_client_locked(struct nfs4_client *clp) 1077 unhash_client_locked(struct nfs4_client *clp)
1078 { 1078 {
1079 struct nfsd4_session *ses; 1079 struct nfsd4_session *ses;
1080 1080
1081 mark_client_expired(clp); 1081 mark_client_expired(clp);
1082 list_del(&clp->cl_lru); 1082 list_del(&clp->cl_lru);
1083 spin_lock(&clp->cl_lock); 1083 spin_lock(&clp->cl_lock);
1084 list_for_each_entry(ses, &clp->cl_sessions, se_perclnt) 1084 list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
1085 list_del_init(&ses->se_hash); 1085 list_del_init(&ses->se_hash);
1086 spin_unlock(&clp->cl_lock); 1086 spin_unlock(&clp->cl_lock);
1087 } 1087 }
1088 1088
1089 static void 1089 static void
1090 expire_client(struct nfs4_client *clp) 1090 expire_client(struct nfs4_client *clp)
1091 { 1091 {
1092 struct nfs4_openowner *oo; 1092 struct nfs4_openowner *oo;
1093 struct nfs4_delegation *dp; 1093 struct nfs4_delegation *dp;
1094 struct list_head reaplist; 1094 struct list_head reaplist;
1095 1095
1096 INIT_LIST_HEAD(&reaplist); 1096 INIT_LIST_HEAD(&reaplist);
1097 spin_lock(&recall_lock); 1097 spin_lock(&recall_lock);
1098 while (!list_empty(&clp->cl_delegations)) { 1098 while (!list_empty(&clp->cl_delegations)) {
1099 dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt); 1099 dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
1100 list_del_init(&dp->dl_perclnt); 1100 list_del_init(&dp->dl_perclnt);
1101 list_move(&dp->dl_recall_lru, &reaplist); 1101 list_move(&dp->dl_recall_lru, &reaplist);
1102 } 1102 }
1103 spin_unlock(&recall_lock); 1103 spin_unlock(&recall_lock);
1104 while (!list_empty(&reaplist)) { 1104 while (!list_empty(&reaplist)) {
1105 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); 1105 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1106 unhash_delegation(dp); 1106 unhash_delegation(dp);
1107 } 1107 }
1108 while (!list_empty(&clp->cl_openowners)) { 1108 while (!list_empty(&clp->cl_openowners)) {
1109 oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); 1109 oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
1110 release_openowner(oo); 1110 release_openowner(oo);
1111 } 1111 }
1112 nfsd4_shutdown_callback(clp); 1112 nfsd4_shutdown_callback(clp);
1113 if (clp->cl_cb_conn.cb_xprt) 1113 if (clp->cl_cb_conn.cb_xprt)
1114 svc_xprt_put(clp->cl_cb_conn.cb_xprt); 1114 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1115 list_del(&clp->cl_idhash); 1115 list_del(&clp->cl_idhash);
1116 list_del(&clp->cl_strhash); 1116 list_del(&clp->cl_strhash);
1117 spin_lock(&client_lock); 1117 spin_lock(&client_lock);
1118 unhash_client_locked(clp); 1118 unhash_client_locked(clp);
1119 if (atomic_read(&clp->cl_refcount) == 0) 1119 if (atomic_read(&clp->cl_refcount) == 0)
1120 free_client(clp); 1120 free_client(clp);
1121 spin_unlock(&client_lock); 1121 spin_unlock(&client_lock);
1122 } 1122 }
1123 1123
1124 static void copy_verf(struct nfs4_client *target, nfs4_verifier *source) 1124 static void copy_verf(struct nfs4_client *target, nfs4_verifier *source)
1125 { 1125 {
1126 memcpy(target->cl_verifier.data, source->data, 1126 memcpy(target->cl_verifier.data, source->data,
1127 sizeof(target->cl_verifier.data)); 1127 sizeof(target->cl_verifier.data));
1128 } 1128 }
1129 1129
1130 static void copy_clid(struct nfs4_client *target, struct nfs4_client *source) 1130 static void copy_clid(struct nfs4_client *target, struct nfs4_client *source)
1131 { 1131 {
1132 target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; 1132 target->cl_clientid.cl_boot = source->cl_clientid.cl_boot;
1133 target->cl_clientid.cl_id = source->cl_clientid.cl_id; 1133 target->cl_clientid.cl_id = source->cl_clientid.cl_id;
1134 } 1134 }
1135 1135
1136 static void copy_cred(struct svc_cred *target, struct svc_cred *source) 1136 static void copy_cred(struct svc_cred *target, struct svc_cred *source)
1137 { 1137 {
1138 target->cr_uid = source->cr_uid; 1138 target->cr_uid = source->cr_uid;
1139 target->cr_gid = source->cr_gid; 1139 target->cr_gid = source->cr_gid;
1140 target->cr_group_info = source->cr_group_info; 1140 target->cr_group_info = source->cr_group_info;
1141 get_group_info(target->cr_group_info); 1141 get_group_info(target->cr_group_info);
1142 } 1142 }
1143 1143
1144 static int same_name(const char *n1, const char *n2) 1144 static int same_name(const char *n1, const char *n2)
1145 { 1145 {
1146 return 0 == memcmp(n1, n2, HEXDIR_LEN); 1146 return 0 == memcmp(n1, n2, HEXDIR_LEN);
1147 } 1147 }
1148 1148
1149 static int 1149 static int
1150 same_verf(nfs4_verifier *v1, nfs4_verifier *v2) 1150 same_verf(nfs4_verifier *v1, nfs4_verifier *v2)
1151 { 1151 {
1152 return 0 == memcmp(v1->data, v2->data, sizeof(v1->data)); 1152 return 0 == memcmp(v1->data, v2->data, sizeof(v1->data));
1153 } 1153 }
1154 1154
1155 static int 1155 static int
1156 same_clid(clientid_t *cl1, clientid_t *cl2) 1156 same_clid(clientid_t *cl1, clientid_t *cl2)
1157 { 1157 {
1158 return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); 1158 return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id);
1159 } 1159 }
1160 1160
1161 /* XXX what about NGROUP */ 1161 /* XXX what about NGROUP */
1162 static int 1162 static int
1163 same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1163 same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1164 { 1164 {
1165 return cr1->cr_uid == cr2->cr_uid; 1165 return cr1->cr_uid == cr2->cr_uid;
1166 } 1166 }
1167 1167
1168 static void gen_clid(struct nfs4_client *clp) 1168 static void gen_clid(struct nfs4_client *clp)
1169 { 1169 {
1170 static u32 current_clientid = 1; 1170 static u32 current_clientid = 1;
1171 1171
1172 clp->cl_clientid.cl_boot = boot_time; 1172 clp->cl_clientid.cl_boot = boot_time;
1173 clp->cl_clientid.cl_id = current_clientid++; 1173 clp->cl_clientid.cl_id = current_clientid++;
1174 } 1174 }
1175 1175
1176 static void gen_confirm(struct nfs4_client *clp) 1176 static void gen_confirm(struct nfs4_client *clp)
1177 { 1177 {
1178 __be32 verf[2]; 1178 __be32 verf[2];
1179 static u32 i; 1179 static u32 i;
1180 1180
1181 verf[0] = (__be32)get_seconds(); 1181 verf[0] = (__be32)get_seconds();
1182 verf[1] = (__be32)i++; 1182 verf[1] = (__be32)i++;
1183 memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data)); 1183 memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
1184 } 1184 }
1185 1185
1186 static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t) 1186 static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t)
1187 { 1187 {
1188 return idr_find(&cl->cl_stateids, t->si_opaque.so_id); 1188 return idr_find(&cl->cl_stateids, t->si_opaque.so_id);
1189 } 1189 }
1190 1190
1191 static struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask) 1191 static struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask)
1192 { 1192 {
1193 struct nfs4_stid *s; 1193 struct nfs4_stid *s;
1194 1194
1195 s = find_stateid(cl, t); 1195 s = find_stateid(cl, t);
1196 if (!s) 1196 if (!s)
1197 return NULL; 1197 return NULL;
1198 if (typemask & s->sc_type) 1198 if (typemask & s->sc_type)
1199 return s; 1199 return s;
1200 return NULL; 1200 return NULL;
1201 } 1201 }
1202 1202
1203 static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, 1203 static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1204 struct svc_rqst *rqstp, nfs4_verifier *verf) 1204 struct svc_rqst *rqstp, nfs4_verifier *verf)
1205 { 1205 {
1206 struct nfs4_client *clp; 1206 struct nfs4_client *clp;
1207 struct sockaddr *sa = svc_addr(rqstp); 1207 struct sockaddr *sa = svc_addr(rqstp);
1208 char *princ; 1208 char *princ;
1209 1209
1210 clp = alloc_client(name); 1210 clp = alloc_client(name);
1211 if (clp == NULL) 1211 if (clp == NULL)
1212 return NULL; 1212 return NULL;
1213 1213
1214 INIT_LIST_HEAD(&clp->cl_sessions); 1214 INIT_LIST_HEAD(&clp->cl_sessions);
1215 1215
1216 princ = svc_gss_principal(rqstp); 1216 princ = svc_gss_principal(rqstp);
1217 if (princ) { 1217 if (princ) {
1218 clp->cl_principal = kstrdup(princ, GFP_KERNEL); 1218 clp->cl_principal = kstrdup(princ, GFP_KERNEL);
1219 if (clp->cl_principal == NULL) { 1219 if (clp->cl_principal == NULL) {
1220 spin_lock(&client_lock); 1220 spin_lock(&client_lock);
1221 free_client(clp); 1221 free_client(clp);
1222 spin_unlock(&client_lock); 1222 spin_unlock(&client_lock);
1223 return NULL; 1223 return NULL;
1224 } 1224 }
1225 } 1225 }
1226 1226
1227 idr_init(&clp->cl_stateids); 1227 idr_init(&clp->cl_stateids);
1228 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 1228 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
1229 atomic_set(&clp->cl_refcount, 0); 1229 atomic_set(&clp->cl_refcount, 0);
1230 clp->cl_cb_state = NFSD4_CB_UNKNOWN; 1230 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
1231 INIT_LIST_HEAD(&clp->cl_idhash); 1231 INIT_LIST_HEAD(&clp->cl_idhash);
1232 INIT_LIST_HEAD(&clp->cl_strhash); 1232 INIT_LIST_HEAD(&clp->cl_strhash);
1233 INIT_LIST_HEAD(&clp->cl_openowners); 1233 INIT_LIST_HEAD(&clp->cl_openowners);
1234 INIT_LIST_HEAD(&clp->cl_delegations); 1234 INIT_LIST_HEAD(&clp->cl_delegations);
1235 INIT_LIST_HEAD(&clp->cl_lru); 1235 INIT_LIST_HEAD(&clp->cl_lru);
1236 INIT_LIST_HEAD(&clp->cl_callbacks); 1236 INIT_LIST_HEAD(&clp->cl_callbacks);
1237 spin_lock_init(&clp->cl_lock); 1237 spin_lock_init(&clp->cl_lock);
1238 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); 1238 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
1239 clp->cl_time = get_seconds(); 1239 clp->cl_time = get_seconds();
1240 clear_bit(0, &clp->cl_cb_slot_busy); 1240 clear_bit(0, &clp->cl_cb_slot_busy);
1241 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 1241 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
1242 copy_verf(clp, verf); 1242 copy_verf(clp, verf);
1243 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); 1243 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
1244 clp->cl_flavor = rqstp->rq_flavor; 1244 clp->cl_flavor = rqstp->rq_flavor;
1245 copy_cred(&clp->cl_cred, &rqstp->rq_cred); 1245 copy_cred(&clp->cl_cred, &rqstp->rq_cred);
1246 gen_confirm(clp); 1246 gen_confirm(clp);
1247 clp->cl_cb_session = NULL; 1247 clp->cl_cb_session = NULL;
1248 return clp; 1248 return clp;
1249 } 1249 }
1250 1250
1251 static void 1251 static void
1252 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) 1252 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
1253 { 1253 {
1254 unsigned int idhashval; 1254 unsigned int idhashval;
1255 1255
1256 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]); 1256 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
1257 idhashval = clientid_hashval(clp->cl_clientid.cl_id); 1257 idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1258 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]); 1258 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
1259 renew_client(clp); 1259 renew_client(clp);
1260 } 1260 }
1261 1261
1262 static void 1262 static void
1263 move_to_confirmed(struct nfs4_client *clp) 1263 move_to_confirmed(struct nfs4_client *clp)
1264 { 1264 {
1265 unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id); 1265 unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1266 unsigned int strhashval; 1266 unsigned int strhashval;
1267 1267
1268 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); 1268 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
1269 list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); 1269 list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
1270 strhashval = clientstr_hashval(clp->cl_recdir); 1270 strhashval = clientstr_hashval(clp->cl_recdir);
1271 list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); 1271 list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
1272 renew_client(clp); 1272 renew_client(clp);
1273 } 1273 }
1274 1274
1275 static struct nfs4_client * 1275 static struct nfs4_client *
1276 find_confirmed_client(clientid_t *clid) 1276 find_confirmed_client(clientid_t *clid)
1277 { 1277 {
1278 struct nfs4_client *clp; 1278 struct nfs4_client *clp;
1279 unsigned int idhashval = clientid_hashval(clid->cl_id); 1279 unsigned int idhashval = clientid_hashval(clid->cl_id);
1280 1280
1281 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) { 1281 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1282 if (same_clid(&clp->cl_clientid, clid)) { 1282 if (same_clid(&clp->cl_clientid, clid)) {
1283 renew_client(clp); 1283 renew_client(clp);
1284 return clp; 1284 return clp;
1285 } 1285 }
1286 } 1286 }
1287 return NULL; 1287 return NULL;
1288 } 1288 }
1289 1289
1290 static struct nfs4_client * 1290 static struct nfs4_client *
1291 find_unconfirmed_client(clientid_t *clid) 1291 find_unconfirmed_client(clientid_t *clid)
1292 { 1292 {
1293 struct nfs4_client *clp; 1293 struct nfs4_client *clp;
1294 unsigned int idhashval = clientid_hashval(clid->cl_id); 1294 unsigned int idhashval = clientid_hashval(clid->cl_id);
1295 1295
1296 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) { 1296 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
1297 if (same_clid(&clp->cl_clientid, clid)) 1297 if (same_clid(&clp->cl_clientid, clid))
1298 return clp; 1298 return clp;
1299 } 1299 }
1300 return NULL; 1300 return NULL;
1301 } 1301 }
1302 1302
1303 static bool clp_used_exchangeid(struct nfs4_client *clp) 1303 static bool clp_used_exchangeid(struct nfs4_client *clp)
1304 { 1304 {
1305 return clp->cl_exchange_flags != 0; 1305 return clp->cl_exchange_flags != 0;
1306 } 1306 }
1307 1307
1308 static struct nfs4_client * 1308 static struct nfs4_client *
1309 find_confirmed_client_by_str(const char *dname, unsigned int hashval) 1309 find_confirmed_client_by_str(const char *dname, unsigned int hashval)
1310 { 1310 {
1311 struct nfs4_client *clp; 1311 struct nfs4_client *clp;
1312 1312
1313 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { 1313 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
1314 if (same_name(clp->cl_recdir, dname)) 1314 if (same_name(clp->cl_recdir, dname))
1315 return clp; 1315 return clp;
1316 } 1316 }
1317 return NULL; 1317 return NULL;
1318 } 1318 }
1319 1319
1320 static struct nfs4_client * 1320 static struct nfs4_client *
1321 find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) 1321 find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
1322 { 1322 {
1323 struct nfs4_client *clp; 1323 struct nfs4_client *clp;
1324 1324
1325 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { 1325 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
1326 if (same_name(clp->cl_recdir, dname)) 1326 if (same_name(clp->cl_recdir, dname))
1327 return clp; 1327 return clp;
1328 } 1328 }
1329 return NULL; 1329 return NULL;
1330 } 1330 }
1331 1331
1332 static void 1332 static void
1333 gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp) 1333 gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
1334 { 1334 {
1335 struct nfs4_cb_conn *conn = &clp->cl_cb_conn; 1335 struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
1336 struct sockaddr *sa = svc_addr(rqstp); 1336 struct sockaddr *sa = svc_addr(rqstp);
1337 u32 scopeid = rpc_get_scope_id(sa); 1337 u32 scopeid = rpc_get_scope_id(sa);
1338 unsigned short expected_family; 1338 unsigned short expected_family;
1339 1339
1340 /* Currently, we only support tcp and tcp6 for the callback channel */ 1340 /* Currently, we only support tcp and tcp6 for the callback channel */
1341 if (se->se_callback_netid_len == 3 && 1341 if (se->se_callback_netid_len == 3 &&
1342 !memcmp(se->se_callback_netid_val, "tcp", 3)) 1342 !memcmp(se->se_callback_netid_val, "tcp", 3))
1343 expected_family = AF_INET; 1343 expected_family = AF_INET;
1344 else if (se->se_callback_netid_len == 4 && 1344 else if (se->se_callback_netid_len == 4 &&
1345 !memcmp(se->se_callback_netid_val, "tcp6", 4)) 1345 !memcmp(se->se_callback_netid_val, "tcp6", 4))
1346 expected_family = AF_INET6; 1346 expected_family = AF_INET6;
1347 else 1347 else
1348 goto out_err; 1348 goto out_err;
1349 1349
1350 conn->cb_addrlen = rpc_uaddr2sockaddr(&init_net, se->se_callback_addr_val, 1350 conn->cb_addrlen = rpc_uaddr2sockaddr(&init_net, se->se_callback_addr_val,
1351 se->se_callback_addr_len, 1351 se->se_callback_addr_len,
1352 (struct sockaddr *)&conn->cb_addr, 1352 (struct sockaddr *)&conn->cb_addr,
1353 sizeof(conn->cb_addr)); 1353 sizeof(conn->cb_addr));
1354 1354
1355 if (!conn->cb_addrlen || conn->cb_addr.ss_family != expected_family) 1355 if (!conn->cb_addrlen || conn->cb_addr.ss_family != expected_family)
1356 goto out_err; 1356 goto out_err;
1357 1357
1358 if (conn->cb_addr.ss_family == AF_INET6) 1358 if (conn->cb_addr.ss_family == AF_INET6)
1359 ((struct sockaddr_in6 *)&conn->cb_addr)->sin6_scope_id = scopeid; 1359 ((struct sockaddr_in6 *)&conn->cb_addr)->sin6_scope_id = scopeid;
1360 1360
1361 conn->cb_prog = se->se_callback_prog; 1361 conn->cb_prog = se->se_callback_prog;
1362 conn->cb_ident = se->se_callback_ident; 1362 conn->cb_ident = se->se_callback_ident;
1363 memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen); 1363 memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen);
1364 return; 1364 return;
1365 out_err: 1365 out_err:
1366 conn->cb_addr.ss_family = AF_UNSPEC; 1366 conn->cb_addr.ss_family = AF_UNSPEC;
1367 conn->cb_addrlen = 0; 1367 conn->cb_addrlen = 0;
1368 dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " 1368 dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
1369 "will not receive delegations\n", 1369 "will not receive delegations\n",
1370 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); 1370 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
1371 1371
1372 return; 1372 return;
1373 } 1373 }
1374 1374
1375 /* 1375 /*
1376 * Cache a reply. nfsd4_check_drc_limit() has bounded the cache size. 1376 * Cache a reply. nfsd4_check_drc_limit() has bounded the cache size.
1377 */ 1377 */
1378 void 1378 void
1379 nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) 1379 nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
1380 { 1380 {
1381 struct nfsd4_slot *slot = resp->cstate.slot; 1381 struct nfsd4_slot *slot = resp->cstate.slot;
1382 unsigned int base; 1382 unsigned int base;
1383 1383
1384 dprintk("--> %s slot %p\n", __func__, slot); 1384 dprintk("--> %s slot %p\n", __func__, slot);
1385 1385
1386 slot->sl_opcnt = resp->opcnt; 1386 slot->sl_opcnt = resp->opcnt;
1387 slot->sl_status = resp->cstate.status; 1387 slot->sl_status = resp->cstate.status;
1388 1388
1389 slot->sl_flags |= NFSD4_SLOT_INITIALIZED; 1389 slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
1390 if (nfsd4_not_cached(resp)) { 1390 if (nfsd4_not_cached(resp)) {
1391 slot->sl_datalen = 0; 1391 slot->sl_datalen = 0;
1392 return; 1392 return;
1393 } 1393 }
1394 slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap; 1394 slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap;
1395 base = (char *)resp->cstate.datap - 1395 base = (char *)resp->cstate.datap -
1396 (char *)resp->xbuf->head[0].iov_base; 1396 (char *)resp->xbuf->head[0].iov_base;
1397 if (read_bytes_from_xdr_buf(resp->xbuf, base, slot->sl_data, 1397 if (read_bytes_from_xdr_buf(resp->xbuf, base, slot->sl_data,
1398 slot->sl_datalen)) 1398 slot->sl_datalen))
1399 WARN("%s: sessions DRC could not cache compound\n", __func__); 1399 WARN("%s: sessions DRC could not cache compound\n", __func__);
1400 return; 1400 return;
1401 } 1401 }
1402 1402
1403 /* 1403 /*
1404 * Encode the replay sequence operation from the slot values. 1404 * Encode the replay sequence operation from the slot values.
1405 * If cachethis is FALSE encode the uncached rep error on the next 1405 * If cachethis is FALSE encode the uncached rep error on the next
1406 * operation which sets resp->p and increments resp->opcnt for 1406 * operation which sets resp->p and increments resp->opcnt for
1407 * nfs4svc_encode_compoundres. 1407 * nfs4svc_encode_compoundres.
1408 * 1408 *
1409 */ 1409 */
1410 static __be32 1410 static __be32
1411 nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args, 1411 nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
1412 struct nfsd4_compoundres *resp) 1412 struct nfsd4_compoundres *resp)
1413 { 1413 {
1414 struct nfsd4_op *op; 1414 struct nfsd4_op *op;
1415 struct nfsd4_slot *slot = resp->cstate.slot; 1415 struct nfsd4_slot *slot = resp->cstate.slot;
1416 1416
1417 /* Encode the replayed sequence operation */ 1417 /* Encode the replayed sequence operation */
1418 op = &args->ops[resp->opcnt - 1]; 1418 op = &args->ops[resp->opcnt - 1];
1419 nfsd4_encode_operation(resp, op); 1419 nfsd4_encode_operation(resp, op);
1420 1420
1421 /* Return nfserr_retry_uncached_rep in next operation. */ 1421 /* Return nfserr_retry_uncached_rep in next operation. */
1422 if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) { 1422 if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
1423 op = &args->ops[resp->opcnt++]; 1423 op = &args->ops[resp->opcnt++];
1424 op->status = nfserr_retry_uncached_rep; 1424 op->status = nfserr_retry_uncached_rep;
1425 nfsd4_encode_operation(resp, op); 1425 nfsd4_encode_operation(resp, op);
1426 } 1426 }
1427 return op->status; 1427 return op->status;
1428 } 1428 }
1429 1429
1430 /* 1430 /*
1431 * The sequence operation is not cached because we can use the slot and 1431 * The sequence operation is not cached because we can use the slot and
1432 * session values. 1432 * session values.
1433 */ 1433 */
1434 __be32 1434 __be32
1435 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, 1435 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1436 struct nfsd4_sequence *seq) 1436 struct nfsd4_sequence *seq)
1437 { 1437 {
1438 struct nfsd4_slot *slot = resp->cstate.slot; 1438 struct nfsd4_slot *slot = resp->cstate.slot;
1439 __be32 status; 1439 __be32 status;
1440 1440
1441 dprintk("--> %s slot %p\n", __func__, slot); 1441 dprintk("--> %s slot %p\n", __func__, slot);
1442 1442
1443 /* Either returns 0 or nfserr_retry_uncached */ 1443 /* Either returns 0 or nfserr_retry_uncached */
1444 status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp); 1444 status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
1445 if (status == nfserr_retry_uncached_rep) 1445 if (status == nfserr_retry_uncached_rep)
1446 return status; 1446 return status;
1447 1447
1448 /* The sequence operation has been encoded, cstate->datap set. */ 1448 /* The sequence operation has been encoded, cstate->datap set. */
1449 memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen); 1449 memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen);
1450 1450
1451 resp->opcnt = slot->sl_opcnt; 1451 resp->opcnt = slot->sl_opcnt;
1452 resp->p = resp->cstate.datap + XDR_QUADLEN(slot->sl_datalen); 1452 resp->p = resp->cstate.datap + XDR_QUADLEN(slot->sl_datalen);
1453 status = slot->sl_status; 1453 status = slot->sl_status;
1454 1454
1455 return status; 1455 return status;
1456 } 1456 }
1457 1457
1458 /* 1458 /*
1459 * Set the exchange_id flags returned by the server. 1459 * Set the exchange_id flags returned by the server.
1460 */ 1460 */
1461 static void 1461 static void
1462 nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid) 1462 nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
1463 { 1463 {
1464 /* pNFS is not supported */ 1464 /* pNFS is not supported */
1465 new->cl_exchange_flags |= EXCHGID4_FLAG_USE_NON_PNFS; 1465 new->cl_exchange_flags |= EXCHGID4_FLAG_USE_NON_PNFS;
1466 1466
1467 /* Referrals are supported, Migration is not. */ 1467 /* Referrals are supported, Migration is not. */
1468 new->cl_exchange_flags |= EXCHGID4_FLAG_SUPP_MOVED_REFER; 1468 new->cl_exchange_flags |= EXCHGID4_FLAG_SUPP_MOVED_REFER;
1469 1469
1470 /* set the wire flags to return to client. */ 1470 /* set the wire flags to return to client. */
1471 clid->flags = new->cl_exchange_flags; 1471 clid->flags = new->cl_exchange_flags;
1472 } 1472 }
1473 1473
1474 __be32 1474 __be32
1475 nfsd4_exchange_id(struct svc_rqst *rqstp, 1475 nfsd4_exchange_id(struct svc_rqst *rqstp,
1476 struct nfsd4_compound_state *cstate, 1476 struct nfsd4_compound_state *cstate,
1477 struct nfsd4_exchange_id *exid) 1477 struct nfsd4_exchange_id *exid)
1478 { 1478 {
1479 struct nfs4_client *unconf, *conf, *new; 1479 struct nfs4_client *unconf, *conf, *new;
1480 int status; 1480 __be32 status;
1481 unsigned int strhashval; 1481 unsigned int strhashval;
1482 char dname[HEXDIR_LEN]; 1482 char dname[HEXDIR_LEN];
1483 char addr_str[INET6_ADDRSTRLEN]; 1483 char addr_str[INET6_ADDRSTRLEN];
1484 nfs4_verifier verf = exid->verifier; 1484 nfs4_verifier verf = exid->verifier;
1485 struct sockaddr *sa = svc_addr(rqstp); 1485 struct sockaddr *sa = svc_addr(rqstp);
1486 1486
1487 rpc_ntop(sa, addr_str, sizeof(addr_str)); 1487 rpc_ntop(sa, addr_str, sizeof(addr_str));
1488 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p " 1488 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
1489 "ip_addr=%s flags %x, spa_how %d\n", 1489 "ip_addr=%s flags %x, spa_how %d\n",
1490 __func__, rqstp, exid, exid->clname.len, exid->clname.data, 1490 __func__, rqstp, exid, exid->clname.len, exid->clname.data,
1491 addr_str, exid->flags, exid->spa_how); 1491 addr_str, exid->flags, exid->spa_how);
1492 1492
1493 if (exid->flags & ~EXCHGID4_FLAG_MASK_A) 1493 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
1494 return nfserr_inval; 1494 return nfserr_inval;
1495 1495
1496 /* Currently only support SP4_NONE */ 1496 /* Currently only support SP4_NONE */
1497 switch (exid->spa_how) { 1497 switch (exid->spa_how) {
1498 case SP4_NONE: 1498 case SP4_NONE:
1499 break; 1499 break;
1500 case SP4_SSV: 1500 case SP4_SSV:
1501 return nfserr_serverfault; 1501 return nfserr_serverfault;
1502 default: 1502 default:
1503 BUG(); /* checked by xdr code */ 1503 BUG(); /* checked by xdr code */
1504 case SP4_MACH_CRED: 1504 case SP4_MACH_CRED:
1505 return nfserr_serverfault; /* no excuse :-/ */ 1505 return nfserr_serverfault; /* no excuse :-/ */
1506 } 1506 }
1507 1507
1508 status = nfs4_make_rec_clidname(dname, &exid->clname); 1508 status = nfs4_make_rec_clidname(dname, &exid->clname);
1509 1509
1510 if (status) 1510 if (status)
1511 goto error; 1511 goto error;
1512 1512
1513 strhashval = clientstr_hashval(dname); 1513 strhashval = clientstr_hashval(dname);
1514 1514
1515 nfs4_lock_state(); 1515 nfs4_lock_state();
1516 status = nfs_ok; 1516 status = nfs_ok;
1517 1517
1518 conf = find_confirmed_client_by_str(dname, strhashval); 1518 conf = find_confirmed_client_by_str(dname, strhashval);
1519 if (conf) { 1519 if (conf) {
1520 if (!clp_used_exchangeid(conf)) { 1520 if (!clp_used_exchangeid(conf)) {
1521 status = nfserr_clid_inuse; /* XXX: ? */ 1521 status = nfserr_clid_inuse; /* XXX: ? */
1522 goto out; 1522 goto out;
1523 } 1523 }
1524 if (!same_verf(&verf, &conf->cl_verifier)) { 1524 if (!same_verf(&verf, &conf->cl_verifier)) {
1525 /* 18.35.4 case 8 */ 1525 /* 18.35.4 case 8 */
1526 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1526 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
1527 status = nfserr_not_same; 1527 status = nfserr_not_same;
1528 goto out; 1528 goto out;
1529 } 1529 }
1530 /* Client reboot: destroy old state */ 1530 /* Client reboot: destroy old state */
1531 expire_client(conf); 1531 expire_client(conf);
1532 goto out_new; 1532 goto out_new;
1533 } 1533 }
1534 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { 1534 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
1535 /* 18.35.4 case 9 */ 1535 /* 18.35.4 case 9 */
1536 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1536 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
1537 status = nfserr_perm; 1537 status = nfserr_perm;
1538 goto out; 1538 goto out;
1539 } 1539 }
1540 expire_client(conf); 1540 expire_client(conf);
1541 goto out_new; 1541 goto out_new;
1542 } 1542 }
1543 /* 1543 /*
1544 * Set bit when the owner id and verifier map to an already 1544 * Set bit when the owner id and verifier map to an already
1545 * confirmed client id (18.35.3). 1545 * confirmed client id (18.35.3).
1546 */ 1546 */
1547 exid->flags |= EXCHGID4_FLAG_CONFIRMED_R; 1547 exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
1548 1548
1549 /* 1549 /*
1550 * Falling into 18.35.4 case 2, possible router replay. 1550 * Falling into 18.35.4 case 2, possible router replay.
1551 * Leave confirmed record intact and return same result. 1551 * Leave confirmed record intact and return same result.
1552 */ 1552 */
1553 copy_verf(conf, &verf); 1553 copy_verf(conf, &verf);
1554 new = conf; 1554 new = conf;
1555 goto out_copy; 1555 goto out_copy;
1556 } 1556 }
1557 1557
1558 /* 18.35.4 case 7 */ 1558 /* 18.35.4 case 7 */
1559 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1559 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
1560 status = nfserr_noent; 1560 status = nfserr_noent;
1561 goto out; 1561 goto out;
1562 } 1562 }
1563 1563
1564 unconf = find_unconfirmed_client_by_str(dname, strhashval); 1564 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1565 if (unconf) { 1565 if (unconf) {
1566 /* 1566 /*
1567 * Possible retry or client restart. Per 18.35.4 case 4, 1567 * Possible retry or client restart. Per 18.35.4 case 4,
1568 * a new unconfirmed record should be generated regardless 1568 * a new unconfirmed record should be generated regardless
1569 * of whether any properties have changed. 1569 * of whether any properties have changed.
1570 */ 1570 */
1571 expire_client(unconf); 1571 expire_client(unconf);
1572 } 1572 }
1573 1573
1574 out_new: 1574 out_new:
1575 /* Normal case */ 1575 /* Normal case */
1576 new = create_client(exid->clname, dname, rqstp, &verf); 1576 new = create_client(exid->clname, dname, rqstp, &verf);
1577 if (new == NULL) { 1577 if (new == NULL) {
1578 status = nfserr_jukebox; 1578 status = nfserr_jukebox;
1579 goto out; 1579 goto out;
1580 } 1580 }
1581 1581
1582 gen_clid(new); 1582 gen_clid(new);
1583 add_to_unconfirmed(new, strhashval); 1583 add_to_unconfirmed(new, strhashval);
1584 out_copy: 1584 out_copy:
1585 exid->clientid.cl_boot = new->cl_clientid.cl_boot; 1585 exid->clientid.cl_boot = new->cl_clientid.cl_boot;
1586 exid->clientid.cl_id = new->cl_clientid.cl_id; 1586 exid->clientid.cl_id = new->cl_clientid.cl_id;
1587 1587
1588 exid->seqid = 1; 1588 exid->seqid = 1;
1589 nfsd4_set_ex_flags(new, exid); 1589 nfsd4_set_ex_flags(new, exid);
1590 1590
1591 dprintk("nfsd4_exchange_id seqid %d flags %x\n", 1591 dprintk("nfsd4_exchange_id seqid %d flags %x\n",
1592 new->cl_cs_slot.sl_seqid, new->cl_exchange_flags); 1592 new->cl_cs_slot.sl_seqid, new->cl_exchange_flags);
1593 status = nfs_ok; 1593 status = nfs_ok;
1594 1594
1595 out: 1595 out:
1596 nfs4_unlock_state(); 1596 nfs4_unlock_state();
1597 error: 1597 error:
1598 dprintk("nfsd4_exchange_id returns %d\n", ntohl(status)); 1598 dprintk("nfsd4_exchange_id returns %d\n", ntohl(status));
1599 return status; 1599 return status;
1600 } 1600 }
1601 1601
1602 static int 1602 static __be32
1603 check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse) 1603 check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
1604 { 1604 {
1605 dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid, 1605 dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
1606 slot_seqid); 1606 slot_seqid);
1607 1607
1608 /* The slot is in use, and no response has been sent. */ 1608 /* The slot is in use, and no response has been sent. */
1609 if (slot_inuse) { 1609 if (slot_inuse) {
1610 if (seqid == slot_seqid) 1610 if (seqid == slot_seqid)
1611 return nfserr_jukebox; 1611 return nfserr_jukebox;
1612 else 1612 else
1613 return nfserr_seq_misordered; 1613 return nfserr_seq_misordered;
1614 } 1614 }
1615 /* Note unsigned 32-bit arithmetic handles wraparound: */ 1615 /* Note unsigned 32-bit arithmetic handles wraparound: */
1616 if (likely(seqid == slot_seqid + 1)) 1616 if (likely(seqid == slot_seqid + 1))
1617 return nfs_ok; 1617 return nfs_ok;
1618 if (seqid == slot_seqid) 1618 if (seqid == slot_seqid)
1619 return nfserr_replay_cache; 1619 return nfserr_replay_cache;
1620 return nfserr_seq_misordered; 1620 return nfserr_seq_misordered;
1621 } 1621 }
1622 1622
1623 /* 1623 /*
1624 * Cache the create session result into the create session single DRC 1624 * Cache the create session result into the create session single DRC
1625 * slot cache by saving the xdr structure. sl_seqid has been set. 1625 * slot cache by saving the xdr structure. sl_seqid has been set.
1626 * Do this for solo or embedded create session operations. 1626 * Do this for solo or embedded create session operations.
1627 */ 1627 */
1628 static void 1628 static void
1629 nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses, 1629 nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses,
1630 struct nfsd4_clid_slot *slot, int nfserr) 1630 struct nfsd4_clid_slot *slot, __be32 nfserr)
1631 { 1631 {
1632 slot->sl_status = nfserr; 1632 slot->sl_status = nfserr;
1633 memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses)); 1633 memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses));
1634 } 1634 }
1635 1635
1636 static __be32 1636 static __be32
1637 nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses, 1637 nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
1638 struct nfsd4_clid_slot *slot) 1638 struct nfsd4_clid_slot *slot)
1639 { 1639 {
1640 memcpy(cr_ses, &slot->sl_cr_ses, sizeof(*cr_ses)); 1640 memcpy(cr_ses, &slot->sl_cr_ses, sizeof(*cr_ses));
1641 return slot->sl_status; 1641 return slot->sl_status;
1642 } 1642 }
1643 1643
1644 #define NFSD_MIN_REQ_HDR_SEQ_SZ ((\ 1644 #define NFSD_MIN_REQ_HDR_SEQ_SZ ((\
1645 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \ 1645 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \
1646 1 + /* MIN tag is length with zero, only length */ \ 1646 1 + /* MIN tag is length with zero, only length */ \
1647 3 + /* version, opcount, opcode */ \ 1647 3 + /* version, opcount, opcode */ \
1648 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 1648 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
1649 /* seqid, slotID, slotID, cache */ \ 1649 /* seqid, slotID, slotID, cache */ \
1650 4 ) * sizeof(__be32)) 1650 4 ) * sizeof(__be32))
1651 1651
1652 #define NFSD_MIN_RESP_HDR_SEQ_SZ ((\ 1652 #define NFSD_MIN_RESP_HDR_SEQ_SZ ((\
1653 2 + /* verifier: AUTH_NULL, length 0 */\ 1653 2 + /* verifier: AUTH_NULL, length 0 */\
1654 1 + /* status */ \ 1654 1 + /* status */ \
1655 1 + /* MIN tag is length with zero, only length */ \ 1655 1 + /* MIN tag is length with zero, only length */ \
1656 3 + /* opcount, opcode, opstatus*/ \ 1656 3 + /* opcount, opcode, opstatus*/ \
1657 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 1657 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
1658 /* seqid, slotID, slotID, slotID, status */ \ 1658 /* seqid, slotID, slotID, slotID, status */ \
1659 5 ) * sizeof(__be32)) 1659 5 ) * sizeof(__be32))
1660 1660
1661 static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel) 1661 static bool check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
1662 { 1662 {
1663 return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ 1663 return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
1664 || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ; 1664 || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
1665 } 1665 }
1666 1666
1667 __be32 1667 __be32
1668 nfsd4_create_session(struct svc_rqst *rqstp, 1668 nfsd4_create_session(struct svc_rqst *rqstp,
1669 struct nfsd4_compound_state *cstate, 1669 struct nfsd4_compound_state *cstate,
1670 struct nfsd4_create_session *cr_ses) 1670 struct nfsd4_create_session *cr_ses)
1671 { 1671 {
1672 struct sockaddr *sa = svc_addr(rqstp); 1672 struct sockaddr *sa = svc_addr(rqstp);
1673 struct nfs4_client *conf, *unconf; 1673 struct nfs4_client *conf, *unconf;
1674 struct nfsd4_session *new; 1674 struct nfsd4_session *new;
1675 struct nfsd4_clid_slot *cs_slot = NULL; 1675 struct nfsd4_clid_slot *cs_slot = NULL;
1676 bool confirm_me = false; 1676 bool confirm_me = false;
1677 int status = 0; 1677 __be32 status = 0;
1678 1678
1679 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1679 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
1680 return nfserr_inval; 1680 return nfserr_inval;
1681 1681
1682 nfs4_lock_state(); 1682 nfs4_lock_state();
1683 unconf = find_unconfirmed_client(&cr_ses->clientid); 1683 unconf = find_unconfirmed_client(&cr_ses->clientid);
1684 conf = find_confirmed_client(&cr_ses->clientid); 1684 conf = find_confirmed_client(&cr_ses->clientid);
1685 1685
1686 if (conf) { 1686 if (conf) {
1687 cs_slot = &conf->cl_cs_slot; 1687 cs_slot = &conf->cl_cs_slot;
1688 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1688 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1689 if (status == nfserr_replay_cache) { 1689 if (status == nfserr_replay_cache) {
1690 dprintk("Got a create_session replay! seqid= %d\n", 1690 dprintk("Got a create_session replay! seqid= %d\n",
1691 cs_slot->sl_seqid); 1691 cs_slot->sl_seqid);
1692 /* Return the cached reply status */ 1692 /* Return the cached reply status */
1693 status = nfsd4_replay_create_session(cr_ses, cs_slot); 1693 status = nfsd4_replay_create_session(cr_ses, cs_slot);
1694 goto out; 1694 goto out;
1695 } else if (cr_ses->seqid != cs_slot->sl_seqid + 1) { 1695 } else if (cr_ses->seqid != cs_slot->sl_seqid + 1) {
1696 status = nfserr_seq_misordered; 1696 status = nfserr_seq_misordered;
1697 dprintk("Sequence misordered!\n"); 1697 dprintk("Sequence misordered!\n");
1698 dprintk("Expected seqid= %d but got seqid= %d\n", 1698 dprintk("Expected seqid= %d but got seqid= %d\n",
1699 cs_slot->sl_seqid, cr_ses->seqid); 1699 cs_slot->sl_seqid, cr_ses->seqid);
1700 goto out; 1700 goto out;
1701 } 1701 }
1702 } else if (unconf) { 1702 } else if (unconf) {
1703 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) || 1703 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
1704 !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) { 1704 !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
1705 status = nfserr_clid_inuse; 1705 status = nfserr_clid_inuse;
1706 goto out; 1706 goto out;
1707 } 1707 }
1708 1708
1709 cs_slot = &unconf->cl_cs_slot; 1709 cs_slot = &unconf->cl_cs_slot;
1710 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1710 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1711 if (status) { 1711 if (status) {
1712 /* an unconfirmed replay returns misordered */ 1712 /* an unconfirmed replay returns misordered */
1713 status = nfserr_seq_misordered; 1713 status = nfserr_seq_misordered;
1714 goto out; 1714 goto out;
1715 } 1715 }
1716 1716
1717 confirm_me = true; 1717 confirm_me = true;
1718 conf = unconf; 1718 conf = unconf;
1719 } else { 1719 } else {
1720 status = nfserr_stale_clientid; 1720 status = nfserr_stale_clientid;
1721 goto out; 1721 goto out;
1722 } 1722 }
1723 1723
1724 /* 1724 /*
1725 * XXX: we should probably set this at creation time, and check 1725 * XXX: we should probably set this at creation time, and check
1726 * for consistent minorversion use throughout: 1726 * for consistent minorversion use throughout:
1727 */ 1727 */
1728 conf->cl_minorversion = 1; 1728 conf->cl_minorversion = 1;
1729 /* 1729 /*
1730 * We do not support RDMA or persistent sessions 1730 * We do not support RDMA or persistent sessions
1731 */ 1731 */
1732 cr_ses->flags &= ~SESSION4_PERSIST; 1732 cr_ses->flags &= ~SESSION4_PERSIST;
1733 cr_ses->flags &= ~SESSION4_RDMA; 1733 cr_ses->flags &= ~SESSION4_RDMA;
1734 1734
1735 status = nfserr_toosmall; 1735 status = nfserr_toosmall;
1736 if (check_forechannel_attrs(cr_ses->fore_channel)) 1736 if (check_forechannel_attrs(cr_ses->fore_channel))
1737 goto out; 1737 goto out;
1738 1738
1739 status = nfserr_jukebox; 1739 status = nfserr_jukebox;
1740 new = alloc_init_session(rqstp, conf, cr_ses); 1740 new = alloc_init_session(rqstp, conf, cr_ses);
1741 if (!new) 1741 if (!new)
1742 goto out; 1742 goto out;
1743 status = nfs_ok; 1743 status = nfs_ok;
1744 memcpy(cr_ses->sessionid.data, new->se_sessionid.data, 1744 memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
1745 NFS4_MAX_SESSIONID_LEN); 1745 NFS4_MAX_SESSIONID_LEN);
1746 memcpy(&cr_ses->fore_channel, &new->se_fchannel, 1746 memcpy(&cr_ses->fore_channel, &new->se_fchannel,
1747 sizeof(struct nfsd4_channel_attrs)); 1747 sizeof(struct nfsd4_channel_attrs));
1748 cs_slot->sl_seqid++; 1748 cs_slot->sl_seqid++;
1749 cr_ses->seqid = cs_slot->sl_seqid; 1749 cr_ses->seqid = cs_slot->sl_seqid;
1750 1750
1751 /* cache solo and embedded create sessions under the state lock */ 1751 /* cache solo and embedded create sessions under the state lock */
1752 nfsd4_cache_create_session(cr_ses, cs_slot, status); 1752 nfsd4_cache_create_session(cr_ses, cs_slot, status);
1753 if (confirm_me) 1753 if (confirm_me)
1754 move_to_confirmed(conf); 1754 move_to_confirmed(conf);
1755 out: 1755 out:
1756 nfs4_unlock_state(); 1756 nfs4_unlock_state();
1757 dprintk("%s returns %d\n", __func__, ntohl(status)); 1757 dprintk("%s returns %d\n", __func__, ntohl(status));
1758 return status; 1758 return status;
1759 } 1759 }
1760 1760
1761 static bool nfsd4_last_compound_op(struct svc_rqst *rqstp) 1761 static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
1762 { 1762 {
1763 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1763 struct nfsd4_compoundres *resp = rqstp->rq_resp;
1764 struct nfsd4_compoundargs *argp = rqstp->rq_argp; 1764 struct nfsd4_compoundargs *argp = rqstp->rq_argp;
1765 1765
1766 return argp->opcnt == resp->opcnt; 1766 return argp->opcnt == resp->opcnt;
1767 } 1767 }
1768 1768
1769 static __be32 nfsd4_map_bcts_dir(u32 *dir) 1769 static __be32 nfsd4_map_bcts_dir(u32 *dir)
1770 { 1770 {
1771 switch (*dir) { 1771 switch (*dir) {
1772 case NFS4_CDFC4_FORE: 1772 case NFS4_CDFC4_FORE:
1773 case NFS4_CDFC4_BACK: 1773 case NFS4_CDFC4_BACK:
1774 return nfs_ok; 1774 return nfs_ok;
1775 case NFS4_CDFC4_FORE_OR_BOTH: 1775 case NFS4_CDFC4_FORE_OR_BOTH:
1776 case NFS4_CDFC4_BACK_OR_BOTH: 1776 case NFS4_CDFC4_BACK_OR_BOTH:
1777 *dir = NFS4_CDFC4_BOTH; 1777 *dir = NFS4_CDFC4_BOTH;
1778 return nfs_ok; 1778 return nfs_ok;
1779 }; 1779 };
1780 return nfserr_inval; 1780 return nfserr_inval;
1781 } 1781 }
1782 1782
1783 __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, 1783 __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1784 struct nfsd4_compound_state *cstate, 1784 struct nfsd4_compound_state *cstate,
1785 struct nfsd4_bind_conn_to_session *bcts) 1785 struct nfsd4_bind_conn_to_session *bcts)
1786 { 1786 {
1787 __be32 status; 1787 __be32 status;
1788 1788
1789 if (!nfsd4_last_compound_op(rqstp)) 1789 if (!nfsd4_last_compound_op(rqstp))
1790 return nfserr_not_only_op; 1790 return nfserr_not_only_op;
1791 spin_lock(&client_lock); 1791 spin_lock(&client_lock);
1792 cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid); 1792 cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid);
1793 /* Sorta weird: we only need the refcnt'ing because new_conn acquires 1793 /* Sorta weird: we only need the refcnt'ing because new_conn acquires
1794 * client_lock iself: */ 1794 * client_lock iself: */
1795 if (cstate->session) { 1795 if (cstate->session) {
1796 nfsd4_get_session(cstate->session); 1796 nfsd4_get_session(cstate->session);
1797 atomic_inc(&cstate->session->se_client->cl_refcount); 1797 atomic_inc(&cstate->session->se_client->cl_refcount);
1798 } 1798 }
1799 spin_unlock(&client_lock); 1799 spin_unlock(&client_lock);
1800 if (!cstate->session) 1800 if (!cstate->session)
1801 return nfserr_badsession; 1801 return nfserr_badsession;
1802 1802
1803 status = nfsd4_map_bcts_dir(&bcts->dir); 1803 status = nfsd4_map_bcts_dir(&bcts->dir);
1804 if (!status) 1804 if (!status)
1805 nfsd4_new_conn(rqstp, cstate->session, bcts->dir); 1805 nfsd4_new_conn(rqstp, cstate->session, bcts->dir);
1806 return status; 1806 return status;
1807 } 1807 }
1808 1808
1809 static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) 1809 static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
1810 { 1810 {
1811 if (!session) 1811 if (!session)
1812 return 0; 1812 return 0;
1813 return !memcmp(sid, &session->se_sessionid, sizeof(*sid)); 1813 return !memcmp(sid, &session->se_sessionid, sizeof(*sid));
1814 } 1814 }
1815 1815
1816 __be32 1816 __be32
1817 nfsd4_destroy_session(struct svc_rqst *r, 1817 nfsd4_destroy_session(struct svc_rqst *r,
1818 struct nfsd4_compound_state *cstate, 1818 struct nfsd4_compound_state *cstate,
1819 struct nfsd4_destroy_session *sessionid) 1819 struct nfsd4_destroy_session *sessionid)
1820 { 1820 {
1821 struct nfsd4_session *ses; 1821 struct nfsd4_session *ses;
1822 u32 status = nfserr_badsession; 1822 __be32 status = nfserr_badsession;
1823 1823
1824 /* Notes: 1824 /* Notes:
1825 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid 1825 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid
1826 * - Should we return nfserr_back_chan_busy if waiting for 1826 * - Should we return nfserr_back_chan_busy if waiting for
1827 * callbacks on to-be-destroyed session? 1827 * callbacks on to-be-destroyed session?
1828 * - Do we need to clear any callback info from previous session? 1828 * - Do we need to clear any callback info from previous session?
1829 */ 1829 */
1830 1830
1831 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) { 1831 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
1832 if (!nfsd4_last_compound_op(r)) 1832 if (!nfsd4_last_compound_op(r))
1833 return nfserr_not_only_op; 1833 return nfserr_not_only_op;
1834 } 1834 }
1835 dump_sessionid(__func__, &sessionid->sessionid); 1835 dump_sessionid(__func__, &sessionid->sessionid);
1836 spin_lock(&client_lock); 1836 spin_lock(&client_lock);
1837 ses = find_in_sessionid_hashtbl(&sessionid->sessionid); 1837 ses = find_in_sessionid_hashtbl(&sessionid->sessionid);
1838 if (!ses) { 1838 if (!ses) {
1839 spin_unlock(&client_lock); 1839 spin_unlock(&client_lock);
1840 goto out; 1840 goto out;
1841 } 1841 }
1842 1842
1843 unhash_session(ses); 1843 unhash_session(ses);
1844 spin_unlock(&client_lock); 1844 spin_unlock(&client_lock);
1845 1845
1846 nfs4_lock_state(); 1846 nfs4_lock_state();
1847 nfsd4_probe_callback_sync(ses->se_client); 1847 nfsd4_probe_callback_sync(ses->se_client);
1848 nfs4_unlock_state(); 1848 nfs4_unlock_state();
1849 1849
1850 spin_lock(&client_lock); 1850 spin_lock(&client_lock);
1851 nfsd4_del_conns(ses); 1851 nfsd4_del_conns(ses);
1852 nfsd4_put_session_locked(ses); 1852 nfsd4_put_session_locked(ses);
1853 spin_unlock(&client_lock); 1853 spin_unlock(&client_lock);
1854 status = nfs_ok; 1854 status = nfs_ok;
1855 out: 1855 out:
1856 dprintk("%s returns %d\n", __func__, ntohl(status)); 1856 dprintk("%s returns %d\n", __func__, ntohl(status));
1857 return status; 1857 return status;
1858 } 1858 }
1859 1859
1860 static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_session *s) 1860 static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_session *s)
1861 { 1861 {
1862 struct nfsd4_conn *c; 1862 struct nfsd4_conn *c;
1863 1863
1864 list_for_each_entry(c, &s->se_conns, cn_persession) { 1864 list_for_each_entry(c, &s->se_conns, cn_persession) {
1865 if (c->cn_xprt == xpt) { 1865 if (c->cn_xprt == xpt) {
1866 return c; 1866 return c;
1867 } 1867 }
1868 } 1868 }
1869 return NULL; 1869 return NULL;
1870 } 1870 }
1871 1871
1872 static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses) 1872 static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
1873 { 1873 {
1874 struct nfs4_client *clp = ses->se_client; 1874 struct nfs4_client *clp = ses->se_client;
1875 struct nfsd4_conn *c; 1875 struct nfsd4_conn *c;
1876 int ret; 1876 int ret;
1877 1877
1878 spin_lock(&clp->cl_lock); 1878 spin_lock(&clp->cl_lock);
1879 c = __nfsd4_find_conn(new->cn_xprt, ses); 1879 c = __nfsd4_find_conn(new->cn_xprt, ses);
1880 if (c) { 1880 if (c) {
1881 spin_unlock(&clp->cl_lock); 1881 spin_unlock(&clp->cl_lock);
1882 free_conn(new); 1882 free_conn(new);
1883 return; 1883 return;
1884 } 1884 }
1885 __nfsd4_hash_conn(new, ses); 1885 __nfsd4_hash_conn(new, ses);
1886 spin_unlock(&clp->cl_lock); 1886 spin_unlock(&clp->cl_lock);
1887 ret = nfsd4_register_conn(new); 1887 ret = nfsd4_register_conn(new);
1888 if (ret) 1888 if (ret)
1889 /* oops; xprt is already down: */ 1889 /* oops; xprt is already down: */
1890 nfsd4_conn_lost(&new->cn_xpt_user); 1890 nfsd4_conn_lost(&new->cn_xpt_user);
1891 return; 1891 return;
1892 } 1892 }
1893 1893
1894 static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session) 1894 static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session)
1895 { 1895 {
1896 struct nfsd4_compoundargs *args = rqstp->rq_argp; 1896 struct nfsd4_compoundargs *args = rqstp->rq_argp;
1897 1897
1898 return args->opcnt > session->se_fchannel.maxops; 1898 return args->opcnt > session->se_fchannel.maxops;
1899 } 1899 }
1900 1900
1901 static bool nfsd4_request_too_big(struct svc_rqst *rqstp, 1901 static bool nfsd4_request_too_big(struct svc_rqst *rqstp,
1902 struct nfsd4_session *session) 1902 struct nfsd4_session *session)
1903 { 1903 {
1904 struct xdr_buf *xb = &rqstp->rq_arg; 1904 struct xdr_buf *xb = &rqstp->rq_arg;
1905 1905
1906 return xb->len > session->se_fchannel.maxreq_sz; 1906 return xb->len > session->se_fchannel.maxreq_sz;
1907 } 1907 }
1908 1908
1909 __be32 1909 __be32
1910 nfsd4_sequence(struct svc_rqst *rqstp, 1910 nfsd4_sequence(struct svc_rqst *rqstp,
1911 struct nfsd4_compound_state *cstate, 1911 struct nfsd4_compound_state *cstate,
1912 struct nfsd4_sequence *seq) 1912 struct nfsd4_sequence *seq)
1913 { 1913 {
1914 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1914 struct nfsd4_compoundres *resp = rqstp->rq_resp;
1915 struct nfsd4_session *session; 1915 struct nfsd4_session *session;
1916 struct nfsd4_slot *slot; 1916 struct nfsd4_slot *slot;
1917 struct nfsd4_conn *conn; 1917 struct nfsd4_conn *conn;
1918 int status; 1918 __be32 status;
1919 1919
1920 if (resp->opcnt != 1) 1920 if (resp->opcnt != 1)
1921 return nfserr_sequence_pos; 1921 return nfserr_sequence_pos;
1922 1922
1923 /* 1923 /*
1924 * Will be either used or freed by nfsd4_sequence_check_conn 1924 * Will be either used or freed by nfsd4_sequence_check_conn
1925 * below. 1925 * below.
1926 */ 1926 */
1927 conn = alloc_conn(rqstp, NFS4_CDFC4_FORE); 1927 conn = alloc_conn(rqstp, NFS4_CDFC4_FORE);
1928 if (!conn) 1928 if (!conn)
1929 return nfserr_jukebox; 1929 return nfserr_jukebox;
1930 1930
1931 spin_lock(&client_lock); 1931 spin_lock(&client_lock);
1932 status = nfserr_badsession; 1932 status = nfserr_badsession;
1933 session = find_in_sessionid_hashtbl(&seq->sessionid); 1933 session = find_in_sessionid_hashtbl(&seq->sessionid);
1934 if (!session) 1934 if (!session)
1935 goto out; 1935 goto out;
1936 1936
1937 status = nfserr_too_many_ops; 1937 status = nfserr_too_many_ops;
1938 if (nfsd4_session_too_many_ops(rqstp, session)) 1938 if (nfsd4_session_too_many_ops(rqstp, session))
1939 goto out; 1939 goto out;
1940 1940
1941 status = nfserr_req_too_big; 1941 status = nfserr_req_too_big;
1942 if (nfsd4_request_too_big(rqstp, session)) 1942 if (nfsd4_request_too_big(rqstp, session))
1943 goto out; 1943 goto out;
1944 1944
1945 status = nfserr_badslot; 1945 status = nfserr_badslot;
1946 if (seq->slotid >= session->se_fchannel.maxreqs) 1946 if (seq->slotid >= session->se_fchannel.maxreqs)
1947 goto out; 1947 goto out;
1948 1948
1949 slot = session->se_slots[seq->slotid]; 1949 slot = session->se_slots[seq->slotid];
1950 dprintk("%s: slotid %d\n", __func__, seq->slotid); 1950 dprintk("%s: slotid %d\n", __func__, seq->slotid);
1951 1951
1952 /* We do not negotiate the number of slots yet, so set the 1952 /* We do not negotiate the number of slots yet, so set the
1953 * maxslots to the session maxreqs which is used to encode 1953 * maxslots to the session maxreqs which is used to encode
1954 * sr_highest_slotid and the sr_target_slot id to maxslots */ 1954 * sr_highest_slotid and the sr_target_slot id to maxslots */
1955 seq->maxslots = session->se_fchannel.maxreqs; 1955 seq->maxslots = session->se_fchannel.maxreqs;
1956 1956
1957 status = check_slot_seqid(seq->seqid, slot->sl_seqid, 1957 status = check_slot_seqid(seq->seqid, slot->sl_seqid,
1958 slot->sl_flags & NFSD4_SLOT_INUSE); 1958 slot->sl_flags & NFSD4_SLOT_INUSE);
1959 if (status == nfserr_replay_cache) { 1959 if (status == nfserr_replay_cache) {
1960 status = nfserr_seq_misordered; 1960 status = nfserr_seq_misordered;
1961 if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED)) 1961 if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
1962 goto out; 1962 goto out;
1963 cstate->slot = slot; 1963 cstate->slot = slot;
1964 cstate->session = session; 1964 cstate->session = session;
1965 /* Return the cached reply status and set cstate->status 1965 /* Return the cached reply status and set cstate->status
1966 * for nfsd4_proc_compound processing */ 1966 * for nfsd4_proc_compound processing */
1967 status = nfsd4_replay_cache_entry(resp, seq); 1967 status = nfsd4_replay_cache_entry(resp, seq);
1968 cstate->status = nfserr_replay_cache; 1968 cstate->status = nfserr_replay_cache;
1969 goto out; 1969 goto out;
1970 } 1970 }
1971 if (status) 1971 if (status)
1972 goto out; 1972 goto out;
1973 1973
1974 nfsd4_sequence_check_conn(conn, session); 1974 nfsd4_sequence_check_conn(conn, session);
1975 conn = NULL; 1975 conn = NULL;
1976 1976
1977 /* Success! bump slot seqid */ 1977 /* Success! bump slot seqid */
1978 slot->sl_seqid = seq->seqid; 1978 slot->sl_seqid = seq->seqid;
1979 slot->sl_flags |= NFSD4_SLOT_INUSE; 1979 slot->sl_flags |= NFSD4_SLOT_INUSE;
1980 if (seq->cachethis) 1980 if (seq->cachethis)
1981 slot->sl_flags |= NFSD4_SLOT_CACHETHIS; 1981 slot->sl_flags |= NFSD4_SLOT_CACHETHIS;
1982 else 1982 else
1983 slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS; 1983 slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS;
1984 1984
1985 cstate->slot = slot; 1985 cstate->slot = slot;
1986 cstate->session = session; 1986 cstate->session = session;
1987 1987
1988 out: 1988 out:
1989 /* Hold a session reference until done processing the compound. */ 1989 /* Hold a session reference until done processing the compound. */
1990 if (cstate->session) { 1990 if (cstate->session) {
1991 struct nfs4_client *clp = session->se_client; 1991 struct nfs4_client *clp = session->se_client;
1992 1992
1993 nfsd4_get_session(cstate->session); 1993 nfsd4_get_session(cstate->session);
1994 atomic_inc(&clp->cl_refcount); 1994 atomic_inc(&clp->cl_refcount);
1995 switch (clp->cl_cb_state) { 1995 switch (clp->cl_cb_state) {
1996 case NFSD4_CB_DOWN: 1996 case NFSD4_CB_DOWN:
1997 seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN; 1997 seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
1998 break; 1998 break;
1999 case NFSD4_CB_FAULT: 1999 case NFSD4_CB_FAULT:
2000 seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT; 2000 seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
2001 break; 2001 break;
2002 default: 2002 default:
2003 seq->status_flags = 0; 2003 seq->status_flags = 0;
2004 } 2004 }
2005 } 2005 }
2006 kfree(conn); 2006 kfree(conn);
2007 spin_unlock(&client_lock); 2007 spin_unlock(&client_lock);
2008 dprintk("%s: return %d\n", __func__, ntohl(status)); 2008 dprintk("%s: return %d\n", __func__, ntohl(status));
2009 return status; 2009 return status;
2010 } 2010 }
2011 2011
2012 static inline bool has_resources(struct nfs4_client *clp) 2012 static inline bool has_resources(struct nfs4_client *clp)
2013 { 2013 {
2014 return !list_empty(&clp->cl_openowners) 2014 return !list_empty(&clp->cl_openowners)
2015 || !list_empty(&clp->cl_delegations) 2015 || !list_empty(&clp->cl_delegations)
2016 || !list_empty(&clp->cl_sessions); 2016 || !list_empty(&clp->cl_sessions);
2017 } 2017 }
2018 2018
2019 __be32 2019 __be32
2020 nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc) 2020 nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc)
2021 { 2021 {
2022 struct nfs4_client *conf, *unconf, *clp; 2022 struct nfs4_client *conf, *unconf, *clp;
2023 int status = 0; 2023 __be32 status = 0;
2024 2024
2025 nfs4_lock_state(); 2025 nfs4_lock_state();
2026 unconf = find_unconfirmed_client(&dc->clientid); 2026 unconf = find_unconfirmed_client(&dc->clientid);
2027 conf = find_confirmed_client(&dc->clientid); 2027 conf = find_confirmed_client(&dc->clientid);
2028 2028
2029 if (conf) { 2029 if (conf) {
2030 clp = conf; 2030 clp = conf;
2031 2031
2032 if (!is_client_expired(conf) && has_resources(conf)) { 2032 if (!is_client_expired(conf) && has_resources(conf)) {
2033 status = nfserr_clientid_busy; 2033 status = nfserr_clientid_busy;
2034 goto out; 2034 goto out;
2035 } 2035 }
2036 2036
2037 /* rfc5661 18.50.3 */ 2037 /* rfc5661 18.50.3 */
2038 if (cstate->session && conf == cstate->session->se_client) { 2038 if (cstate->session && conf == cstate->session->se_client) {
2039 status = nfserr_clientid_busy; 2039 status = nfserr_clientid_busy;
2040 goto out; 2040 goto out;
2041 } 2041 }
2042 } else if (unconf) 2042 } else if (unconf)
2043 clp = unconf; 2043 clp = unconf;
2044 else { 2044 else {
2045 status = nfserr_stale_clientid; 2045 status = nfserr_stale_clientid;
2046 goto out; 2046 goto out;
2047 } 2047 }
2048 2048
2049 expire_client(clp); 2049 expire_client(clp);
2050 out: 2050 out:
2051 nfs4_unlock_state(); 2051 nfs4_unlock_state();
2052 dprintk("%s return %d\n", __func__, ntohl(status)); 2052 dprintk("%s return %d\n", __func__, ntohl(status));
2053 return status; 2053 return status;
2054 } 2054 }
2055 2055
2056 __be32 2056 __be32
2057 nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) 2057 nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
2058 { 2058 {
2059 int status = 0; 2059 __be32 status = 0;
2060 2060
2061 if (rc->rca_one_fs) { 2061 if (rc->rca_one_fs) {
2062 if (!cstate->current_fh.fh_dentry) 2062 if (!cstate->current_fh.fh_dentry)
2063 return nfserr_nofilehandle; 2063 return nfserr_nofilehandle;
2064 /* 2064 /*
2065 * We don't take advantage of the rca_one_fs case. 2065 * We don't take advantage of the rca_one_fs case.
2066 * That's OK, it's optional, we can safely ignore it. 2066 * That's OK, it's optional, we can safely ignore it.
2067 */ 2067 */
2068 return nfs_ok; 2068 return nfs_ok;
2069 } 2069 }
2070 2070
2071 nfs4_lock_state(); 2071 nfs4_lock_state();
2072 status = nfserr_complete_already; 2072 status = nfserr_complete_already;
2073 if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, 2073 if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
2074 &cstate->session->se_client->cl_flags)) 2074 &cstate->session->se_client->cl_flags))
2075 goto out; 2075 goto out;
2076 2076
2077 status = nfserr_stale_clientid; 2077 status = nfserr_stale_clientid;
2078 if (is_client_expired(cstate->session->se_client)) 2078 if (is_client_expired(cstate->session->se_client))
2079 /* 2079 /*
2080 * The following error isn't really legal. 2080 * The following error isn't really legal.
2081 * But we only get here if the client just explicitly 2081 * But we only get here if the client just explicitly
2082 * destroyed the client. Surely it no longer cares what 2082 * destroyed the client. Surely it no longer cares what
2083 * error it gets back on an operation for the dead 2083 * error it gets back on an operation for the dead
2084 * client. 2084 * client.
2085 */ 2085 */
2086 goto out; 2086 goto out;
2087 2087
2088 status = nfs_ok; 2088 status = nfs_ok;
2089 nfsd4_client_record_create(cstate->session->se_client); 2089 nfsd4_client_record_create(cstate->session->se_client);
2090 out: 2090 out:
2091 nfs4_unlock_state(); 2091 nfs4_unlock_state();
2092 return status; 2092 return status;
2093 } 2093 }
2094 2094
2095 __be32 2095 __be32
2096 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 2096 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2097 struct nfsd4_setclientid *setclid) 2097 struct nfsd4_setclientid *setclid)
2098 { 2098 {
2099 struct xdr_netobj clname = setclid->se_name; 2099 struct xdr_netobj clname = setclid->se_name;
2100 nfs4_verifier clverifier = setclid->se_verf; 2100 nfs4_verifier clverifier = setclid->se_verf;
2101 unsigned int strhashval; 2101 unsigned int strhashval;
2102 struct nfs4_client *conf, *unconf, *new; 2102 struct nfs4_client *conf, *unconf, *new;
2103 __be32 status; 2103 __be32 status;
2104 char dname[HEXDIR_LEN]; 2104 char dname[HEXDIR_LEN];
2105 2105
2106 status = nfs4_make_rec_clidname(dname, &clname); 2106 status = nfs4_make_rec_clidname(dname, &clname);
2107 if (status) 2107 if (status)
2108 return status; 2108 return status;
2109 2109
2110 /* 2110 /*
2111 * XXX The Duplicate Request Cache (DRC) has been checked (??) 2111 * XXX The Duplicate Request Cache (DRC) has been checked (??)
2112 * We get here on a DRC miss. 2112 * We get here on a DRC miss.
2113 */ 2113 */
2114 2114
2115 strhashval = clientstr_hashval(dname); 2115 strhashval = clientstr_hashval(dname);
2116 2116
2117 nfs4_lock_state(); 2117 nfs4_lock_state();
2118 conf = find_confirmed_client_by_str(dname, strhashval); 2118 conf = find_confirmed_client_by_str(dname, strhashval);
2119 if (conf) { 2119 if (conf) {
2120 /* RFC 3530 14.2.33 CASE 0: */ 2120 /* RFC 3530 14.2.33 CASE 0: */
2121 status = nfserr_clid_inuse; 2121 status = nfserr_clid_inuse;
2122 if (clp_used_exchangeid(conf)) 2122 if (clp_used_exchangeid(conf))
2123 goto out; 2123 goto out;
2124 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { 2124 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
2125 char addr_str[INET6_ADDRSTRLEN]; 2125 char addr_str[INET6_ADDRSTRLEN];
2126 rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str, 2126 rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str,
2127 sizeof(addr_str)); 2127 sizeof(addr_str));
2128 dprintk("NFSD: setclientid: string in use by client " 2128 dprintk("NFSD: setclientid: string in use by client "
2129 "at %s\n", addr_str); 2129 "at %s\n", addr_str);
2130 goto out; 2130 goto out;
2131 } 2131 }
2132 } 2132 }
2133 /* 2133 /*
2134 * section 14.2.33 of RFC 3530 (under the heading "IMPLEMENTATION") 2134 * section 14.2.33 of RFC 3530 (under the heading "IMPLEMENTATION")
2135 * has a description of SETCLIENTID request processing consisting 2135 * has a description of SETCLIENTID request processing consisting
2136 * of 5 bullet points, labeled as CASE0 - CASE4 below. 2136 * of 5 bullet points, labeled as CASE0 - CASE4 below.
2137 */ 2137 */
2138 unconf = find_unconfirmed_client_by_str(dname, strhashval); 2138 unconf = find_unconfirmed_client_by_str(dname, strhashval);
2139 status = nfserr_jukebox; 2139 status = nfserr_jukebox;
2140 if (!conf) { 2140 if (!conf) {
2141 /* 2141 /*
2142 * RFC 3530 14.2.33 CASE 4: 2142 * RFC 3530 14.2.33 CASE 4:
2143 * placed first, because it is the normal case 2143 * placed first, because it is the normal case
2144 */ 2144 */
2145 if (unconf) 2145 if (unconf)
2146 expire_client(unconf); 2146 expire_client(unconf);
2147 new = create_client(clname, dname, rqstp, &clverifier); 2147 new = create_client(clname, dname, rqstp, &clverifier);
2148 if (new == NULL) 2148 if (new == NULL)
2149 goto out; 2149 goto out;
2150 gen_clid(new); 2150 gen_clid(new);
2151 } else if (same_verf(&conf->cl_verifier, &clverifier)) { 2151 } else if (same_verf(&conf->cl_verifier, &clverifier)) {
2152 /* 2152 /*
2153 * RFC 3530 14.2.33 CASE 1: 2153 * RFC 3530 14.2.33 CASE 1:
2154 * probable callback update 2154 * probable callback update
2155 */ 2155 */
2156 if (unconf) { 2156 if (unconf) {
2157 /* Note this is removing unconfirmed {*x***}, 2157 /* Note this is removing unconfirmed {*x***},
2158 * which is stronger than RFC recommended {vxc**}. 2158 * which is stronger than RFC recommended {vxc**}.
2159 * This has the advantage that there is at most 2159 * This has the advantage that there is at most
2160 * one {*x***} in either list at any time. 2160 * one {*x***} in either list at any time.
2161 */ 2161 */
2162 expire_client(unconf); 2162 expire_client(unconf);
2163 } 2163 }
2164 new = create_client(clname, dname, rqstp, &clverifier); 2164 new = create_client(clname, dname, rqstp, &clverifier);
2165 if (new == NULL) 2165 if (new == NULL)
2166 goto out; 2166 goto out;
2167 copy_clid(new, conf); 2167 copy_clid(new, conf);
2168 } else if (!unconf) { 2168 } else if (!unconf) {
2169 /* 2169 /*
2170 * RFC 3530 14.2.33 CASE 2: 2170 * RFC 3530 14.2.33 CASE 2:
2171 * probable client reboot; state will be removed if 2171 * probable client reboot; state will be removed if
2172 * confirmed. 2172 * confirmed.
2173 */ 2173 */
2174 new = create_client(clname, dname, rqstp, &clverifier); 2174 new = create_client(clname, dname, rqstp, &clverifier);
2175 if (new == NULL) 2175 if (new == NULL)
2176 goto out; 2176 goto out;
2177 gen_clid(new); 2177 gen_clid(new);
2178 } else { 2178 } else {
2179 /* 2179 /*
2180 * RFC 3530 14.2.33 CASE 3: 2180 * RFC 3530 14.2.33 CASE 3:
2181 * probable client reboot; state will be removed if 2181 * probable client reboot; state will be removed if
2182 * confirmed. 2182 * confirmed.
2183 */ 2183 */
2184 expire_client(unconf); 2184 expire_client(unconf);
2185 new = create_client(clname, dname, rqstp, &clverifier); 2185 new = create_client(clname, dname, rqstp, &clverifier);
2186 if (new == NULL) 2186 if (new == NULL)
2187 goto out; 2187 goto out;
2188 gen_clid(new); 2188 gen_clid(new);
2189 } 2189 }
2190 /* 2190 /*
2191 * XXX: we should probably set this at creation time, and check 2191 * XXX: we should probably set this at creation time, and check
2192 * for consistent minorversion use throughout: 2192 * for consistent minorversion use throughout:
2193 */ 2193 */
2194 new->cl_minorversion = 0; 2194 new->cl_minorversion = 0;
2195 gen_callback(new, setclid, rqstp); 2195 gen_callback(new, setclid, rqstp);
2196 add_to_unconfirmed(new, strhashval); 2196 add_to_unconfirmed(new, strhashval);
2197 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; 2197 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
2198 setclid->se_clientid.cl_id = new->cl_clientid.cl_id; 2198 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
2199 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data)); 2199 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
2200 status = nfs_ok; 2200 status = nfs_ok;
2201 out: 2201 out:
2202 nfs4_unlock_state(); 2202 nfs4_unlock_state();
2203 return status; 2203 return status;
2204 } 2204 }
2205 2205
2206 2206
2207 /* 2207 /*
2208 * Section 14.2.34 of RFC 3530 (under the heading "IMPLEMENTATION") has 2208 * Section 14.2.34 of RFC 3530 (under the heading "IMPLEMENTATION") has
2209 * a description of SETCLIENTID_CONFIRM request processing consisting of 4 2209 * a description of SETCLIENTID_CONFIRM request processing consisting of 4
2210 * bullets, labeled as CASE1 - CASE4 below. 2210 * bullets, labeled as CASE1 - CASE4 below.
2211 */ 2211 */
2212 __be32 2212 __be32
2213 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 2213 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
2214 struct nfsd4_compound_state *cstate, 2214 struct nfsd4_compound_state *cstate,
2215 struct nfsd4_setclientid_confirm *setclientid_confirm) 2215 struct nfsd4_setclientid_confirm *setclientid_confirm)
2216 { 2216 {
2217 struct sockaddr *sa = svc_addr(rqstp); 2217 struct sockaddr *sa = svc_addr(rqstp);
2218 struct nfs4_client *conf, *unconf; 2218 struct nfs4_client *conf, *unconf;
2219 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 2219 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
2220 clientid_t * clid = &setclientid_confirm->sc_clientid; 2220 clientid_t * clid = &setclientid_confirm->sc_clientid;
2221 __be32 status; 2221 __be32 status;
2222 2222
2223 if (STALE_CLIENTID(clid)) 2223 if (STALE_CLIENTID(clid))
2224 return nfserr_stale_clientid; 2224 return nfserr_stale_clientid;
2225 /* 2225 /*
2226 * XXX The Duplicate Request Cache (DRC) has been checked (??) 2226 * XXX The Duplicate Request Cache (DRC) has been checked (??)
2227 * We get here on a DRC miss. 2227 * We get here on a DRC miss.
2228 */ 2228 */
2229 2229
2230 nfs4_lock_state(); 2230 nfs4_lock_state();
2231 2231
2232 conf = find_confirmed_client(clid); 2232 conf = find_confirmed_client(clid);
2233 unconf = find_unconfirmed_client(clid); 2233 unconf = find_unconfirmed_client(clid);
2234 2234
2235 status = nfserr_clid_inuse; 2235 status = nfserr_clid_inuse;
2236 if (conf && !rpc_cmp_addr((struct sockaddr *) &conf->cl_addr, sa)) 2236 if (conf && !rpc_cmp_addr((struct sockaddr *) &conf->cl_addr, sa))
2237 goto out; 2237 goto out;
2238 if (unconf && !rpc_cmp_addr((struct sockaddr *) &unconf->cl_addr, sa)) 2238 if (unconf && !rpc_cmp_addr((struct sockaddr *) &unconf->cl_addr, sa))
2239 goto out; 2239 goto out;
2240 2240
2241 /* 2241 /*
2242 * section 14.2.34 of RFC 3530 has a description of 2242 * section 14.2.34 of RFC 3530 has a description of
2243 * SETCLIENTID_CONFIRM request processing consisting 2243 * SETCLIENTID_CONFIRM request processing consisting
2244 * of 4 bullet points, labeled as CASE1 - CASE4 below. 2244 * of 4 bullet points, labeled as CASE1 - CASE4 below.
2245 */ 2245 */
2246 if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) { 2246 if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) {
2247 /* 2247 /*
2248 * RFC 3530 14.2.34 CASE 1: 2248 * RFC 3530 14.2.34 CASE 1:
2249 * callback update 2249 * callback update
2250 */ 2250 */
2251 if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 2251 if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
2252 status = nfserr_clid_inuse; 2252 status = nfserr_clid_inuse;
2253 else { 2253 else {
2254 nfsd4_change_callback(conf, &unconf->cl_cb_conn); 2254 nfsd4_change_callback(conf, &unconf->cl_cb_conn);
2255 nfsd4_probe_callback(conf); 2255 nfsd4_probe_callback(conf);
2256 expire_client(unconf); 2256 expire_client(unconf);
2257 status = nfs_ok; 2257 status = nfs_ok;
2258 2258
2259 } 2259 }
2260 } else if (conf && !unconf) { 2260 } else if (conf && !unconf) {
2261 /* 2261 /*
2262 * RFC 3530 14.2.34 CASE 2: 2262 * RFC 3530 14.2.34 CASE 2:
2263 * probable retransmitted request; play it safe and 2263 * probable retransmitted request; play it safe and
2264 * do nothing. 2264 * do nothing.
2265 */ 2265 */
2266 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) 2266 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred))
2267 status = nfserr_clid_inuse; 2267 status = nfserr_clid_inuse;
2268 else 2268 else
2269 status = nfs_ok; 2269 status = nfs_ok;
2270 } else if (!conf && unconf 2270 } else if (!conf && unconf
2271 && same_verf(&unconf->cl_confirm, &confirm)) { 2271 && same_verf(&unconf->cl_confirm, &confirm)) {
2272 /* 2272 /*
2273 * RFC 3530 14.2.34 CASE 3: 2273 * RFC 3530 14.2.34 CASE 3:
2274 * Normal case; new or rebooted client: 2274 * Normal case; new or rebooted client:
2275 */ 2275 */
2276 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) { 2276 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
2277 status = nfserr_clid_inuse; 2277 status = nfserr_clid_inuse;
2278 } else { 2278 } else {
2279 unsigned int hash = 2279 unsigned int hash =
2280 clientstr_hashval(unconf->cl_recdir); 2280 clientstr_hashval(unconf->cl_recdir);
2281 conf = find_confirmed_client_by_str(unconf->cl_recdir, 2281 conf = find_confirmed_client_by_str(unconf->cl_recdir,
2282 hash); 2282 hash);
2283 if (conf) { 2283 if (conf) {
2284 nfsd4_client_record_remove(conf); 2284 nfsd4_client_record_remove(conf);
2285 expire_client(conf); 2285 expire_client(conf);
2286 } 2286 }
2287 move_to_confirmed(unconf); 2287 move_to_confirmed(unconf);
2288 conf = unconf; 2288 conf = unconf;
2289 nfsd4_probe_callback(conf); 2289 nfsd4_probe_callback(conf);
2290 status = nfs_ok; 2290 status = nfs_ok;
2291 } 2291 }
2292 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm))) 2292 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm)))
2293 && (!unconf || (unconf && !same_verf(&unconf->cl_confirm, 2293 && (!unconf || (unconf && !same_verf(&unconf->cl_confirm,
2294 &confirm)))) { 2294 &confirm)))) {
2295 /* 2295 /*
2296 * RFC 3530 14.2.34 CASE 4: 2296 * RFC 3530 14.2.34 CASE 4:
2297 * Client probably hasn't noticed that we rebooted yet. 2297 * Client probably hasn't noticed that we rebooted yet.
2298 */ 2298 */
2299 status = nfserr_stale_clientid; 2299 status = nfserr_stale_clientid;
2300 } else { 2300 } else {
2301 /* check that we have hit one of the cases...*/ 2301 /* check that we have hit one of the cases...*/
2302 status = nfserr_clid_inuse; 2302 status = nfserr_clid_inuse;
2303 } 2303 }
2304 out: 2304 out:
2305 nfs4_unlock_state(); 2305 nfs4_unlock_state();
2306 return status; 2306 return status;
2307 } 2307 }
2308 2308
2309 static struct nfs4_file *nfsd4_alloc_file(void) 2309 static struct nfs4_file *nfsd4_alloc_file(void)
2310 { 2310 {
2311 return kmem_cache_alloc(file_slab, GFP_KERNEL); 2311 return kmem_cache_alloc(file_slab, GFP_KERNEL);
2312 } 2312 }
2313 2313
2314 /* OPEN Share state helper functions */ 2314 /* OPEN Share state helper functions */
2315 static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino) 2315 static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
2316 { 2316 {
2317 unsigned int hashval = file_hashval(ino); 2317 unsigned int hashval = file_hashval(ino);
2318 2318
2319 atomic_set(&fp->fi_ref, 1); 2319 atomic_set(&fp->fi_ref, 1);
2320 INIT_LIST_HEAD(&fp->fi_hash); 2320 INIT_LIST_HEAD(&fp->fi_hash);
2321 INIT_LIST_HEAD(&fp->fi_stateids); 2321 INIT_LIST_HEAD(&fp->fi_stateids);
2322 INIT_LIST_HEAD(&fp->fi_delegations); 2322 INIT_LIST_HEAD(&fp->fi_delegations);
2323 fp->fi_inode = igrab(ino); 2323 fp->fi_inode = igrab(ino);
2324 fp->fi_had_conflict = false; 2324 fp->fi_had_conflict = false;
2325 fp->fi_lease = NULL; 2325 fp->fi_lease = NULL;
2326 memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); 2326 memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
2327 memset(fp->fi_access, 0, sizeof(fp->fi_access)); 2327 memset(fp->fi_access, 0, sizeof(fp->fi_access));
2328 spin_lock(&recall_lock); 2328 spin_lock(&recall_lock);
2329 list_add(&fp->fi_hash, &file_hashtbl[hashval]); 2329 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
2330 spin_unlock(&recall_lock); 2330 spin_unlock(&recall_lock);
2331 } 2331 }
2332 2332
2333 static void 2333 static void
2334 nfsd4_free_slab(struct kmem_cache **slab) 2334 nfsd4_free_slab(struct kmem_cache **slab)
2335 { 2335 {
2336 if (*slab == NULL) 2336 if (*slab == NULL)
2337 return; 2337 return;
2338 kmem_cache_destroy(*slab); 2338 kmem_cache_destroy(*slab);
2339 *slab = NULL; 2339 *slab = NULL;
2340 } 2340 }
2341 2341
2342 void 2342 void
2343 nfsd4_free_slabs(void) 2343 nfsd4_free_slabs(void)
2344 { 2344 {
2345 nfsd4_free_slab(&openowner_slab); 2345 nfsd4_free_slab(&openowner_slab);
2346 nfsd4_free_slab(&lockowner_slab); 2346 nfsd4_free_slab(&lockowner_slab);
2347 nfsd4_free_slab(&file_slab); 2347 nfsd4_free_slab(&file_slab);
2348 nfsd4_free_slab(&stateid_slab); 2348 nfsd4_free_slab(&stateid_slab);
2349 nfsd4_free_slab(&deleg_slab); 2349 nfsd4_free_slab(&deleg_slab);
2350 } 2350 }
2351 2351
2352 int 2352 int
2353 nfsd4_init_slabs(void) 2353 nfsd4_init_slabs(void)
2354 { 2354 {
2355 openowner_slab = kmem_cache_create("nfsd4_openowners", 2355 openowner_slab = kmem_cache_create("nfsd4_openowners",
2356 sizeof(struct nfs4_openowner), 0, 0, NULL); 2356 sizeof(struct nfs4_openowner), 0, 0, NULL);
2357 if (openowner_slab == NULL) 2357 if (openowner_slab == NULL)
2358 goto out_nomem; 2358 goto out_nomem;
2359 lockowner_slab = kmem_cache_create("nfsd4_lockowners", 2359 lockowner_slab = kmem_cache_create("nfsd4_lockowners",
2360 sizeof(struct nfs4_openowner), 0, 0, NULL); 2360 sizeof(struct nfs4_openowner), 0, 0, NULL);
2361 if (lockowner_slab == NULL) 2361 if (lockowner_slab == NULL)
2362 goto out_nomem; 2362 goto out_nomem;
2363 file_slab = kmem_cache_create("nfsd4_files", 2363 file_slab = kmem_cache_create("nfsd4_files",
2364 sizeof(struct nfs4_file), 0, 0, NULL); 2364 sizeof(struct nfs4_file), 0, 0, NULL);
2365 if (file_slab == NULL) 2365 if (file_slab == NULL)
2366 goto out_nomem; 2366 goto out_nomem;
2367 stateid_slab = kmem_cache_create("nfsd4_stateids", 2367 stateid_slab = kmem_cache_create("nfsd4_stateids",
2368 sizeof(struct nfs4_ol_stateid), 0, 0, NULL); 2368 sizeof(struct nfs4_ol_stateid), 0, 0, NULL);
2369 if (stateid_slab == NULL) 2369 if (stateid_slab == NULL)
2370 goto out_nomem; 2370 goto out_nomem;
2371 deleg_slab = kmem_cache_create("nfsd4_delegations", 2371 deleg_slab = kmem_cache_create("nfsd4_delegations",
2372 sizeof(struct nfs4_delegation), 0, 0, NULL); 2372 sizeof(struct nfs4_delegation), 0, 0, NULL);
2373 if (deleg_slab == NULL) 2373 if (deleg_slab == NULL)
2374 goto out_nomem; 2374 goto out_nomem;
2375 return 0; 2375 return 0;
2376 out_nomem: 2376 out_nomem:
2377 nfsd4_free_slabs(); 2377 nfsd4_free_slabs();
2378 dprintk("nfsd4: out of memory while initializing nfsv4\n"); 2378 dprintk("nfsd4: out of memory while initializing nfsv4\n");
2379 return -ENOMEM; 2379 return -ENOMEM;
2380 } 2380 }
2381 2381
2382 void nfs4_free_openowner(struct nfs4_openowner *oo) 2382 void nfs4_free_openowner(struct nfs4_openowner *oo)
2383 { 2383 {
2384 kfree(oo->oo_owner.so_owner.data); 2384 kfree(oo->oo_owner.so_owner.data);
2385 kmem_cache_free(openowner_slab, oo); 2385 kmem_cache_free(openowner_slab, oo);
2386 } 2386 }
2387 2387
2388 void nfs4_free_lockowner(struct nfs4_lockowner *lo) 2388 void nfs4_free_lockowner(struct nfs4_lockowner *lo)
2389 { 2389 {
2390 kfree(lo->lo_owner.so_owner.data); 2390 kfree(lo->lo_owner.so_owner.data);
2391 kmem_cache_free(lockowner_slab, lo); 2391 kmem_cache_free(lockowner_slab, lo);
2392 } 2392 }
2393 2393
2394 static void init_nfs4_replay(struct nfs4_replay *rp) 2394 static void init_nfs4_replay(struct nfs4_replay *rp)
2395 { 2395 {
2396 rp->rp_status = nfserr_serverfault; 2396 rp->rp_status = nfserr_serverfault;
2397 rp->rp_buflen = 0; 2397 rp->rp_buflen = 0;
2398 rp->rp_buf = rp->rp_ibuf; 2398 rp->rp_buf = rp->rp_ibuf;
2399 } 2399 }
2400 2400
2401 static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp) 2401 static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp)
2402 { 2402 {
2403 struct nfs4_stateowner *sop; 2403 struct nfs4_stateowner *sop;
2404 2404
2405 sop = kmem_cache_alloc(slab, GFP_KERNEL); 2405 sop = kmem_cache_alloc(slab, GFP_KERNEL);
2406 if (!sop) 2406 if (!sop)
2407 return NULL; 2407 return NULL;
2408 2408
2409 sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL); 2409 sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL);
2410 if (!sop->so_owner.data) { 2410 if (!sop->so_owner.data) {
2411 kmem_cache_free(slab, sop); 2411 kmem_cache_free(slab, sop);
2412 return NULL; 2412 return NULL;
2413 } 2413 }
2414 sop->so_owner.len = owner->len; 2414 sop->so_owner.len = owner->len;
2415 2415
2416 INIT_LIST_HEAD(&sop->so_stateids); 2416 INIT_LIST_HEAD(&sop->so_stateids);
2417 sop->so_client = clp; 2417 sop->so_client = clp;
2418 init_nfs4_replay(&sop->so_replay); 2418 init_nfs4_replay(&sop->so_replay);
2419 return sop; 2419 return sop;
2420 } 2420 }
2421 2421
2422 static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval) 2422 static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
2423 { 2423 {
2424 list_add(&oo->oo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); 2424 list_add(&oo->oo_owner.so_strhash, &ownerstr_hashtbl[strhashval]);
2425 list_add(&oo->oo_perclient, &clp->cl_openowners); 2425 list_add(&oo->oo_perclient, &clp->cl_openowners);
2426 } 2426 }
2427 2427
2428 static struct nfs4_openowner * 2428 static struct nfs4_openowner *
2429 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) { 2429 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
2430 struct nfs4_openowner *oo; 2430 struct nfs4_openowner *oo;
2431 2431
2432 oo = alloc_stateowner(openowner_slab, &open->op_owner, clp); 2432 oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
2433 if (!oo) 2433 if (!oo)
2434 return NULL; 2434 return NULL;
2435 oo->oo_owner.so_is_open_owner = 1; 2435 oo->oo_owner.so_is_open_owner = 1;
2436 oo->oo_owner.so_seqid = open->op_seqid; 2436 oo->oo_owner.so_seqid = open->op_seqid;
2437 oo->oo_flags = NFS4_OO_NEW; 2437 oo->oo_flags = NFS4_OO_NEW;
2438 oo->oo_time = 0; 2438 oo->oo_time = 0;
2439 oo->oo_last_closed_stid = NULL; 2439 oo->oo_last_closed_stid = NULL;
2440 INIT_LIST_HEAD(&oo->oo_close_lru); 2440 INIT_LIST_HEAD(&oo->oo_close_lru);
2441 hash_openowner(oo, clp, strhashval); 2441 hash_openowner(oo, clp, strhashval);
2442 return oo; 2442 return oo;
2443 } 2443 }
2444 2444
2445 static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { 2445 static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
2446 struct nfs4_openowner *oo = open->op_openowner; 2446 struct nfs4_openowner *oo = open->op_openowner;
2447 struct nfs4_client *clp = oo->oo_owner.so_client; 2447 struct nfs4_client *clp = oo->oo_owner.so_client;
2448 2448
2449 init_stid(&stp->st_stid, clp, NFS4_OPEN_STID); 2449 init_stid(&stp->st_stid, clp, NFS4_OPEN_STID);
2450 INIT_LIST_HEAD(&stp->st_lockowners); 2450 INIT_LIST_HEAD(&stp->st_lockowners);
2451 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); 2451 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
2452 list_add(&stp->st_perfile, &fp->fi_stateids); 2452 list_add(&stp->st_perfile, &fp->fi_stateids);
2453 stp->st_stateowner = &oo->oo_owner; 2453 stp->st_stateowner = &oo->oo_owner;
2454 get_nfs4_file(fp); 2454 get_nfs4_file(fp);
2455 stp->st_file = fp; 2455 stp->st_file = fp;
2456 stp->st_access_bmap = 0; 2456 stp->st_access_bmap = 0;
2457 stp->st_deny_bmap = 0; 2457 stp->st_deny_bmap = 0;
2458 __set_bit(open->op_share_access, &stp->st_access_bmap); 2458 __set_bit(open->op_share_access, &stp->st_access_bmap);
2459 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2459 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2460 stp->st_openstp = NULL; 2460 stp->st_openstp = NULL;
2461 } 2461 }
2462 2462
2463 static void 2463 static void
2464 move_to_close_lru(struct nfs4_openowner *oo) 2464 move_to_close_lru(struct nfs4_openowner *oo)
2465 { 2465 {
2466 dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo); 2466 dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo);
2467 2467
2468 list_move_tail(&oo->oo_close_lru, &close_lru); 2468 list_move_tail(&oo->oo_close_lru, &close_lru);
2469 oo->oo_time = get_seconds(); 2469 oo->oo_time = get_seconds();
2470 } 2470 }
2471 2471
2472 static int 2472 static int
2473 same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, 2473 same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
2474 clientid_t *clid) 2474 clientid_t *clid)
2475 { 2475 {
2476 return (sop->so_owner.len == owner->len) && 2476 return (sop->so_owner.len == owner->len) &&
2477 0 == memcmp(sop->so_owner.data, owner->data, owner->len) && 2477 0 == memcmp(sop->so_owner.data, owner->data, owner->len) &&
2478 (sop->so_client->cl_clientid.cl_id == clid->cl_id); 2478 (sop->so_client->cl_clientid.cl_id == clid->cl_id);
2479 } 2479 }
2480 2480
2481 static struct nfs4_openowner * 2481 static struct nfs4_openowner *
2482 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open) 2482 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)
2483 { 2483 {
2484 struct nfs4_stateowner *so; 2484 struct nfs4_stateowner *so;
2485 struct nfs4_openowner *oo; 2485 struct nfs4_openowner *oo;
2486 2486
2487 list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) { 2487 list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) {
2488 if (!so->so_is_open_owner) 2488 if (!so->so_is_open_owner)
2489 continue; 2489 continue;
2490 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) { 2490 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) {
2491 oo = openowner(so); 2491 oo = openowner(so);
2492 renew_client(oo->oo_owner.so_client); 2492 renew_client(oo->oo_owner.so_client);
2493 return oo; 2493 return oo;
2494 } 2494 }
2495 } 2495 }
2496 return NULL; 2496 return NULL;
2497 } 2497 }
2498 2498
2499 /* search file_hashtbl[] for file */ 2499 /* search file_hashtbl[] for file */
2500 static struct nfs4_file * 2500 static struct nfs4_file *
2501 find_file(struct inode *ino) 2501 find_file(struct inode *ino)
2502 { 2502 {
2503 unsigned int hashval = file_hashval(ino); 2503 unsigned int hashval = file_hashval(ino);
2504 struct nfs4_file *fp; 2504 struct nfs4_file *fp;
2505 2505
2506 spin_lock(&recall_lock); 2506 spin_lock(&recall_lock);
2507 list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) { 2507 list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
2508 if (fp->fi_inode == ino) { 2508 if (fp->fi_inode == ino) {
2509 get_nfs4_file(fp); 2509 get_nfs4_file(fp);
2510 spin_unlock(&recall_lock); 2510 spin_unlock(&recall_lock);
2511 return fp; 2511 return fp;
2512 } 2512 }
2513 } 2513 }
2514 spin_unlock(&recall_lock); 2514 spin_unlock(&recall_lock);
2515 return NULL; 2515 return NULL;
2516 } 2516 }
2517 2517
2518 /* 2518 /*
2519 * Called to check deny when READ with all zero stateid or 2519 * Called to check deny when READ with all zero stateid or
2520 * WRITE with all zero or all one stateid 2520 * WRITE with all zero or all one stateid
2521 */ 2521 */
2522 static __be32 2522 static __be32
2523 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) 2523 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
2524 { 2524 {
2525 struct inode *ino = current_fh->fh_dentry->d_inode; 2525 struct inode *ino = current_fh->fh_dentry->d_inode;
2526 struct nfs4_file *fp; 2526 struct nfs4_file *fp;
2527 struct nfs4_ol_stateid *stp; 2527 struct nfs4_ol_stateid *stp;
2528 __be32 ret; 2528 __be32 ret;
2529 2529
2530 dprintk("NFSD: nfs4_share_conflict\n"); 2530 dprintk("NFSD: nfs4_share_conflict\n");
2531 2531
2532 fp = find_file(ino); 2532 fp = find_file(ino);
2533 if (!fp) 2533 if (!fp)
2534 return nfs_ok; 2534 return nfs_ok;
2535 ret = nfserr_locked; 2535 ret = nfserr_locked;
2536 /* Search for conflicting share reservations */ 2536 /* Search for conflicting share reservations */
2537 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) { 2537 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
2538 if (test_bit(deny_type, &stp->st_deny_bmap) || 2538 if (test_bit(deny_type, &stp->st_deny_bmap) ||
2539 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap)) 2539 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
2540 goto out; 2540 goto out;
2541 } 2541 }
2542 ret = nfs_ok; 2542 ret = nfs_ok;
2543 out: 2543 out:
2544 put_nfs4_file(fp); 2544 put_nfs4_file(fp);
2545 return ret; 2545 return ret;
2546 } 2546 }
2547 2547
2548 static void nfsd_break_one_deleg(struct nfs4_delegation *dp) 2548 static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
2549 { 2549 {
2550 /* We're assuming the state code never drops its reference 2550 /* We're assuming the state code never drops its reference
2551 * without first removing the lease. Since we're in this lease 2551 * without first removing the lease. Since we're in this lease
2552 * callback (and since the lease code is serialized by the kernel 2552 * callback (and since the lease code is serialized by the kernel
2553 * lock) we know the server hasn't removed the lease yet, we know 2553 * lock) we know the server hasn't removed the lease yet, we know
2554 * it's safe to take a reference: */ 2554 * it's safe to take a reference: */
2555 atomic_inc(&dp->dl_count); 2555 atomic_inc(&dp->dl_count);
2556 2556
2557 list_add_tail(&dp->dl_recall_lru, &del_recall_lru); 2557 list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
2558 2558
2559 /* only place dl_time is set. protected by lock_flocks*/ 2559 /* only place dl_time is set. protected by lock_flocks*/
2560 dp->dl_time = get_seconds(); 2560 dp->dl_time = get_seconds();
2561 2561
2562 nfsd4_cb_recall(dp); 2562 nfsd4_cb_recall(dp);
2563 } 2563 }
2564 2564
2565 /* Called from break_lease() with lock_flocks() held. */ 2565 /* Called from break_lease() with lock_flocks() held. */
2566 static void nfsd_break_deleg_cb(struct file_lock *fl) 2566 static void nfsd_break_deleg_cb(struct file_lock *fl)
2567 { 2567 {
2568 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; 2568 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
2569 struct nfs4_delegation *dp; 2569 struct nfs4_delegation *dp;
2570 2570
2571 BUG_ON(!fp); 2571 BUG_ON(!fp);
2572 /* We assume break_lease is only called once per lease: */ 2572 /* We assume break_lease is only called once per lease: */
2573 BUG_ON(fp->fi_had_conflict); 2573 BUG_ON(fp->fi_had_conflict);
2574 /* 2574 /*
2575 * We don't want the locks code to timeout the lease for us; 2575 * We don't want the locks code to timeout the lease for us;
2576 * we'll remove it ourself if a delegation isn't returned 2576 * we'll remove it ourself if a delegation isn't returned
2577 * in time: 2577 * in time:
2578 */ 2578 */
2579 fl->fl_break_time = 0; 2579 fl->fl_break_time = 0;
2580 2580
2581 spin_lock(&recall_lock); 2581 spin_lock(&recall_lock);
2582 fp->fi_had_conflict = true; 2582 fp->fi_had_conflict = true;
2583 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) 2583 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
2584 nfsd_break_one_deleg(dp); 2584 nfsd_break_one_deleg(dp);
2585 spin_unlock(&recall_lock); 2585 spin_unlock(&recall_lock);
2586 } 2586 }
2587 2587
2588 static 2588 static
2589 int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) 2589 int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2590 { 2590 {
2591 if (arg & F_UNLCK) 2591 if (arg & F_UNLCK)
2592 return lease_modify(onlist, arg); 2592 return lease_modify(onlist, arg);
2593 else 2593 else
2594 return -EAGAIN; 2594 return -EAGAIN;
2595 } 2595 }
2596 2596
2597 static const struct lock_manager_operations nfsd_lease_mng_ops = { 2597 static const struct lock_manager_operations nfsd_lease_mng_ops = {
2598 .lm_break = nfsd_break_deleg_cb, 2598 .lm_break = nfsd_break_deleg_cb,
2599 .lm_change = nfsd_change_deleg_cb, 2599 .lm_change = nfsd_change_deleg_cb,
2600 }; 2600 };
2601 2601
2602 static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4_stateowner *so, u32 seqid) 2602 static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4_stateowner *so, u32 seqid)
2603 { 2603 {
2604 if (nfsd4_has_session(cstate)) 2604 if (nfsd4_has_session(cstate))
2605 return nfs_ok; 2605 return nfs_ok;
2606 if (seqid == so->so_seqid - 1) 2606 if (seqid == so->so_seqid - 1)
2607 return nfserr_replay_me; 2607 return nfserr_replay_me;
2608 if (seqid == so->so_seqid) 2608 if (seqid == so->so_seqid)
2609 return nfs_ok; 2609 return nfs_ok;
2610 return nfserr_bad_seqid; 2610 return nfserr_bad_seqid;
2611 } 2611 }
2612 2612
2613 __be32 2613 __be32
2614 nfsd4_process_open1(struct nfsd4_compound_state *cstate, 2614 nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2615 struct nfsd4_open *open) 2615 struct nfsd4_open *open)
2616 { 2616 {
2617 clientid_t *clientid = &open->op_clientid; 2617 clientid_t *clientid = &open->op_clientid;
2618 struct nfs4_client *clp = NULL; 2618 struct nfs4_client *clp = NULL;
2619 unsigned int strhashval; 2619 unsigned int strhashval;
2620 struct nfs4_openowner *oo = NULL; 2620 struct nfs4_openowner *oo = NULL;
2621 __be32 status; 2621 __be32 status;
2622 2622
2623 if (STALE_CLIENTID(&open->op_clientid)) 2623 if (STALE_CLIENTID(&open->op_clientid))
2624 return nfserr_stale_clientid; 2624 return nfserr_stale_clientid;
2625 /* 2625 /*
2626 * In case we need it later, after we've already created the 2626 * In case we need it later, after we've already created the
2627 * file and don't want to risk a further failure: 2627 * file and don't want to risk a further failure:
2628 */ 2628 */
2629 open->op_file = nfsd4_alloc_file(); 2629 open->op_file = nfsd4_alloc_file();
2630 if (open->op_file == NULL) 2630 if (open->op_file == NULL)
2631 return nfserr_jukebox; 2631 return nfserr_jukebox;
2632 2632
2633 strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner); 2633 strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner);
2634 oo = find_openstateowner_str(strhashval, open); 2634 oo = find_openstateowner_str(strhashval, open);
2635 open->op_openowner = oo; 2635 open->op_openowner = oo;
2636 if (!oo) { 2636 if (!oo) {
2637 clp = find_confirmed_client(clientid); 2637 clp = find_confirmed_client(clientid);
2638 if (clp == NULL) 2638 if (clp == NULL)
2639 return nfserr_expired; 2639 return nfserr_expired;
2640 goto new_owner; 2640 goto new_owner;
2641 } 2641 }
2642 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) { 2642 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
2643 /* Replace unconfirmed owners without checking for replay. */ 2643 /* Replace unconfirmed owners without checking for replay. */
2644 clp = oo->oo_owner.so_client; 2644 clp = oo->oo_owner.so_client;
2645 release_openowner(oo); 2645 release_openowner(oo);
2646 open->op_openowner = NULL; 2646 open->op_openowner = NULL;
2647 goto new_owner; 2647 goto new_owner;
2648 } 2648 }
2649 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid); 2649 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
2650 if (status) 2650 if (status)
2651 return status; 2651 return status;
2652 clp = oo->oo_owner.so_client; 2652 clp = oo->oo_owner.so_client;
2653 goto alloc_stateid; 2653 goto alloc_stateid;
2654 new_owner: 2654 new_owner:
2655 oo = alloc_init_open_stateowner(strhashval, clp, open); 2655 oo = alloc_init_open_stateowner(strhashval, clp, open);
2656 if (oo == NULL) 2656 if (oo == NULL)
2657 return nfserr_jukebox; 2657 return nfserr_jukebox;
2658 open->op_openowner = oo; 2658 open->op_openowner = oo;
2659 alloc_stateid: 2659 alloc_stateid:
2660 open->op_stp = nfs4_alloc_stateid(clp); 2660 open->op_stp = nfs4_alloc_stateid(clp);
2661 if (!open->op_stp) 2661 if (!open->op_stp)
2662 return nfserr_jukebox; 2662 return nfserr_jukebox;
2663 return nfs_ok; 2663 return nfs_ok;
2664 } 2664 }
2665 2665
2666 static inline __be32 2666 static inline __be32
2667 nfs4_check_delegmode(struct nfs4_delegation *dp, int flags) 2667 nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
2668 { 2668 {
2669 if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ)) 2669 if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
2670 return nfserr_openmode; 2670 return nfserr_openmode;
2671 else 2671 else
2672 return nfs_ok; 2672 return nfs_ok;
2673 } 2673 }
2674 2674
2675 static int share_access_to_flags(u32 share_access) 2675 static int share_access_to_flags(u32 share_access)
2676 { 2676 {
2677 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE; 2677 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
2678 } 2678 }
2679 2679
2680 static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, stateid_t *s) 2680 static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, stateid_t *s)
2681 { 2681 {
2682 struct nfs4_stid *ret; 2682 struct nfs4_stid *ret;
2683 2683
2684 ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID); 2684 ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID);
2685 if (!ret) 2685 if (!ret)
2686 return NULL; 2686 return NULL;
2687 return delegstateid(ret); 2687 return delegstateid(ret);
2688 } 2688 }
2689 2689
2690 static bool nfsd4_is_deleg_cur(struct nfsd4_open *open) 2690 static bool nfsd4_is_deleg_cur(struct nfsd4_open *open)
2691 { 2691 {
2692 return open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR || 2692 return open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR ||
2693 open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH; 2693 open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH;
2694 } 2694 }
2695 2695
2696 static __be32 2696 static __be32
2697 nfs4_check_deleg(struct nfs4_client *cl, struct nfs4_file *fp, struct nfsd4_open *open, 2697 nfs4_check_deleg(struct nfs4_client *cl, struct nfs4_file *fp, struct nfsd4_open *open,
2698 struct nfs4_delegation **dp) 2698 struct nfs4_delegation **dp)
2699 { 2699 {
2700 int flags; 2700 int flags;
2701 __be32 status = nfserr_bad_stateid; 2701 __be32 status = nfserr_bad_stateid;
2702 2702
2703 *dp = find_deleg_stateid(cl, &open->op_delegate_stateid); 2703 *dp = find_deleg_stateid(cl, &open->op_delegate_stateid);
2704 if (*dp == NULL) 2704 if (*dp == NULL)
2705 goto out; 2705 goto out;
2706 flags = share_access_to_flags(open->op_share_access); 2706 flags = share_access_to_flags(open->op_share_access);
2707 status = nfs4_check_delegmode(*dp, flags); 2707 status = nfs4_check_delegmode(*dp, flags);
2708 if (status) 2708 if (status)
2709 *dp = NULL; 2709 *dp = NULL;
2710 out: 2710 out:
2711 if (!nfsd4_is_deleg_cur(open)) 2711 if (!nfsd4_is_deleg_cur(open))
2712 return nfs_ok; 2712 return nfs_ok;
2713 if (status) 2713 if (status)
2714 return status; 2714 return status;
2715 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 2715 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2716 return nfs_ok; 2716 return nfs_ok;
2717 } 2717 }
2718 2718
2719 static __be32 2719 static __be32
2720 nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_stateid **stpp) 2720 nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_stateid **stpp)
2721 { 2721 {
2722 struct nfs4_ol_stateid *local; 2722 struct nfs4_ol_stateid *local;
2723 struct nfs4_openowner *oo = open->op_openowner; 2723 struct nfs4_openowner *oo = open->op_openowner;
2724 2724
2725 list_for_each_entry(local, &fp->fi_stateids, st_perfile) { 2725 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
2726 /* ignore lock owners */ 2726 /* ignore lock owners */
2727 if (local->st_stateowner->so_is_open_owner == 0) 2727 if (local->st_stateowner->so_is_open_owner == 0)
2728 continue; 2728 continue;
2729 /* remember if we have seen this open owner */ 2729 /* remember if we have seen this open owner */
2730 if (local->st_stateowner == &oo->oo_owner) 2730 if (local->st_stateowner == &oo->oo_owner)
2731 *stpp = local; 2731 *stpp = local;
2732 /* check for conflicting share reservations */ 2732 /* check for conflicting share reservations */
2733 if (!test_share(local, open)) 2733 if (!test_share(local, open))
2734 return nfserr_share_denied; 2734 return nfserr_share_denied;
2735 } 2735 }
2736 return nfs_ok; 2736 return nfs_ok;
2737 } 2737 }
2738 2738
2739 static void nfs4_free_stateid(struct nfs4_ol_stateid *s) 2739 static void nfs4_free_stateid(struct nfs4_ol_stateid *s)
2740 { 2740 {
2741 kmem_cache_free(stateid_slab, s); 2741 kmem_cache_free(stateid_slab, s);
2742 } 2742 }
2743 2743
2744 static inline int nfs4_access_to_access(u32 nfs4_access) 2744 static inline int nfs4_access_to_access(u32 nfs4_access)
2745 { 2745 {
2746 int flags = 0; 2746 int flags = 0;
2747 2747
2748 if (nfs4_access & NFS4_SHARE_ACCESS_READ) 2748 if (nfs4_access & NFS4_SHARE_ACCESS_READ)
2749 flags |= NFSD_MAY_READ; 2749 flags |= NFSD_MAY_READ;
2750 if (nfs4_access & NFS4_SHARE_ACCESS_WRITE) 2750 if (nfs4_access & NFS4_SHARE_ACCESS_WRITE)
2751 flags |= NFSD_MAY_WRITE; 2751 flags |= NFSD_MAY_WRITE;
2752 return flags; 2752 return flags;
2753 } 2753 }
2754 2754
2755 static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, 2755 static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
2756 struct svc_fh *cur_fh, struct nfsd4_open *open) 2756 struct svc_fh *cur_fh, struct nfsd4_open *open)
2757 { 2757 {
2758 __be32 status; 2758 __be32 status;
2759 int oflag = nfs4_access_to_omode(open->op_share_access); 2759 int oflag = nfs4_access_to_omode(open->op_share_access);
2760 int access = nfs4_access_to_access(open->op_share_access); 2760 int access = nfs4_access_to_access(open->op_share_access);
2761 2761
2762 if (!fp->fi_fds[oflag]) { 2762 if (!fp->fi_fds[oflag]) {
2763 status = nfsd_open(rqstp, cur_fh, S_IFREG, access, 2763 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
2764 &fp->fi_fds[oflag]); 2764 &fp->fi_fds[oflag]);
2765 if (status) 2765 if (status)
2766 return status; 2766 return status;
2767 } 2767 }
2768 nfs4_file_get_access(fp, oflag); 2768 nfs4_file_get_access(fp, oflag);
2769 2769
2770 return nfs_ok; 2770 return nfs_ok;
2771 } 2771 }
2772 2772
2773 static inline __be32 2773 static inline __be32
2774 nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, 2774 nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
2775 struct nfsd4_open *open) 2775 struct nfsd4_open *open)
2776 { 2776 {
2777 struct iattr iattr = { 2777 struct iattr iattr = {
2778 .ia_valid = ATTR_SIZE, 2778 .ia_valid = ATTR_SIZE,
2779 .ia_size = 0, 2779 .ia_size = 0,
2780 }; 2780 };
2781 if (!open->op_truncate) 2781 if (!open->op_truncate)
2782 return 0; 2782 return 0;
2783 if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) 2783 if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
2784 return nfserr_inval; 2784 return nfserr_inval;
2785 return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0); 2785 return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
2786 } 2786 }
2787 2787
2788 static __be32 2788 static __be32
2789 nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, struct nfsd4_open *open) 2789 nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, struct nfsd4_open *open)
2790 { 2790 {
2791 u32 op_share_access = open->op_share_access; 2791 u32 op_share_access = open->op_share_access;
2792 bool new_access; 2792 bool new_access;
2793 __be32 status; 2793 __be32 status;
2794 2794
2795 new_access = !test_bit(op_share_access, &stp->st_access_bmap); 2795 new_access = !test_bit(op_share_access, &stp->st_access_bmap);
2796 if (new_access) { 2796 if (new_access) {
2797 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); 2797 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
2798 if (status) 2798 if (status)
2799 return status; 2799 return status;
2800 } 2800 }
2801 status = nfsd4_truncate(rqstp, cur_fh, open); 2801 status = nfsd4_truncate(rqstp, cur_fh, open);
2802 if (status) { 2802 if (status) {
2803 if (new_access) { 2803 if (new_access) {
2804 int oflag = nfs4_access_to_omode(op_share_access); 2804 int oflag = nfs4_access_to_omode(op_share_access);
2805 nfs4_file_put_access(fp, oflag); 2805 nfs4_file_put_access(fp, oflag);
2806 } 2806 }
2807 return status; 2807 return status;
2808 } 2808 }
2809 /* remember the open */ 2809 /* remember the open */
2810 __set_bit(op_share_access, &stp->st_access_bmap); 2810 __set_bit(op_share_access, &stp->st_access_bmap);
2811 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2811 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2812 2812
2813 return nfs_ok; 2813 return nfs_ok;
2814 } 2814 }
2815 2815
2816 2816
2817 static void 2817 static void
2818 nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session) 2818 nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session)
2819 { 2819 {
2820 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 2820 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2821 } 2821 }
2822 2822
2823 /* Should we give out recallable state?: */ 2823 /* Should we give out recallable state?: */
2824 static bool nfsd4_cb_channel_good(struct nfs4_client *clp) 2824 static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
2825 { 2825 {
2826 if (clp->cl_cb_state == NFSD4_CB_UP) 2826 if (clp->cl_cb_state == NFSD4_CB_UP)
2827 return true; 2827 return true;
2828 /* 2828 /*
2829 * In the sessions case, since we don't have to establish a 2829 * In the sessions case, since we don't have to establish a
2830 * separate connection for callbacks, we assume it's OK 2830 * separate connection for callbacks, we assume it's OK
2831 * until we hear otherwise: 2831 * until we hear otherwise:
2832 */ 2832 */
2833 return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN; 2833 return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
2834 } 2834 }
2835 2835
2836 static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int flag) 2836 static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int flag)
2837 { 2837 {
2838 struct file_lock *fl; 2838 struct file_lock *fl;
2839 2839
2840 fl = locks_alloc_lock(); 2840 fl = locks_alloc_lock();
2841 if (!fl) 2841 if (!fl)
2842 return NULL; 2842 return NULL;
2843 locks_init_lock(fl); 2843 locks_init_lock(fl);
2844 fl->fl_lmops = &nfsd_lease_mng_ops; 2844 fl->fl_lmops = &nfsd_lease_mng_ops;
2845 fl->fl_flags = FL_LEASE; 2845 fl->fl_flags = FL_LEASE;
2846 fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; 2846 fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
2847 fl->fl_end = OFFSET_MAX; 2847 fl->fl_end = OFFSET_MAX;
2848 fl->fl_owner = (fl_owner_t)(dp->dl_file); 2848 fl->fl_owner = (fl_owner_t)(dp->dl_file);
2849 fl->fl_pid = current->tgid; 2849 fl->fl_pid = current->tgid;
2850 return fl; 2850 return fl;
2851 } 2851 }
2852 2852
2853 static int nfs4_setlease(struct nfs4_delegation *dp, int flag) 2853 static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
2854 { 2854 {
2855 struct nfs4_file *fp = dp->dl_file; 2855 struct nfs4_file *fp = dp->dl_file;
2856 struct file_lock *fl; 2856 struct file_lock *fl;
2857 int status; 2857 int status;
2858 2858
2859 fl = nfs4_alloc_init_lease(dp, flag); 2859 fl = nfs4_alloc_init_lease(dp, flag);
2860 if (!fl) 2860 if (!fl)
2861 return -ENOMEM; 2861 return -ENOMEM;
2862 fl->fl_file = find_readable_file(fp); 2862 fl->fl_file = find_readable_file(fp);
2863 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); 2863 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
2864 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); 2864 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl);
2865 if (status) { 2865 if (status) {
2866 list_del_init(&dp->dl_perclnt); 2866 list_del_init(&dp->dl_perclnt);
2867 locks_free_lock(fl); 2867 locks_free_lock(fl);
2868 return -ENOMEM; 2868 return -ENOMEM;
2869 } 2869 }
2870 fp->fi_lease = fl; 2870 fp->fi_lease = fl;
2871 fp->fi_deleg_file = fl->fl_file; 2871 fp->fi_deleg_file = fl->fl_file;
2872 get_file(fp->fi_deleg_file); 2872 get_file(fp->fi_deleg_file);
2873 atomic_set(&fp->fi_delegees, 1); 2873 atomic_set(&fp->fi_delegees, 1);
2874 list_add(&dp->dl_perfile, &fp->fi_delegations); 2874 list_add(&dp->dl_perfile, &fp->fi_delegations);
2875 return 0; 2875 return 0;
2876 } 2876 }
2877 2877
2878 static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) 2878 static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag)
2879 { 2879 {
2880 struct nfs4_file *fp = dp->dl_file; 2880 struct nfs4_file *fp = dp->dl_file;
2881 2881
2882 if (!fp->fi_lease) 2882 if (!fp->fi_lease)
2883 return nfs4_setlease(dp, flag); 2883 return nfs4_setlease(dp, flag);
2884 spin_lock(&recall_lock); 2884 spin_lock(&recall_lock);
2885 if (fp->fi_had_conflict) { 2885 if (fp->fi_had_conflict) {
2886 spin_unlock(&recall_lock); 2886 spin_unlock(&recall_lock);
2887 return -EAGAIN; 2887 return -EAGAIN;
2888 } 2888 }
2889 atomic_inc(&fp->fi_delegees); 2889 atomic_inc(&fp->fi_delegees);
2890 list_add(&dp->dl_perfile, &fp->fi_delegations); 2890 list_add(&dp->dl_perfile, &fp->fi_delegations);
2891 spin_unlock(&recall_lock); 2891 spin_unlock(&recall_lock);
2892 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); 2892 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
2893 return 0; 2893 return 0;
2894 } 2894 }
2895 2895
2896 static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status) 2896 static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
2897 { 2897 {
2898 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT; 2898 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
2899 if (status == -EAGAIN) 2899 if (status == -EAGAIN)
2900 open->op_why_no_deleg = WND4_CONTENTION; 2900 open->op_why_no_deleg = WND4_CONTENTION;
2901 else { 2901 else {
2902 open->op_why_no_deleg = WND4_RESOURCE; 2902 open->op_why_no_deleg = WND4_RESOURCE;
2903 switch (open->op_deleg_want) { 2903 switch (open->op_deleg_want) {
2904 case NFS4_SHARE_WANT_READ_DELEG: 2904 case NFS4_SHARE_WANT_READ_DELEG:
2905 case NFS4_SHARE_WANT_WRITE_DELEG: 2905 case NFS4_SHARE_WANT_WRITE_DELEG:
2906 case NFS4_SHARE_WANT_ANY_DELEG: 2906 case NFS4_SHARE_WANT_ANY_DELEG:
2907 break; 2907 break;
2908 case NFS4_SHARE_WANT_CANCEL: 2908 case NFS4_SHARE_WANT_CANCEL:
2909 open->op_why_no_deleg = WND4_CANCELLED; 2909 open->op_why_no_deleg = WND4_CANCELLED;
2910 break; 2910 break;
2911 case NFS4_SHARE_WANT_NO_DELEG: 2911 case NFS4_SHARE_WANT_NO_DELEG:
2912 BUG(); /* not supposed to get here */ 2912 BUG(); /* not supposed to get here */
2913 } 2913 }
2914 } 2914 }
2915 } 2915 }
2916 2916
2917 /* 2917 /*
2918 * Attempt to hand out a delegation. 2918 * Attempt to hand out a delegation.
2919 */ 2919 */
2920 static void 2920 static void
2921 nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_stateid *stp) 2921 nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_stateid *stp)
2922 { 2922 {
2923 struct nfs4_delegation *dp; 2923 struct nfs4_delegation *dp;
2924 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); 2924 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
2925 int cb_up; 2925 int cb_up;
2926 int status = 0, flag = 0; 2926 int status = 0, flag = 0;
2927 2927
2928 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); 2928 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
2929 flag = NFS4_OPEN_DELEGATE_NONE; 2929 flag = NFS4_OPEN_DELEGATE_NONE;
2930 open->op_recall = 0; 2930 open->op_recall = 0;
2931 switch (open->op_claim_type) { 2931 switch (open->op_claim_type) {
2932 case NFS4_OPEN_CLAIM_PREVIOUS: 2932 case NFS4_OPEN_CLAIM_PREVIOUS:
2933 if (!cb_up) 2933 if (!cb_up)
2934 open->op_recall = 1; 2934 open->op_recall = 1;
2935 flag = open->op_delegate_type; 2935 flag = open->op_delegate_type;
2936 if (flag == NFS4_OPEN_DELEGATE_NONE) 2936 if (flag == NFS4_OPEN_DELEGATE_NONE)
2937 goto out; 2937 goto out;
2938 break; 2938 break;
2939 case NFS4_OPEN_CLAIM_NULL: 2939 case NFS4_OPEN_CLAIM_NULL:
2940 /* Let's not give out any delegations till everyone's 2940 /* Let's not give out any delegations till everyone's
2941 * had the chance to reclaim theirs.... */ 2941 * had the chance to reclaim theirs.... */
2942 if (locks_in_grace()) 2942 if (locks_in_grace())
2943 goto out; 2943 goto out;
2944 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) 2944 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
2945 goto out; 2945 goto out;
2946 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 2946 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
2947 flag = NFS4_OPEN_DELEGATE_WRITE; 2947 flag = NFS4_OPEN_DELEGATE_WRITE;
2948 else 2948 else
2949 flag = NFS4_OPEN_DELEGATE_READ; 2949 flag = NFS4_OPEN_DELEGATE_READ;
2950 break; 2950 break;
2951 default: 2951 default:
2952 goto out; 2952 goto out;
2953 } 2953 }
2954 2954
2955 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag); 2955 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag);
2956 if (dp == NULL) 2956 if (dp == NULL)
2957 goto out_no_deleg; 2957 goto out_no_deleg;
2958 status = nfs4_set_delegation(dp, flag); 2958 status = nfs4_set_delegation(dp, flag);
2959 if (status) 2959 if (status)
2960 goto out_free; 2960 goto out_free;
2961 2961
2962 memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl_stid.sc_stateid)); 2962 memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl_stid.sc_stateid));
2963 2963
2964 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", 2964 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
2965 STATEID_VAL(&dp->dl_stid.sc_stateid)); 2965 STATEID_VAL(&dp->dl_stid.sc_stateid));
2966 out: 2966 out:
2967 open->op_delegate_type = flag; 2967 open->op_delegate_type = flag;
2968 if (flag == NFS4_OPEN_DELEGATE_NONE) { 2968 if (flag == NFS4_OPEN_DELEGATE_NONE) {
2969 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS && 2969 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
2970 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) 2970 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
2971 dprintk("NFSD: WARNING: refusing delegation reclaim\n"); 2971 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
2972 2972
2973 /* 4.1 client asking for a delegation? */ 2973 /* 4.1 client asking for a delegation? */
2974 if (open->op_deleg_want) 2974 if (open->op_deleg_want)
2975 nfsd4_open_deleg_none_ext(open, status); 2975 nfsd4_open_deleg_none_ext(open, status);
2976 } 2976 }
2977 return; 2977 return;
2978 out_free: 2978 out_free:
2979 nfs4_put_delegation(dp); 2979 nfs4_put_delegation(dp);
2980 out_no_deleg: 2980 out_no_deleg:
2981 flag = NFS4_OPEN_DELEGATE_NONE; 2981 flag = NFS4_OPEN_DELEGATE_NONE;
2982 goto out; 2982 goto out;
2983 } 2983 }
2984 2984
2985 static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open, 2985 static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
2986 struct nfs4_delegation *dp) 2986 struct nfs4_delegation *dp)
2987 { 2987 {
2988 if (open->op_deleg_want == NFS4_SHARE_WANT_READ_DELEG && 2988 if (open->op_deleg_want == NFS4_SHARE_WANT_READ_DELEG &&
2989 dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) { 2989 dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
2990 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT; 2990 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
2991 open->op_why_no_deleg = WND4_NOT_SUPP_DOWNGRADE; 2991 open->op_why_no_deleg = WND4_NOT_SUPP_DOWNGRADE;
2992 } else if (open->op_deleg_want == NFS4_SHARE_WANT_WRITE_DELEG && 2992 } else if (open->op_deleg_want == NFS4_SHARE_WANT_WRITE_DELEG &&
2993 dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) { 2993 dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
2994 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT; 2994 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
2995 open->op_why_no_deleg = WND4_NOT_SUPP_UPGRADE; 2995 open->op_why_no_deleg = WND4_NOT_SUPP_UPGRADE;
2996 } 2996 }
2997 /* Otherwise the client must be confused wanting a delegation 2997 /* Otherwise the client must be confused wanting a delegation
2998 * it already has, therefore we don't return 2998 * it already has, therefore we don't return
2999 * NFS4_OPEN_DELEGATE_NONE_EXT and reason. 2999 * NFS4_OPEN_DELEGATE_NONE_EXT and reason.
3000 */ 3000 */
3001 } 3001 }
3002 3002
3003 /* 3003 /*
3004 * called with nfs4_lock_state() held. 3004 * called with nfs4_lock_state() held.
3005 */ 3005 */
3006 __be32 3006 __be32
3007 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 3007 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
3008 { 3008 {
3009 struct nfsd4_compoundres *resp = rqstp->rq_resp; 3009 struct nfsd4_compoundres *resp = rqstp->rq_resp;
3010 struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; 3010 struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
3011 struct nfs4_file *fp = NULL; 3011 struct nfs4_file *fp = NULL;
3012 struct inode *ino = current_fh->fh_dentry->d_inode; 3012 struct inode *ino = current_fh->fh_dentry->d_inode;
3013 struct nfs4_ol_stateid *stp = NULL; 3013 struct nfs4_ol_stateid *stp = NULL;
3014 struct nfs4_delegation *dp = NULL; 3014 struct nfs4_delegation *dp = NULL;
3015 __be32 status; 3015 __be32 status;
3016 3016
3017 /* 3017 /*
3018 * Lookup file; if found, lookup stateid and check open request, 3018 * Lookup file; if found, lookup stateid and check open request,
3019 * and check for delegations in the process of being recalled. 3019 * and check for delegations in the process of being recalled.
3020 * If not found, create the nfs4_file struct 3020 * If not found, create the nfs4_file struct
3021 */ 3021 */
3022 fp = find_file(ino); 3022 fp = find_file(ino);
3023 if (fp) { 3023 if (fp) {
3024 if ((status = nfs4_check_open(fp, open, &stp))) 3024 if ((status = nfs4_check_open(fp, open, &stp)))
3025 goto out; 3025 goto out;
3026 status = nfs4_check_deleg(cl, fp, open, &dp); 3026 status = nfs4_check_deleg(cl, fp, open, &dp);
3027 if (status) 3027 if (status)
3028 goto out; 3028 goto out;
3029 } else { 3029 } else {
3030 status = nfserr_bad_stateid; 3030 status = nfserr_bad_stateid;
3031 if (nfsd4_is_deleg_cur(open)) 3031 if (nfsd4_is_deleg_cur(open))
3032 goto out; 3032 goto out;
3033 status = nfserr_jukebox; 3033 status = nfserr_jukebox;
3034 fp = open->op_file; 3034 fp = open->op_file;
3035 open->op_file = NULL; 3035 open->op_file = NULL;
3036 nfsd4_init_file(fp, ino); 3036 nfsd4_init_file(fp, ino);
3037 } 3037 }
3038 3038
3039 /* 3039 /*
3040 * OPEN the file, or upgrade an existing OPEN. 3040 * OPEN the file, or upgrade an existing OPEN.
3041 * If truncate fails, the OPEN fails. 3041 * If truncate fails, the OPEN fails.
3042 */ 3042 */
3043 if (stp) { 3043 if (stp) {
3044 /* Stateid was found, this is an OPEN upgrade */ 3044 /* Stateid was found, this is an OPEN upgrade */
3045 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open); 3045 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
3046 if (status) 3046 if (status)
3047 goto out; 3047 goto out;
3048 } else { 3048 } else {
3049 status = nfs4_get_vfs_file(rqstp, fp, current_fh, open); 3049 status = nfs4_get_vfs_file(rqstp, fp, current_fh, open);
3050 if (status) 3050 if (status)
3051 goto out; 3051 goto out;
3052 stp = open->op_stp; 3052 stp = open->op_stp;
3053 open->op_stp = NULL; 3053 open->op_stp = NULL;
3054 init_open_stateid(stp, fp, open); 3054 init_open_stateid(stp, fp, open);
3055 status = nfsd4_truncate(rqstp, current_fh, open); 3055 status = nfsd4_truncate(rqstp, current_fh, open);
3056 if (status) { 3056 if (status) {
3057 release_open_stateid(stp); 3057 release_open_stateid(stp);
3058 goto out; 3058 goto out;
3059 } 3059 }
3060 } 3060 }
3061 update_stateid(&stp->st_stid.sc_stateid); 3061 update_stateid(&stp->st_stid.sc_stateid);
3062 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3062 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3063 3063
3064 if (nfsd4_has_session(&resp->cstate)) { 3064 if (nfsd4_has_session(&resp->cstate)) {
3065 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 3065 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
3066 3066
3067 if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) { 3067 if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
3068 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT; 3068 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
3069 open->op_why_no_deleg = WND4_NOT_WANTED; 3069 open->op_why_no_deleg = WND4_NOT_WANTED;
3070 goto nodeleg; 3070 goto nodeleg;
3071 } 3071 }
3072 } 3072 }
3073 3073
3074 /* 3074 /*
3075 * Attempt to hand out a delegation. No error return, because the 3075 * Attempt to hand out a delegation. No error return, because the
3076 * OPEN succeeds even if we fail. 3076 * OPEN succeeds even if we fail.
3077 */ 3077 */
3078 nfs4_open_delegation(current_fh, open, stp); 3078 nfs4_open_delegation(current_fh, open, stp);
3079 nodeleg: 3079 nodeleg:
3080 status = nfs_ok; 3080 status = nfs_ok;
3081 3081
3082 dprintk("%s: stateid=" STATEID_FMT "\n", __func__, 3082 dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
3083 STATEID_VAL(&stp->st_stid.sc_stateid)); 3083 STATEID_VAL(&stp->st_stid.sc_stateid));
3084 out: 3084 out:
3085 /* 4.1 client trying to upgrade/downgrade delegation? */ 3085 /* 4.1 client trying to upgrade/downgrade delegation? */
3086 if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp && 3086 if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
3087 open->op_deleg_want) 3087 open->op_deleg_want)
3088 nfsd4_deleg_xgrade_none_ext(open, dp); 3088 nfsd4_deleg_xgrade_none_ext(open, dp);
3089 3089
3090 if (fp) 3090 if (fp)
3091 put_nfs4_file(fp); 3091 put_nfs4_file(fp);
3092 if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 3092 if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
3093 nfs4_set_claim_prev(open, nfsd4_has_session(&resp->cstate)); 3093 nfs4_set_claim_prev(open, nfsd4_has_session(&resp->cstate));
3094 /* 3094 /*
3095 * To finish the open response, we just need to set the rflags. 3095 * To finish the open response, we just need to set the rflags.
3096 */ 3096 */
3097 open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX; 3097 open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
3098 if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED) && 3098 if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED) &&
3099 !nfsd4_has_session(&resp->cstate)) 3099 !nfsd4_has_session(&resp->cstate))
3100 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; 3100 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
3101 3101
3102 return status; 3102 return status;
3103 } 3103 }
3104 3104
3105 void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) 3105 void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status)
3106 { 3106 {
3107 if (open->op_openowner) { 3107 if (open->op_openowner) {
3108 struct nfs4_openowner *oo = open->op_openowner; 3108 struct nfs4_openowner *oo = open->op_openowner;
3109 3109
3110 if (!list_empty(&oo->oo_owner.so_stateids)) 3110 if (!list_empty(&oo->oo_owner.so_stateids))
3111 list_del_init(&oo->oo_close_lru); 3111 list_del_init(&oo->oo_close_lru);
3112 if (oo->oo_flags & NFS4_OO_NEW) { 3112 if (oo->oo_flags & NFS4_OO_NEW) {
3113 if (status) { 3113 if (status) {
3114 release_openowner(oo); 3114 release_openowner(oo);
3115 open->op_openowner = NULL; 3115 open->op_openowner = NULL;
3116 } else 3116 } else
3117 oo->oo_flags &= ~NFS4_OO_NEW; 3117 oo->oo_flags &= ~NFS4_OO_NEW;
3118 } 3118 }
3119 } 3119 }
3120 if (open->op_file) 3120 if (open->op_file)
3121 nfsd4_free_file(open->op_file); 3121 nfsd4_free_file(open->op_file);
3122 if (open->op_stp) 3122 if (open->op_stp)
3123 nfs4_free_stateid(open->op_stp); 3123 nfs4_free_stateid(open->op_stp);
3124 } 3124 }
3125 3125
3126 __be32 3126 __be32
3127 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3127 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3128 clientid_t *clid) 3128 clientid_t *clid)
3129 { 3129 {
3130 struct nfs4_client *clp; 3130 struct nfs4_client *clp;
3131 __be32 status; 3131 __be32 status;
3132 3132
3133 nfs4_lock_state(); 3133 nfs4_lock_state();
3134 dprintk("process_renew(%08x/%08x): starting\n", 3134 dprintk("process_renew(%08x/%08x): starting\n",
3135 clid->cl_boot, clid->cl_id); 3135 clid->cl_boot, clid->cl_id);
3136 status = nfserr_stale_clientid; 3136 status = nfserr_stale_clientid;
3137 if (STALE_CLIENTID(clid)) 3137 if (STALE_CLIENTID(clid))
3138 goto out; 3138 goto out;
3139 clp = find_confirmed_client(clid); 3139 clp = find_confirmed_client(clid);
3140 status = nfserr_expired; 3140 status = nfserr_expired;
3141 if (clp == NULL) { 3141 if (clp == NULL) {
3142 /* We assume the client took too long to RENEW. */ 3142 /* We assume the client took too long to RENEW. */
3143 dprintk("nfsd4_renew: clientid not found!\n"); 3143 dprintk("nfsd4_renew: clientid not found!\n");
3144 goto out; 3144 goto out;
3145 } 3145 }
3146 status = nfserr_cb_path_down; 3146 status = nfserr_cb_path_down;
3147 if (!list_empty(&clp->cl_delegations) 3147 if (!list_empty(&clp->cl_delegations)
3148 && clp->cl_cb_state != NFSD4_CB_UP) 3148 && clp->cl_cb_state != NFSD4_CB_UP)
3149 goto out; 3149 goto out;
3150 status = nfs_ok; 3150 status = nfs_ok;
3151 out: 3151 out:
3152 nfs4_unlock_state(); 3152 nfs4_unlock_state();
3153 return status; 3153 return status;
3154 } 3154 }
3155 3155
3156 static struct lock_manager nfsd4_manager = { 3156 static struct lock_manager nfsd4_manager = {
3157 }; 3157 };
3158 3158
3159 static bool grace_ended; 3159 static bool grace_ended;
3160 3160
3161 static void 3161 static void
3162 nfsd4_end_grace(void) 3162 nfsd4_end_grace(void)
3163 { 3163 {
3164 /* do nothing if grace period already ended */ 3164 /* do nothing if grace period already ended */
3165 if (grace_ended) 3165 if (grace_ended)
3166 return; 3166 return;
3167 3167
3168 dprintk("NFSD: end of grace period\n"); 3168 dprintk("NFSD: end of grace period\n");
3169 grace_ended = true; 3169 grace_ended = true;
3170 nfsd4_record_grace_done(&init_net, boot_time); 3170 nfsd4_record_grace_done(&init_net, boot_time);
3171 locks_end_grace(&nfsd4_manager); 3171 locks_end_grace(&nfsd4_manager);
3172 /* 3172 /*
3173 * Now that every NFSv4 client has had the chance to recover and 3173 * Now that every NFSv4 client has had the chance to recover and
3174 * to see the (possibly new, possibly shorter) lease time, we 3174 * to see the (possibly new, possibly shorter) lease time, we
3175 * can safely set the next grace time to the current lease time: 3175 * can safely set the next grace time to the current lease time:
3176 */ 3176 */
3177 nfsd4_grace = nfsd4_lease; 3177 nfsd4_grace = nfsd4_lease;
3178 } 3178 }
3179 3179
3180 static time_t 3180 static time_t
3181 nfs4_laundromat(void) 3181 nfs4_laundromat(void)
3182 { 3182 {
3183 struct nfs4_client *clp; 3183 struct nfs4_client *clp;
3184 struct nfs4_openowner *oo; 3184 struct nfs4_openowner *oo;
3185 struct nfs4_delegation *dp; 3185 struct nfs4_delegation *dp;
3186 struct list_head *pos, *next, reaplist; 3186 struct list_head *pos, *next, reaplist;
3187 time_t cutoff = get_seconds() - nfsd4_lease; 3187 time_t cutoff = get_seconds() - nfsd4_lease;
3188 time_t t, clientid_val = nfsd4_lease; 3188 time_t t, clientid_val = nfsd4_lease;
3189 time_t u, test_val = nfsd4_lease; 3189 time_t u, test_val = nfsd4_lease;
3190 3190
3191 nfs4_lock_state(); 3191 nfs4_lock_state();
3192 3192
3193 dprintk("NFSD: laundromat service - starting\n"); 3193 dprintk("NFSD: laundromat service - starting\n");
3194 nfsd4_end_grace(); 3194 nfsd4_end_grace();
3195 INIT_LIST_HEAD(&reaplist); 3195 INIT_LIST_HEAD(&reaplist);
3196 spin_lock(&client_lock); 3196 spin_lock(&client_lock);
3197 list_for_each_safe(pos, next, &client_lru) { 3197 list_for_each_safe(pos, next, &client_lru) {
3198 clp = list_entry(pos, struct nfs4_client, cl_lru); 3198 clp = list_entry(pos, struct nfs4_client, cl_lru);
3199 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 3199 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
3200 t = clp->cl_time - cutoff; 3200 t = clp->cl_time - cutoff;
3201 if (clientid_val > t) 3201 if (clientid_val > t)
3202 clientid_val = t; 3202 clientid_val = t;
3203 break; 3203 break;
3204 } 3204 }
3205 if (atomic_read(&clp->cl_refcount)) { 3205 if (atomic_read(&clp->cl_refcount)) {
3206 dprintk("NFSD: client in use (clientid %08x)\n", 3206 dprintk("NFSD: client in use (clientid %08x)\n",
3207 clp->cl_clientid.cl_id); 3207 clp->cl_clientid.cl_id);
3208 continue; 3208 continue;
3209 } 3209 }
3210 unhash_client_locked(clp); 3210 unhash_client_locked(clp);
3211 list_add(&clp->cl_lru, &reaplist); 3211 list_add(&clp->cl_lru, &reaplist);
3212 } 3212 }
3213 spin_unlock(&client_lock); 3213 spin_unlock(&client_lock);
3214 list_for_each_safe(pos, next, &reaplist) { 3214 list_for_each_safe(pos, next, &reaplist) {
3215 clp = list_entry(pos, struct nfs4_client, cl_lru); 3215 clp = list_entry(pos, struct nfs4_client, cl_lru);
3216 dprintk("NFSD: purging unused client (clientid %08x)\n", 3216 dprintk("NFSD: purging unused client (clientid %08x)\n",
3217 clp->cl_clientid.cl_id); 3217 clp->cl_clientid.cl_id);
3218 nfsd4_client_record_remove(clp); 3218 nfsd4_client_record_remove(clp);
3219 expire_client(clp); 3219 expire_client(clp);
3220 } 3220 }
3221 spin_lock(&recall_lock); 3221 spin_lock(&recall_lock);
3222 list_for_each_safe(pos, next, &del_recall_lru) { 3222 list_for_each_safe(pos, next, &del_recall_lru) {
3223 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 3223 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3224 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) { 3224 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
3225 u = dp->dl_time - cutoff; 3225 u = dp->dl_time - cutoff;
3226 if (test_val > u) 3226 if (test_val > u)
3227 test_val = u; 3227 test_val = u;
3228 break; 3228 break;
3229 } 3229 }
3230 list_move(&dp->dl_recall_lru, &reaplist); 3230 list_move(&dp->dl_recall_lru, &reaplist);
3231 } 3231 }
3232 spin_unlock(&recall_lock); 3232 spin_unlock(&recall_lock);
3233 list_for_each_safe(pos, next, &reaplist) { 3233 list_for_each_safe(pos, next, &reaplist) {
3234 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 3234 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3235 unhash_delegation(dp); 3235 unhash_delegation(dp);
3236 } 3236 }
3237 test_val = nfsd4_lease; 3237 test_val = nfsd4_lease;
3238 list_for_each_safe(pos, next, &close_lru) { 3238 list_for_each_safe(pos, next, &close_lru) {
3239 oo = container_of(pos, struct nfs4_openowner, oo_close_lru); 3239 oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
3240 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) { 3240 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
3241 u = oo->oo_time - cutoff; 3241 u = oo->oo_time - cutoff;
3242 if (test_val > u) 3242 if (test_val > u)
3243 test_val = u; 3243 test_val = u;
3244 break; 3244 break;
3245 } 3245 }
3246 release_openowner(oo); 3246 release_openowner(oo);
3247 } 3247 }
3248 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) 3248 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
3249 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; 3249 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
3250 nfs4_unlock_state(); 3250 nfs4_unlock_state();
3251 return clientid_val; 3251 return clientid_val;
3252 } 3252 }
3253 3253
3254 static struct workqueue_struct *laundry_wq; 3254 static struct workqueue_struct *laundry_wq;
3255 static void laundromat_main(struct work_struct *); 3255 static void laundromat_main(struct work_struct *);
3256 static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main); 3256 static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main);
3257 3257
3258 static void 3258 static void
3259 laundromat_main(struct work_struct *not_used) 3259 laundromat_main(struct work_struct *not_used)
3260 { 3260 {
3261 time_t t; 3261 time_t t;
3262 3262
3263 t = nfs4_laundromat(); 3263 t = nfs4_laundromat();
3264 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t); 3264 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
3265 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 3265 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
3266 } 3266 }
3267 3267
3268 static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp) 3268 static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
3269 { 3269 {
3270 if (fhp->fh_dentry->d_inode != stp->st_file->fi_inode) 3270 if (fhp->fh_dentry->d_inode != stp->st_file->fi_inode)
3271 return nfserr_bad_stateid; 3271 return nfserr_bad_stateid;
3272 return nfs_ok; 3272 return nfs_ok;
3273 } 3273 }
3274 3274
3275 static int 3275 static int
3276 STALE_STATEID(stateid_t *stateid) 3276 STALE_STATEID(stateid_t *stateid)
3277 { 3277 {
3278 if (stateid->si_opaque.so_clid.cl_boot == boot_time) 3278 if (stateid->si_opaque.so_clid.cl_boot == boot_time)
3279 return 0; 3279 return 0;
3280 dprintk("NFSD: stale stateid " STATEID_FMT "!\n", 3280 dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
3281 STATEID_VAL(stateid)); 3281 STATEID_VAL(stateid));
3282 return 1; 3282 return 1;
3283 } 3283 }
3284 3284
3285 static inline int 3285 static inline int
3286 access_permit_read(unsigned long access_bmap) 3286 access_permit_read(unsigned long access_bmap)
3287 { 3287 {
3288 return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || 3288 return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
3289 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) || 3289 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) ||
3290 test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap); 3290 test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap);
3291 } 3291 }
3292 3292
3293 static inline int 3293 static inline int
3294 access_permit_write(unsigned long access_bmap) 3294 access_permit_write(unsigned long access_bmap)
3295 { 3295 {
3296 return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || 3296 return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
3297 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); 3297 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
3298 } 3298 }
3299 3299
3300 static 3300 static
3301 __be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags) 3301 __be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
3302 { 3302 {
3303 __be32 status = nfserr_openmode; 3303 __be32 status = nfserr_openmode;
3304 3304
3305 /* For lock stateid's, we test the parent open, not the lock: */ 3305 /* For lock stateid's, we test the parent open, not the lock: */
3306 if (stp->st_openstp) 3306 if (stp->st_openstp)
3307 stp = stp->st_openstp; 3307 stp = stp->st_openstp;
3308 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 3308 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
3309 goto out; 3309 goto out;
3310 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) 3310 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
3311 goto out; 3311 goto out;
3312 status = nfs_ok; 3312 status = nfs_ok;
3313 out: 3313 out:
3314 return status; 3314 return status;
3315 } 3315 }
3316 3316
3317 static inline __be32 3317 static inline __be32
3318 check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) 3318 check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
3319 { 3319 {
3320 if (ONE_STATEID(stateid) && (flags & RD_STATE)) 3320 if (ONE_STATEID(stateid) && (flags & RD_STATE))
3321 return nfs_ok; 3321 return nfs_ok;
3322 else if (locks_in_grace()) { 3322 else if (locks_in_grace()) {
3323 /* Answer in remaining cases depends on existence of 3323 /* Answer in remaining cases depends on existence of
3324 * conflicting state; so we must wait out the grace period. */ 3324 * conflicting state; so we must wait out the grace period. */
3325 return nfserr_grace; 3325 return nfserr_grace;
3326 } else if (flags & WR_STATE) 3326 } else if (flags & WR_STATE)
3327 return nfs4_share_conflict(current_fh, 3327 return nfs4_share_conflict(current_fh,
3328 NFS4_SHARE_DENY_WRITE); 3328 NFS4_SHARE_DENY_WRITE);
3329 else /* (flags & RD_STATE) && ZERO_STATEID(stateid) */ 3329 else /* (flags & RD_STATE) && ZERO_STATEID(stateid) */
3330 return nfs4_share_conflict(current_fh, 3330 return nfs4_share_conflict(current_fh,
3331 NFS4_SHARE_DENY_READ); 3331 NFS4_SHARE_DENY_READ);
3332 } 3332 }
3333 3333
3334 /* 3334 /*
3335 * Allow READ/WRITE during grace period on recovered state only for files 3335 * Allow READ/WRITE during grace period on recovered state only for files
3336 * that are not able to provide mandatory locking. 3336 * that are not able to provide mandatory locking.
3337 */ 3337 */
3338 static inline int 3338 static inline int
3339 grace_disallows_io(struct inode *inode) 3339 grace_disallows_io(struct inode *inode)
3340 { 3340 {
3341 return locks_in_grace() && mandatory_lock(inode); 3341 return locks_in_grace() && mandatory_lock(inode);
3342 } 3342 }
3343 3343
3344 /* Returns true iff a is later than b: */ 3344 /* Returns true iff a is later than b: */
3345 static bool stateid_generation_after(stateid_t *a, stateid_t *b) 3345 static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3346 { 3346 {
3347 return (s32)a->si_generation - (s32)b->si_generation > 0; 3347 return (s32)a->si_generation - (s32)b->si_generation > 0;
3348 } 3348 }
3349 3349
3350 static int check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3350 static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
3351 { 3351 {
3352 /* 3352 /*
3353 * When sessions are used the stateid generation number is ignored 3353 * When sessions are used the stateid generation number is ignored
3354 * when it is zero. 3354 * when it is zero.
3355 */ 3355 */
3356 if (has_session && in->si_generation == 0) 3356 if (has_session && in->si_generation == 0)
3357 return nfs_ok; 3357 return nfs_ok;
3358 3358
3359 if (in->si_generation == ref->si_generation) 3359 if (in->si_generation == ref->si_generation)
3360 return nfs_ok; 3360 return nfs_ok;
3361 3361
3362 /* If the client sends us a stateid from the future, it's buggy: */ 3362 /* If the client sends us a stateid from the future, it's buggy: */
3363 if (stateid_generation_after(in, ref)) 3363 if (stateid_generation_after(in, ref))
3364 return nfserr_bad_stateid; 3364 return nfserr_bad_stateid;
3365 /* 3365 /*
3366 * However, we could see a stateid from the past, even from a 3366 * However, we could see a stateid from the past, even from a
3367 * non-buggy client. For example, if the client sends a lock 3367 * non-buggy client. For example, if the client sends a lock
3368 * while some IO is outstanding, the lock may bump si_generation 3368 * while some IO is outstanding, the lock may bump si_generation
3369 * while the IO is still in flight. The client could avoid that 3369 * while the IO is still in flight. The client could avoid that
3370 * situation by waiting for responses on all the IO requests, 3370 * situation by waiting for responses on all the IO requests,
3371 * but better performance may result in retrying IO that 3371 * but better performance may result in retrying IO that
3372 * receives an old_stateid error if requests are rarely 3372 * receives an old_stateid error if requests are rarely
3373 * reordered in flight: 3373 * reordered in flight:
3374 */ 3374 */
3375 return nfserr_old_stateid; 3375 return nfserr_old_stateid;
3376 } 3376 }
3377 3377
3378 __be32 nfs4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) 3378 __be32 nfs4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
3379 { 3379 {
3380 struct nfs4_stid *s; 3380 struct nfs4_stid *s;
3381 struct nfs4_ol_stateid *ols; 3381 struct nfs4_ol_stateid *ols;
3382 __be32 status; 3382 __be32 status;
3383 3383
3384 if (STALE_STATEID(stateid)) 3384 if (STALE_STATEID(stateid))
3385 return nfserr_stale_stateid; 3385 return nfserr_stale_stateid;
3386 3386
3387 s = find_stateid(cl, stateid); 3387 s = find_stateid(cl, stateid);
3388 if (!s) 3388 if (!s)
3389 return nfserr_stale_stateid; 3389 return nfserr_stale_stateid;
3390 status = check_stateid_generation(stateid, &s->sc_stateid, 1); 3390 status = check_stateid_generation(stateid, &s->sc_stateid, 1);
3391 if (status) 3391 if (status)
3392 return status; 3392 return status;
3393 if (!(s->sc_type & (NFS4_OPEN_STID | NFS4_LOCK_STID))) 3393 if (!(s->sc_type & (NFS4_OPEN_STID | NFS4_LOCK_STID)))
3394 return nfs_ok; 3394 return nfs_ok;
3395 ols = openlockstateid(s); 3395 ols = openlockstateid(s);
3396 if (ols->st_stateowner->so_is_open_owner 3396 if (ols->st_stateowner->so_is_open_owner
3397 && !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED)) 3397 && !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
3398 return nfserr_bad_stateid; 3398 return nfserr_bad_stateid;
3399 return nfs_ok; 3399 return nfs_ok;
3400 } 3400 }
3401 3401
3402 static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s) 3402 static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s)
3403 { 3403 {
3404 struct nfs4_client *cl; 3404 struct nfs4_client *cl;
3405 3405
3406 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3406 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3407 return nfserr_bad_stateid; 3407 return nfserr_bad_stateid;
3408 if (STALE_STATEID(stateid)) 3408 if (STALE_STATEID(stateid))
3409 return nfserr_stale_stateid; 3409 return nfserr_stale_stateid;
3410 cl = find_confirmed_client(&stateid->si_opaque.so_clid); 3410 cl = find_confirmed_client(&stateid->si_opaque.so_clid);
3411 if (!cl) 3411 if (!cl)
3412 return nfserr_expired; 3412 return nfserr_expired;
3413 *s = find_stateid_by_type(cl, stateid, typemask); 3413 *s = find_stateid_by_type(cl, stateid, typemask);
3414 if (!*s) 3414 if (!*s)
3415 return nfserr_bad_stateid; 3415 return nfserr_bad_stateid;
3416 return nfs_ok; 3416 return nfs_ok;
3417 3417
3418 } 3418 }
3419 3419
3420 /* 3420 /*
3421 * Checks for stateid operations 3421 * Checks for stateid operations
3422 */ 3422 */
3423 __be32 3423 __be32
3424 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, 3424 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3425 stateid_t *stateid, int flags, struct file **filpp) 3425 stateid_t *stateid, int flags, struct file **filpp)
3426 { 3426 {
3427 struct nfs4_stid *s; 3427 struct nfs4_stid *s;
3428 struct nfs4_ol_stateid *stp = NULL; 3428 struct nfs4_ol_stateid *stp = NULL;
3429 struct nfs4_delegation *dp = NULL; 3429 struct nfs4_delegation *dp = NULL;
3430 struct svc_fh *current_fh = &cstate->current_fh; 3430 struct svc_fh *current_fh = &cstate->current_fh;
3431 struct inode *ino = current_fh->fh_dentry->d_inode; 3431 struct inode *ino = current_fh->fh_dentry->d_inode;
3432 __be32 status; 3432 __be32 status;
3433 3433
3434 if (filpp) 3434 if (filpp)
3435 *filpp = NULL; 3435 *filpp = NULL;
3436 3436
3437 if (grace_disallows_io(ino)) 3437 if (grace_disallows_io(ino))
3438 return nfserr_grace; 3438 return nfserr_grace;
3439 3439
3440 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3440 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3441 return check_special_stateids(current_fh, stateid, flags); 3441 return check_special_stateids(current_fh, stateid, flags);
3442 3442
3443 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s); 3443 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s);
3444 if (status) 3444 if (status)
3445 return status; 3445 return status;
3446 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate)); 3446 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
3447 if (status) 3447 if (status)
3448 goto out; 3448 goto out;
3449 switch (s->sc_type) { 3449 switch (s->sc_type) {
3450 case NFS4_DELEG_STID: 3450 case NFS4_DELEG_STID:
3451 dp = delegstateid(s); 3451 dp = delegstateid(s);
3452 status = nfs4_check_delegmode(dp, flags); 3452 status = nfs4_check_delegmode(dp, flags);
3453 if (status) 3453 if (status)
3454 goto out; 3454 goto out;
3455 if (filpp) { 3455 if (filpp) {
3456 *filpp = dp->dl_file->fi_deleg_file; 3456 *filpp = dp->dl_file->fi_deleg_file;
3457 BUG_ON(!*filpp); 3457 BUG_ON(!*filpp);
3458 } 3458 }
3459 break; 3459 break;
3460 case NFS4_OPEN_STID: 3460 case NFS4_OPEN_STID:
3461 case NFS4_LOCK_STID: 3461 case NFS4_LOCK_STID:
3462 stp = openlockstateid(s); 3462 stp = openlockstateid(s);
3463 status = nfs4_check_fh(current_fh, stp); 3463 status = nfs4_check_fh(current_fh, stp);
3464 if (status) 3464 if (status)
3465 goto out; 3465 goto out;
3466 if (stp->st_stateowner->so_is_open_owner 3466 if (stp->st_stateowner->so_is_open_owner
3467 && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED)) 3467 && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
3468 goto out; 3468 goto out;
3469 status = nfs4_check_openmode(stp, flags); 3469 status = nfs4_check_openmode(stp, flags);
3470 if (status) 3470 if (status)
3471 goto out; 3471 goto out;
3472 if (filpp) { 3472 if (filpp) {
3473 if (flags & RD_STATE) 3473 if (flags & RD_STATE)
3474 *filpp = find_readable_file(stp->st_file); 3474 *filpp = find_readable_file(stp->st_file);
3475 else 3475 else
3476 *filpp = find_writeable_file(stp->st_file); 3476 *filpp = find_writeable_file(stp->st_file);
3477 } 3477 }
3478 break; 3478 break;
3479 default: 3479 default:
3480 return nfserr_bad_stateid; 3480 return nfserr_bad_stateid;
3481 } 3481 }
3482 status = nfs_ok; 3482 status = nfs_ok;
3483 out: 3483 out:
3484 return status; 3484 return status;
3485 } 3485 }
3486 3486
3487 static __be32 3487 static __be32
3488 nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp) 3488 nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
3489 { 3489 {
3490 if (check_for_locks(stp->st_file, lockowner(stp->st_stateowner))) 3490 if (check_for_locks(stp->st_file, lockowner(stp->st_stateowner)))
3491 return nfserr_locks_held; 3491 return nfserr_locks_held;
3492 release_lock_stateid(stp); 3492 release_lock_stateid(stp);
3493 return nfs_ok; 3493 return nfs_ok;
3494 } 3494 }
3495 3495
3496 /* 3496 /*
3497 * Test if the stateid is valid 3497 * Test if the stateid is valid
3498 */ 3498 */
3499 __be32 3499 __be32
3500 nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3500 nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3501 struct nfsd4_test_stateid *test_stateid) 3501 struct nfsd4_test_stateid *test_stateid)
3502 { 3502 {
3503 struct nfsd4_test_stateid_id *stateid; 3503 struct nfsd4_test_stateid_id *stateid;
3504 struct nfs4_client *cl = cstate->session->se_client; 3504 struct nfs4_client *cl = cstate->session->se_client;
3505 3505
3506 nfs4_lock_state(); 3506 nfs4_lock_state();
3507 list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list) 3507 list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
3508 stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid); 3508 stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid);
3509 nfs4_unlock_state(); 3509 nfs4_unlock_state();
3510 3510
3511 return nfs_ok; 3511 return nfs_ok;
3512 } 3512 }
3513 3513
3514 __be32 3514 __be32
3515 nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3515 nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3516 struct nfsd4_free_stateid *free_stateid) 3516 struct nfsd4_free_stateid *free_stateid)
3517 { 3517 {
3518 stateid_t *stateid = &free_stateid->fr_stateid; 3518 stateid_t *stateid = &free_stateid->fr_stateid;
3519 struct nfs4_stid *s; 3519 struct nfs4_stid *s;
3520 struct nfs4_client *cl = cstate->session->se_client; 3520 struct nfs4_client *cl = cstate->session->se_client;
3521 __be32 ret = nfserr_bad_stateid; 3521 __be32 ret = nfserr_bad_stateid;
3522 3522
3523 nfs4_lock_state(); 3523 nfs4_lock_state();
3524 s = find_stateid(cl, stateid); 3524 s = find_stateid(cl, stateid);
3525 if (!s) 3525 if (!s)
3526 goto out; 3526 goto out;
3527 switch (s->sc_type) { 3527 switch (s->sc_type) {
3528 case NFS4_DELEG_STID: 3528 case NFS4_DELEG_STID:
3529 ret = nfserr_locks_held; 3529 ret = nfserr_locks_held;
3530 goto out; 3530 goto out;
3531 case NFS4_OPEN_STID: 3531 case NFS4_OPEN_STID:
3532 case NFS4_LOCK_STID: 3532 case NFS4_LOCK_STID:
3533 ret = check_stateid_generation(stateid, &s->sc_stateid, 1); 3533 ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
3534 if (ret) 3534 if (ret)
3535 goto out; 3535 goto out;
3536 if (s->sc_type == NFS4_LOCK_STID) 3536 if (s->sc_type == NFS4_LOCK_STID)
3537 ret = nfsd4_free_lock_stateid(openlockstateid(s)); 3537 ret = nfsd4_free_lock_stateid(openlockstateid(s));
3538 else 3538 else
3539 ret = nfserr_locks_held; 3539 ret = nfserr_locks_held;
3540 break; 3540 break;
3541 default: 3541 default:
3542 ret = nfserr_bad_stateid; 3542 ret = nfserr_bad_stateid;
3543 } 3543 }
3544 out: 3544 out:
3545 nfs4_unlock_state(); 3545 nfs4_unlock_state();
3546 return ret; 3546 return ret;
3547 } 3547 }
3548 3548
3549 static inline int 3549 static inline int
3550 setlkflg (int type) 3550 setlkflg (int type)
3551 { 3551 {
3552 return (type == NFS4_READW_LT || type == NFS4_READ_LT) ? 3552 return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
3553 RD_STATE : WR_STATE; 3553 RD_STATE : WR_STATE;
3554 } 3554 }
3555 3555
3556 static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_ol_stateid *stp) 3556 static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_ol_stateid *stp)
3557 { 3557 {
3558 struct svc_fh *current_fh = &cstate->current_fh; 3558 struct svc_fh *current_fh = &cstate->current_fh;
3559 struct nfs4_stateowner *sop = stp->st_stateowner; 3559 struct nfs4_stateowner *sop = stp->st_stateowner;
3560 __be32 status; 3560 __be32 status;
3561 3561
3562 status = nfsd4_check_seqid(cstate, sop, seqid); 3562 status = nfsd4_check_seqid(cstate, sop, seqid);
3563 if (status) 3563 if (status)
3564 return status; 3564 return status;
3565 if (stp->st_stid.sc_type == NFS4_CLOSED_STID) 3565 if (stp->st_stid.sc_type == NFS4_CLOSED_STID)
3566 /* 3566 /*
3567 * "Closed" stateid's exist *only* to return 3567 * "Closed" stateid's exist *only* to return
3568 * nfserr_replay_me from the previous step. 3568 * nfserr_replay_me from the previous step.
3569 */ 3569 */
3570 return nfserr_bad_stateid; 3570 return nfserr_bad_stateid;
3571 status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate)); 3571 status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
3572 if (status) 3572 if (status)
3573 return status; 3573 return status;
3574 return nfs4_check_fh(current_fh, stp); 3574 return nfs4_check_fh(current_fh, stp);
3575 } 3575 }
3576 3576
3577 /* 3577 /*
3578 * Checks for sequence id mutating operations. 3578 * Checks for sequence id mutating operations.
3579 */ 3579 */
3580 static __be32 3580 static __be32
3581 nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, 3581 nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3582 stateid_t *stateid, char typemask, 3582 stateid_t *stateid, char typemask,
3583 struct nfs4_ol_stateid **stpp) 3583 struct nfs4_ol_stateid **stpp)
3584 { 3584 {
3585 __be32 status; 3585 __be32 status;
3586 struct nfs4_stid *s; 3586 struct nfs4_stid *s;
3587 3587
3588 dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, 3588 dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
3589 seqid, STATEID_VAL(stateid)); 3589 seqid, STATEID_VAL(stateid));
3590 3590
3591 *stpp = NULL; 3591 *stpp = NULL;
3592 status = nfsd4_lookup_stateid(stateid, typemask, &s); 3592 status = nfsd4_lookup_stateid(stateid, typemask, &s);
3593 if (status) 3593 if (status)
3594 return status; 3594 return status;
3595 *stpp = openlockstateid(s); 3595 *stpp = openlockstateid(s);
3596 cstate->replay_owner = (*stpp)->st_stateowner; 3596 cstate->replay_owner = (*stpp)->st_stateowner;
3597 3597
3598 return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp); 3598 return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp);
3599 } 3599 }
3600 3600
3601 static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, stateid_t *stateid, struct nfs4_ol_stateid **stpp) 3601 static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, stateid_t *stateid, struct nfs4_ol_stateid **stpp)
3602 { 3602 {
3603 __be32 status; 3603 __be32 status;
3604 struct nfs4_openowner *oo; 3604 struct nfs4_openowner *oo;
3605 3605
3606 status = nfs4_preprocess_seqid_op(cstate, seqid, stateid, 3606 status = nfs4_preprocess_seqid_op(cstate, seqid, stateid,
3607 NFS4_OPEN_STID, stpp); 3607 NFS4_OPEN_STID, stpp);
3608 if (status) 3608 if (status)
3609 return status; 3609 return status;
3610 oo = openowner((*stpp)->st_stateowner); 3610 oo = openowner((*stpp)->st_stateowner);
3611 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) 3611 if (!(oo->oo_flags & NFS4_OO_CONFIRMED))
3612 return nfserr_bad_stateid; 3612 return nfserr_bad_stateid;
3613 return nfs_ok; 3613 return nfs_ok;
3614 } 3614 }
3615 3615
3616 __be32 3616 __be32
3617 nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3617 nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3618 struct nfsd4_open_confirm *oc) 3618 struct nfsd4_open_confirm *oc)
3619 { 3619 {
3620 __be32 status; 3620 __be32 status;
3621 struct nfs4_openowner *oo; 3621 struct nfs4_openowner *oo;
3622 struct nfs4_ol_stateid *stp; 3622 struct nfs4_ol_stateid *stp;
3623 3623
3624 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", 3624 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
3625 (int)cstate->current_fh.fh_dentry->d_name.len, 3625 (int)cstate->current_fh.fh_dentry->d_name.len,
3626 cstate->current_fh.fh_dentry->d_name.name); 3626 cstate->current_fh.fh_dentry->d_name.name);
3627 3627
3628 status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0); 3628 status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
3629 if (status) 3629 if (status)
3630 return status; 3630 return status;
3631 3631
3632 nfs4_lock_state(); 3632 nfs4_lock_state();
3633 3633
3634 status = nfs4_preprocess_seqid_op(cstate, 3634 status = nfs4_preprocess_seqid_op(cstate,
3635 oc->oc_seqid, &oc->oc_req_stateid, 3635 oc->oc_seqid, &oc->oc_req_stateid,
3636 NFS4_OPEN_STID, &stp); 3636 NFS4_OPEN_STID, &stp);
3637 if (status) 3637 if (status)
3638 goto out; 3638 goto out;
3639 oo = openowner(stp->st_stateowner); 3639 oo = openowner(stp->st_stateowner);
3640 status = nfserr_bad_stateid; 3640 status = nfserr_bad_stateid;
3641 if (oo->oo_flags & NFS4_OO_CONFIRMED) 3641 if (oo->oo_flags & NFS4_OO_CONFIRMED)
3642 goto out; 3642 goto out;
3643 oo->oo_flags |= NFS4_OO_CONFIRMED; 3643 oo->oo_flags |= NFS4_OO_CONFIRMED;
3644 update_stateid(&stp->st_stid.sc_stateid); 3644 update_stateid(&stp->st_stid.sc_stateid);
3645 memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3645 memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3646 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", 3646 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
3647 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid)); 3647 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
3648 3648
3649 nfsd4_client_record_create(oo->oo_owner.so_client); 3649 nfsd4_client_record_create(oo->oo_owner.so_client);
3650 status = nfs_ok; 3650 status = nfs_ok;
3651 out: 3651 out:
3652 if (!cstate->replay_owner) 3652 if (!cstate->replay_owner)
3653 nfs4_unlock_state(); 3653 nfs4_unlock_state();
3654 return status; 3654 return status;
3655 } 3655 }
3656 3656
3657 static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access) 3657 static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
3658 { 3658 {
3659 if (!test_bit(access, &stp->st_access_bmap)) 3659 if (!test_bit(access, &stp->st_access_bmap))
3660 return; 3660 return;
3661 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access)); 3661 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access));
3662 __clear_bit(access, &stp->st_access_bmap); 3662 __clear_bit(access, &stp->st_access_bmap);
3663 } 3663 }
3664 3664
3665 static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access) 3665 static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access)
3666 { 3666 {
3667 switch (to_access) { 3667 switch (to_access) {
3668 case NFS4_SHARE_ACCESS_READ: 3668 case NFS4_SHARE_ACCESS_READ:
3669 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_WRITE); 3669 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_WRITE);
3670 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH); 3670 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH);
3671 break; 3671 break;
3672 case NFS4_SHARE_ACCESS_WRITE: 3672 case NFS4_SHARE_ACCESS_WRITE:
3673 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_READ); 3673 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_READ);
3674 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH); 3674 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH);
3675 break; 3675 break;
3676 case NFS4_SHARE_ACCESS_BOTH: 3676 case NFS4_SHARE_ACCESS_BOTH:
3677 break; 3677 break;
3678 default: 3678 default:
3679 BUG(); 3679 BUG();
3680 } 3680 }
3681 } 3681 }
3682 3682
3683 static void 3683 static void
3684 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap) 3684 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
3685 { 3685 {
3686 int i; 3686 int i;
3687 for (i = 0; i < 4; i++) { 3687 for (i = 0; i < 4; i++) {
3688 if ((i & deny) != i) 3688 if ((i & deny) != i)
3689 __clear_bit(i, bmap); 3689 __clear_bit(i, bmap);
3690 } 3690 }
3691 } 3691 }
3692 3692
3693 __be32 3693 __be32
3694 nfsd4_open_downgrade(struct svc_rqst *rqstp, 3694 nfsd4_open_downgrade(struct svc_rqst *rqstp,
3695 struct nfsd4_compound_state *cstate, 3695 struct nfsd4_compound_state *cstate,
3696 struct nfsd4_open_downgrade *od) 3696 struct nfsd4_open_downgrade *od)
3697 { 3697 {
3698 __be32 status; 3698 __be32 status;
3699 struct nfs4_ol_stateid *stp; 3699 struct nfs4_ol_stateid *stp;
3700 3700
3701 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 3701 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
3702 (int)cstate->current_fh.fh_dentry->d_name.len, 3702 (int)cstate->current_fh.fh_dentry->d_name.len,
3703 cstate->current_fh.fh_dentry->d_name.name); 3703 cstate->current_fh.fh_dentry->d_name.name);
3704 3704
3705 /* We don't yet support WANT bits: */ 3705 /* We don't yet support WANT bits: */
3706 if (od->od_deleg_want) 3706 if (od->od_deleg_want)
3707 dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__, 3707 dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
3708 od->od_deleg_want); 3708 od->od_deleg_want);
3709 3709
3710 nfs4_lock_state(); 3710 nfs4_lock_state();
3711 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid, 3711 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
3712 &od->od_stateid, &stp); 3712 &od->od_stateid, &stp);
3713 if (status) 3713 if (status)
3714 goto out; 3714 goto out;
3715 status = nfserr_inval; 3715 status = nfserr_inval;
3716 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3716 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
3717 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", 3717 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
3718 stp->st_access_bmap, od->od_share_access); 3718 stp->st_access_bmap, od->od_share_access);
3719 goto out; 3719 goto out;
3720 } 3720 }
3721 if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) { 3721 if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) {
3722 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n", 3722 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n",
3723 stp->st_deny_bmap, od->od_share_deny); 3723 stp->st_deny_bmap, od->od_share_deny);
3724 goto out; 3724 goto out;
3725 } 3725 }
3726 nfs4_stateid_downgrade(stp, od->od_share_access); 3726 nfs4_stateid_downgrade(stp, od->od_share_access);
3727 3727
3728 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3728 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
3729 3729
3730 update_stateid(&stp->st_stid.sc_stateid); 3730 update_stateid(&stp->st_stid.sc_stateid);
3731 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3731 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3732 status = nfs_ok; 3732 status = nfs_ok;
3733 out: 3733 out:
3734 if (!cstate->replay_owner) 3734 if (!cstate->replay_owner)
3735 nfs4_unlock_state(); 3735 nfs4_unlock_state();
3736 return status; 3736 return status;
3737 } 3737 }
3738 3738
3739 void nfsd4_purge_closed_stateid(struct nfs4_stateowner *so) 3739 void nfsd4_purge_closed_stateid(struct nfs4_stateowner *so)
3740 { 3740 {
3741 struct nfs4_openowner *oo; 3741 struct nfs4_openowner *oo;
3742 struct nfs4_ol_stateid *s; 3742 struct nfs4_ol_stateid *s;
3743 3743
3744 if (!so->so_is_open_owner) 3744 if (!so->so_is_open_owner)
3745 return; 3745 return;
3746 oo = openowner(so); 3746 oo = openowner(so);
3747 s = oo->oo_last_closed_stid; 3747 s = oo->oo_last_closed_stid;
3748 if (!s) 3748 if (!s)
3749 return; 3749 return;
3750 if (!(oo->oo_flags & NFS4_OO_PURGE_CLOSE)) { 3750 if (!(oo->oo_flags & NFS4_OO_PURGE_CLOSE)) {
3751 /* Release the last_closed_stid on the next seqid bump: */ 3751 /* Release the last_closed_stid on the next seqid bump: */
3752 oo->oo_flags |= NFS4_OO_PURGE_CLOSE; 3752 oo->oo_flags |= NFS4_OO_PURGE_CLOSE;
3753 return; 3753 return;
3754 } 3754 }
3755 oo->oo_flags &= ~NFS4_OO_PURGE_CLOSE; 3755 oo->oo_flags &= ~NFS4_OO_PURGE_CLOSE;
3756 release_last_closed_stateid(oo); 3756 release_last_closed_stateid(oo);
3757 } 3757 }
3758 3758
3759 static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) 3759 static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
3760 { 3760 {
3761 unhash_open_stateid(s); 3761 unhash_open_stateid(s);
3762 s->st_stid.sc_type = NFS4_CLOSED_STID; 3762 s->st_stid.sc_type = NFS4_CLOSED_STID;
3763 } 3763 }
3764 3764
3765 /* 3765 /*
3766 * nfs4_unlock_state() called after encode 3766 * nfs4_unlock_state() called after encode
3767 */ 3767 */
3768 __be32 3768 __be32
3769 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3769 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3770 struct nfsd4_close *close) 3770 struct nfsd4_close *close)
3771 { 3771 {
3772 __be32 status; 3772 __be32 status;
3773 struct nfs4_openowner *oo; 3773 struct nfs4_openowner *oo;
3774 struct nfs4_ol_stateid *stp; 3774 struct nfs4_ol_stateid *stp;
3775 3775
3776 dprintk("NFSD: nfsd4_close on file %.*s\n", 3776 dprintk("NFSD: nfsd4_close on file %.*s\n",
3777 (int)cstate->current_fh.fh_dentry->d_name.len, 3777 (int)cstate->current_fh.fh_dentry->d_name.len,
3778 cstate->current_fh.fh_dentry->d_name.name); 3778 cstate->current_fh.fh_dentry->d_name.name);
3779 3779
3780 nfs4_lock_state(); 3780 nfs4_lock_state();
3781 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid, 3781 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
3782 &close->cl_stateid, 3782 &close->cl_stateid,
3783 NFS4_OPEN_STID|NFS4_CLOSED_STID, 3783 NFS4_OPEN_STID|NFS4_CLOSED_STID,
3784 &stp); 3784 &stp);
3785 if (status) 3785 if (status)
3786 goto out; 3786 goto out;
3787 oo = openowner(stp->st_stateowner); 3787 oo = openowner(stp->st_stateowner);
3788 status = nfs_ok; 3788 status = nfs_ok;
3789 update_stateid(&stp->st_stid.sc_stateid); 3789 update_stateid(&stp->st_stid.sc_stateid);
3790 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3790 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3791 3791
3792 nfsd4_close_open_stateid(stp); 3792 nfsd4_close_open_stateid(stp);
3793 oo->oo_last_closed_stid = stp; 3793 oo->oo_last_closed_stid = stp;
3794 3794
3795 /* place unused nfs4_stateowners on so_close_lru list to be 3795 /* place unused nfs4_stateowners on so_close_lru list to be
3796 * released by the laundromat service after the lease period 3796 * released by the laundromat service after the lease period
3797 * to enable us to handle CLOSE replay 3797 * to enable us to handle CLOSE replay
3798 */ 3798 */
3799 if (list_empty(&oo->oo_owner.so_stateids)) 3799 if (list_empty(&oo->oo_owner.so_stateids))
3800 move_to_close_lru(oo); 3800 move_to_close_lru(oo);
3801 out: 3801 out:
3802 if (!cstate->replay_owner) 3802 if (!cstate->replay_owner)
3803 nfs4_unlock_state(); 3803 nfs4_unlock_state();
3804 return status; 3804 return status;
3805 } 3805 }
3806 3806
3807 __be32 3807 __be32
3808 nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3808 nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3809 struct nfsd4_delegreturn *dr) 3809 struct nfsd4_delegreturn *dr)
3810 { 3810 {
3811 struct nfs4_delegation *dp; 3811 struct nfs4_delegation *dp;
3812 stateid_t *stateid = &dr->dr_stateid; 3812 stateid_t *stateid = &dr->dr_stateid;
3813 struct nfs4_stid *s; 3813 struct nfs4_stid *s;
3814 struct inode *inode; 3814 struct inode *inode;
3815 __be32 status; 3815 __be32 status;
3816 3816
3817 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) 3817 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
3818 return status; 3818 return status;
3819 inode = cstate->current_fh.fh_dentry->d_inode; 3819 inode = cstate->current_fh.fh_dentry->d_inode;
3820 3820
3821 nfs4_lock_state(); 3821 nfs4_lock_state();
3822 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s); 3822 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s);
3823 if (status) 3823 if (status)
3824 goto out; 3824 goto out;
3825 dp = delegstateid(s); 3825 dp = delegstateid(s);
3826 status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate)); 3826 status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
3827 if (status) 3827 if (status)
3828 goto out; 3828 goto out;
3829 3829
3830 unhash_delegation(dp); 3830 unhash_delegation(dp);
3831 out: 3831 out:
3832 nfs4_unlock_state(); 3832 nfs4_unlock_state();
3833 3833
3834 return status; 3834 return status;
3835 } 3835 }
3836 3836
3837 3837
3838 #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start)) 3838 #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start))
3839 3839
3840 #define LOCKOWNER_INO_HASH_BITS 8 3840 #define LOCKOWNER_INO_HASH_BITS 8
3841 #define LOCKOWNER_INO_HASH_SIZE (1 << LOCKOWNER_INO_HASH_BITS) 3841 #define LOCKOWNER_INO_HASH_SIZE (1 << LOCKOWNER_INO_HASH_BITS)
3842 #define LOCKOWNER_INO_HASH_MASK (LOCKOWNER_INO_HASH_SIZE - 1) 3842 #define LOCKOWNER_INO_HASH_MASK (LOCKOWNER_INO_HASH_SIZE - 1)
3843 3843
3844 static inline u64 3844 static inline u64
3845 end_offset(u64 start, u64 len) 3845 end_offset(u64 start, u64 len)
3846 { 3846 {
3847 u64 end; 3847 u64 end;
3848 3848
3849 end = start + len; 3849 end = start + len;
3850 return end >= start ? end: NFS4_MAX_UINT64; 3850 return end >= start ? end: NFS4_MAX_UINT64;
3851 } 3851 }
3852 3852
3853 /* last octet in a range */ 3853 /* last octet in a range */
3854 static inline u64 3854 static inline u64
3855 last_byte_offset(u64 start, u64 len) 3855 last_byte_offset(u64 start, u64 len)
3856 { 3856 {
3857 u64 end; 3857 u64 end;
3858 3858
3859 BUG_ON(!len); 3859 BUG_ON(!len);
3860 end = start + len; 3860 end = start + len;
3861 return end > start ? end - 1: NFS4_MAX_UINT64; 3861 return end > start ? end - 1: NFS4_MAX_UINT64;
3862 } 3862 }
3863 3863
3864 static unsigned int lockowner_ino_hashval(struct inode *inode, u32 cl_id, struct xdr_netobj *ownername) 3864 static unsigned int lockowner_ino_hashval(struct inode *inode, u32 cl_id, struct xdr_netobj *ownername)
3865 { 3865 {
3866 return (file_hashval(inode) + cl_id 3866 return (file_hashval(inode) + cl_id
3867 + opaque_hashval(ownername->data, ownername->len)) 3867 + opaque_hashval(ownername->data, ownername->len))
3868 & LOCKOWNER_INO_HASH_MASK; 3868 & LOCKOWNER_INO_HASH_MASK;
3869 } 3869 }
3870 3870
3871 static struct list_head lockowner_ino_hashtbl[LOCKOWNER_INO_HASH_SIZE]; 3871 static struct list_head lockowner_ino_hashtbl[LOCKOWNER_INO_HASH_SIZE];
3872 3872
3873 /* 3873 /*
3874 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that 3874 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
3875 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th 3875 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
3876 * byte, because of sign extension problems. Since NFSv4 calls for 64-bit 3876 * byte, because of sign extension problems. Since NFSv4 calls for 64-bit
3877 * locking, this prevents us from being completely protocol-compliant. The 3877 * locking, this prevents us from being completely protocol-compliant. The
3878 * real solution to this problem is to start using unsigned file offsets in 3878 * real solution to this problem is to start using unsigned file offsets in
3879 * the VFS, but this is a very deep change! 3879 * the VFS, but this is a very deep change!
3880 */ 3880 */
3881 static inline void 3881 static inline void
3882 nfs4_transform_lock_offset(struct file_lock *lock) 3882 nfs4_transform_lock_offset(struct file_lock *lock)
3883 { 3883 {
3884 if (lock->fl_start < 0) 3884 if (lock->fl_start < 0)
3885 lock->fl_start = OFFSET_MAX; 3885 lock->fl_start = OFFSET_MAX;
3886 if (lock->fl_end < 0) 3886 if (lock->fl_end < 0)
3887 lock->fl_end = OFFSET_MAX; 3887 lock->fl_end = OFFSET_MAX;
3888 } 3888 }
3889 3889
3890 /* Hack!: For now, we're defining this just so we can use a pointer to it 3890 /* Hack!: For now, we're defining this just so we can use a pointer to it
3891 * as a unique cookie to identify our (NFSv4's) posix locks. */ 3891 * as a unique cookie to identify our (NFSv4's) posix locks. */
3892 static const struct lock_manager_operations nfsd_posix_mng_ops = { 3892 static const struct lock_manager_operations nfsd_posix_mng_ops = {
3893 }; 3893 };
3894 3894
3895 static inline void 3895 static inline void
3896 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) 3896 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
3897 { 3897 {
3898 struct nfs4_lockowner *lo; 3898 struct nfs4_lockowner *lo;
3899 3899
3900 if (fl->fl_lmops == &nfsd_posix_mng_ops) { 3900 if (fl->fl_lmops == &nfsd_posix_mng_ops) {
3901 lo = (struct nfs4_lockowner *) fl->fl_owner; 3901 lo = (struct nfs4_lockowner *) fl->fl_owner;
3902 deny->ld_owner.data = kmemdup(lo->lo_owner.so_owner.data, 3902 deny->ld_owner.data = kmemdup(lo->lo_owner.so_owner.data,
3903 lo->lo_owner.so_owner.len, GFP_KERNEL); 3903 lo->lo_owner.so_owner.len, GFP_KERNEL);
3904 if (!deny->ld_owner.data) 3904 if (!deny->ld_owner.data)
3905 /* We just don't care that much */ 3905 /* We just don't care that much */
3906 goto nevermind; 3906 goto nevermind;
3907 deny->ld_owner.len = lo->lo_owner.so_owner.len; 3907 deny->ld_owner.len = lo->lo_owner.so_owner.len;
3908 deny->ld_clientid = lo->lo_owner.so_client->cl_clientid; 3908 deny->ld_clientid = lo->lo_owner.so_client->cl_clientid;
3909 } else { 3909 } else {
3910 nevermind: 3910 nevermind:
3911 deny->ld_owner.len = 0; 3911 deny->ld_owner.len = 0;
3912 deny->ld_owner.data = NULL; 3912 deny->ld_owner.data = NULL;
3913 deny->ld_clientid.cl_boot = 0; 3913 deny->ld_clientid.cl_boot = 0;
3914 deny->ld_clientid.cl_id = 0; 3914 deny->ld_clientid.cl_id = 0;
3915 } 3915 }
3916 deny->ld_start = fl->fl_start; 3916 deny->ld_start = fl->fl_start;
3917 deny->ld_length = NFS4_MAX_UINT64; 3917 deny->ld_length = NFS4_MAX_UINT64;
3918 if (fl->fl_end != NFS4_MAX_UINT64) 3918 if (fl->fl_end != NFS4_MAX_UINT64)
3919 deny->ld_length = fl->fl_end - fl->fl_start + 1; 3919 deny->ld_length = fl->fl_end - fl->fl_start + 1;
3920 deny->ld_type = NFS4_READ_LT; 3920 deny->ld_type = NFS4_READ_LT;
3921 if (fl->fl_type != F_RDLCK) 3921 if (fl->fl_type != F_RDLCK)
3922 deny->ld_type = NFS4_WRITE_LT; 3922 deny->ld_type = NFS4_WRITE_LT;
3923 } 3923 }
3924 3924
3925 static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) 3925 static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner)
3926 { 3926 {
3927 struct nfs4_ol_stateid *lst; 3927 struct nfs4_ol_stateid *lst;
3928 3928
3929 if (!same_owner_str(&lo->lo_owner, owner, clid)) 3929 if (!same_owner_str(&lo->lo_owner, owner, clid))
3930 return false; 3930 return false;
3931 lst = list_first_entry(&lo->lo_owner.so_stateids, 3931 lst = list_first_entry(&lo->lo_owner.so_stateids,
3932 struct nfs4_ol_stateid, st_perstateowner); 3932 struct nfs4_ol_stateid, st_perstateowner);
3933 return lst->st_file->fi_inode == inode; 3933 return lst->st_file->fi_inode == inode;
3934 } 3934 }
3935 3935
3936 static struct nfs4_lockowner * 3936 static struct nfs4_lockowner *
3937 find_lockowner_str(struct inode *inode, clientid_t *clid, 3937 find_lockowner_str(struct inode *inode, clientid_t *clid,
3938 struct xdr_netobj *owner) 3938 struct xdr_netobj *owner)
3939 { 3939 {
3940 unsigned int hashval = lockowner_ino_hashval(inode, clid->cl_id, owner); 3940 unsigned int hashval = lockowner_ino_hashval(inode, clid->cl_id, owner);
3941 struct nfs4_lockowner *lo; 3941 struct nfs4_lockowner *lo;
3942 3942
3943 list_for_each_entry(lo, &lockowner_ino_hashtbl[hashval], lo_owner_ino_hash) { 3943 list_for_each_entry(lo, &lockowner_ino_hashtbl[hashval], lo_owner_ino_hash) {
3944 if (same_lockowner_ino(lo, inode, clid, owner)) 3944 if (same_lockowner_ino(lo, inode, clid, owner))
3945 return lo; 3945 return lo;
3946 } 3946 }
3947 return NULL; 3947 return NULL;
3948 } 3948 }
3949 3949
3950 static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp) 3950 static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp)
3951 { 3951 {
3952 struct inode *inode = open_stp->st_file->fi_inode; 3952 struct inode *inode = open_stp->st_file->fi_inode;
3953 unsigned int inohash = lockowner_ino_hashval(inode, 3953 unsigned int inohash = lockowner_ino_hashval(inode,
3954 clp->cl_clientid.cl_id, &lo->lo_owner.so_owner); 3954 clp->cl_clientid.cl_id, &lo->lo_owner.so_owner);
3955 3955
3956 list_add(&lo->lo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); 3956 list_add(&lo->lo_owner.so_strhash, &ownerstr_hashtbl[strhashval]);
3957 list_add(&lo->lo_owner_ino_hash, &lockowner_ino_hashtbl[inohash]); 3957 list_add(&lo->lo_owner_ino_hash, &lockowner_ino_hashtbl[inohash]);
3958 list_add(&lo->lo_perstateid, &open_stp->st_lockowners); 3958 list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
3959 } 3959 }
3960 3960
3961 /* 3961 /*
3962 * Alloc a lock owner structure. 3962 * Alloc a lock owner structure.
3963 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 3963 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
3964 * occurred. 3964 * occurred.
3965 * 3965 *
3966 * strhashval = ownerstr_hashval 3966 * strhashval = ownerstr_hashval
3967 */ 3967 */
3968 3968
3969 static struct nfs4_lockowner * 3969 static struct nfs4_lockowner *
3970 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp, struct nfsd4_lock *lock) { 3970 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp, struct nfsd4_lock *lock) {
3971 struct nfs4_lockowner *lo; 3971 struct nfs4_lockowner *lo;
3972 3972
3973 lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp); 3973 lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp);
3974 if (!lo) 3974 if (!lo)
3975 return NULL; 3975 return NULL;
3976 INIT_LIST_HEAD(&lo->lo_owner.so_stateids); 3976 INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
3977 lo->lo_owner.so_is_open_owner = 0; 3977 lo->lo_owner.so_is_open_owner = 0;
3978 /* It is the openowner seqid that will be incremented in encode in the 3978 /* It is the openowner seqid that will be incremented in encode in the
3979 * case of new lockowners; so increment the lock seqid manually: */ 3979 * case of new lockowners; so increment the lock seqid manually: */
3980 lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1; 3980 lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1;
3981 hash_lockowner(lo, strhashval, clp, open_stp); 3981 hash_lockowner(lo, strhashval, clp, open_stp);
3982 return lo; 3982 return lo;
3983 } 3983 }
3984 3984
3985 static struct nfs4_ol_stateid * 3985 static struct nfs4_ol_stateid *
3986 alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_ol_stateid *open_stp) 3986 alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_ol_stateid *open_stp)
3987 { 3987 {
3988 struct nfs4_ol_stateid *stp; 3988 struct nfs4_ol_stateid *stp;
3989 struct nfs4_client *clp = lo->lo_owner.so_client; 3989 struct nfs4_client *clp = lo->lo_owner.so_client;
3990 3990
3991 stp = nfs4_alloc_stateid(clp); 3991 stp = nfs4_alloc_stateid(clp);
3992 if (stp == NULL) 3992 if (stp == NULL)
3993 return NULL; 3993 return NULL;
3994 init_stid(&stp->st_stid, clp, NFS4_LOCK_STID); 3994 init_stid(&stp->st_stid, clp, NFS4_LOCK_STID);
3995 list_add(&stp->st_perfile, &fp->fi_stateids); 3995 list_add(&stp->st_perfile, &fp->fi_stateids);
3996 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); 3996 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
3997 stp->st_stateowner = &lo->lo_owner; 3997 stp->st_stateowner = &lo->lo_owner;
3998 get_nfs4_file(fp); 3998 get_nfs4_file(fp);
3999 stp->st_file = fp; 3999 stp->st_file = fp;
4000 stp->st_access_bmap = 0; 4000 stp->st_access_bmap = 0;
4001 stp->st_deny_bmap = open_stp->st_deny_bmap; 4001 stp->st_deny_bmap = open_stp->st_deny_bmap;
4002 stp->st_openstp = open_stp; 4002 stp->st_openstp = open_stp;
4003 return stp; 4003 return stp;
4004 } 4004 }
4005 4005
4006 static int 4006 static int
4007 check_lock_length(u64 offset, u64 length) 4007 check_lock_length(u64 offset, u64 length)
4008 { 4008 {
4009 return ((length == 0) || ((length != NFS4_MAX_UINT64) && 4009 return ((length == 0) || ((length != NFS4_MAX_UINT64) &&
4010 LOFF_OVERFLOW(offset, length))); 4010 LOFF_OVERFLOW(offset, length)));
4011 } 4011 }
4012 4012
4013 static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access) 4013 static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
4014 { 4014 {
4015 struct nfs4_file *fp = lock_stp->st_file; 4015 struct nfs4_file *fp = lock_stp->st_file;
4016 int oflag = nfs4_access_to_omode(access); 4016 int oflag = nfs4_access_to_omode(access);
4017 4017
4018 if (test_bit(access, &lock_stp->st_access_bmap)) 4018 if (test_bit(access, &lock_stp->st_access_bmap))
4019 return; 4019 return;
4020 nfs4_file_get_access(fp, oflag); 4020 nfs4_file_get_access(fp, oflag);
4021 __set_bit(access, &lock_stp->st_access_bmap); 4021 __set_bit(access, &lock_stp->st_access_bmap);
4022 } 4022 }
4023 4023
4024 static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new) 4024 static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new)
4025 { 4025 {
4026 struct nfs4_file *fi = ost->st_file; 4026 struct nfs4_file *fi = ost->st_file;
4027 struct nfs4_openowner *oo = openowner(ost->st_stateowner); 4027 struct nfs4_openowner *oo = openowner(ost->st_stateowner);
4028 struct nfs4_client *cl = oo->oo_owner.so_client; 4028 struct nfs4_client *cl = oo->oo_owner.so_client;
4029 struct nfs4_lockowner *lo; 4029 struct nfs4_lockowner *lo;
4030 unsigned int strhashval; 4030 unsigned int strhashval;
4031 4031
4032 lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid, &lock->v.new.owner); 4032 lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid, &lock->v.new.owner);
4033 if (lo) { 4033 if (lo) {
4034 if (!cstate->minorversion) 4034 if (!cstate->minorversion)
4035 return nfserr_bad_seqid; 4035 return nfserr_bad_seqid;
4036 /* XXX: a lockowner always has exactly one stateid: */ 4036 /* XXX: a lockowner always has exactly one stateid: */
4037 *lst = list_first_entry(&lo->lo_owner.so_stateids, 4037 *lst = list_first_entry(&lo->lo_owner.so_stateids,
4038 struct nfs4_ol_stateid, st_perstateowner); 4038 struct nfs4_ol_stateid, st_perstateowner);
4039 return nfs_ok; 4039 return nfs_ok;
4040 } 4040 }
4041 strhashval = ownerstr_hashval(cl->cl_clientid.cl_id, 4041 strhashval = ownerstr_hashval(cl->cl_clientid.cl_id,
4042 &lock->v.new.owner); 4042 &lock->v.new.owner);
4043 lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); 4043 lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock);
4044 if (lo == NULL) 4044 if (lo == NULL)
4045 return nfserr_jukebox; 4045 return nfserr_jukebox;
4046 *lst = alloc_init_lock_stateid(lo, fi, ost); 4046 *lst = alloc_init_lock_stateid(lo, fi, ost);
4047 if (*lst == NULL) { 4047 if (*lst == NULL) {
4048 release_lockowner(lo); 4048 release_lockowner(lo);
4049 return nfserr_jukebox; 4049 return nfserr_jukebox;
4050 } 4050 }
4051 *new = true; 4051 *new = true;
4052 return nfs_ok; 4052 return nfs_ok;
4053 } 4053 }
4054 4054
4055 /* 4055 /*
4056 * LOCK operation 4056 * LOCK operation
4057 */ 4057 */
4058 __be32 4058 __be32
4059 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4059 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4060 struct nfsd4_lock *lock) 4060 struct nfsd4_lock *lock)
4061 { 4061 {
4062 struct nfs4_openowner *open_sop = NULL; 4062 struct nfs4_openowner *open_sop = NULL;
4063 struct nfs4_lockowner *lock_sop = NULL; 4063 struct nfs4_lockowner *lock_sop = NULL;
4064 struct nfs4_ol_stateid *lock_stp; 4064 struct nfs4_ol_stateid *lock_stp;
4065 struct file *filp = NULL; 4065 struct file *filp = NULL;
4066 struct file_lock file_lock; 4066 struct file_lock file_lock;
4067 struct file_lock conflock; 4067 struct file_lock conflock;
4068 __be32 status = 0; 4068 __be32 status = 0;
4069 bool new_state = false; 4069 bool new_state = false;
4070 int lkflg; 4070 int lkflg;
4071 int err; 4071 int err;
4072 4072
4073 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", 4073 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
4074 (long long) lock->lk_offset, 4074 (long long) lock->lk_offset,
4075 (long long) lock->lk_length); 4075 (long long) lock->lk_length);
4076 4076
4077 if (check_lock_length(lock->lk_offset, lock->lk_length)) 4077 if (check_lock_length(lock->lk_offset, lock->lk_length))
4078 return nfserr_inval; 4078 return nfserr_inval;
4079 4079
4080 if ((status = fh_verify(rqstp, &cstate->current_fh, 4080 if ((status = fh_verify(rqstp, &cstate->current_fh,
4081 S_IFREG, NFSD_MAY_LOCK))) { 4081 S_IFREG, NFSD_MAY_LOCK))) {
4082 dprintk("NFSD: nfsd4_lock: permission denied!\n"); 4082 dprintk("NFSD: nfsd4_lock: permission denied!\n");
4083 return status; 4083 return status;
4084 } 4084 }
4085 4085
4086 nfs4_lock_state(); 4086 nfs4_lock_state();
4087 4087
4088 if (lock->lk_is_new) { 4088 if (lock->lk_is_new) {
4089 /* 4089 /*
4090 * Client indicates that this is a new lockowner. 4090 * Client indicates that this is a new lockowner.
4091 * Use open owner and open stateid to create lock owner and 4091 * Use open owner and open stateid to create lock owner and
4092 * lock stateid. 4092 * lock stateid.
4093 */ 4093 */
4094 struct nfs4_ol_stateid *open_stp = NULL; 4094 struct nfs4_ol_stateid *open_stp = NULL;
4095 4095
4096 if (nfsd4_has_session(cstate)) 4096 if (nfsd4_has_session(cstate))
4097 /* See rfc 5661 18.10.3: given clientid is ignored: */ 4097 /* See rfc 5661 18.10.3: given clientid is ignored: */
4098 memcpy(&lock->v.new.clientid, 4098 memcpy(&lock->v.new.clientid,
4099 &cstate->session->se_client->cl_clientid, 4099 &cstate->session->se_client->cl_clientid,
4100 sizeof(clientid_t)); 4100 sizeof(clientid_t));
4101 4101
4102 status = nfserr_stale_clientid; 4102 status = nfserr_stale_clientid;
4103 if (STALE_CLIENTID(&lock->lk_new_clientid)) 4103 if (STALE_CLIENTID(&lock->lk_new_clientid))
4104 goto out; 4104 goto out;
4105 4105
4106 /* validate and update open stateid and open seqid */ 4106 /* validate and update open stateid and open seqid */
4107 status = nfs4_preprocess_confirmed_seqid_op(cstate, 4107 status = nfs4_preprocess_confirmed_seqid_op(cstate,
4108 lock->lk_new_open_seqid, 4108 lock->lk_new_open_seqid,
4109 &lock->lk_new_open_stateid, 4109 &lock->lk_new_open_stateid,
4110 &open_stp); 4110 &open_stp);
4111 if (status) 4111 if (status)
4112 goto out; 4112 goto out;
4113 open_sop = openowner(open_stp->st_stateowner); 4113 open_sop = openowner(open_stp->st_stateowner);
4114 status = nfserr_bad_stateid; 4114 status = nfserr_bad_stateid;
4115 if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, 4115 if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
4116 &lock->v.new.clientid)) 4116 &lock->v.new.clientid))
4117 goto out; 4117 goto out;
4118 status = lookup_or_create_lock_state(cstate, open_stp, lock, 4118 status = lookup_or_create_lock_state(cstate, open_stp, lock,
4119 &lock_stp, &new_state); 4119 &lock_stp, &new_state);
4120 if (status) 4120 if (status)
4121 goto out; 4121 goto out;
4122 } else { 4122 } else {
4123 /* lock (lock owner + lock stateid) already exists */ 4123 /* lock (lock owner + lock stateid) already exists */
4124 status = nfs4_preprocess_seqid_op(cstate, 4124 status = nfs4_preprocess_seqid_op(cstate,
4125 lock->lk_old_lock_seqid, 4125 lock->lk_old_lock_seqid,
4126 &lock->lk_old_lock_stateid, 4126 &lock->lk_old_lock_stateid,
4127 NFS4_LOCK_STID, &lock_stp); 4127 NFS4_LOCK_STID, &lock_stp);
4128 if (status) 4128 if (status)
4129 goto out; 4129 goto out;
4130 } 4130 }
4131 lock_sop = lockowner(lock_stp->st_stateowner); 4131 lock_sop = lockowner(lock_stp->st_stateowner);
4132 4132
4133 lkflg = setlkflg(lock->lk_type); 4133 lkflg = setlkflg(lock->lk_type);
4134 status = nfs4_check_openmode(lock_stp, lkflg); 4134 status = nfs4_check_openmode(lock_stp, lkflg);
4135 if (status) 4135 if (status)
4136 goto out; 4136 goto out;
4137 4137
4138 status = nfserr_grace; 4138 status = nfserr_grace;
4139 if (locks_in_grace() && !lock->lk_reclaim) 4139 if (locks_in_grace() && !lock->lk_reclaim)
4140 goto out; 4140 goto out;
4141 status = nfserr_no_grace; 4141 status = nfserr_no_grace;
4142 if (!locks_in_grace() && lock->lk_reclaim) 4142 if (!locks_in_grace() && lock->lk_reclaim)
4143 goto out; 4143 goto out;
4144 4144
4145 locks_init_lock(&file_lock); 4145 locks_init_lock(&file_lock);
4146 switch (lock->lk_type) { 4146 switch (lock->lk_type) {
4147 case NFS4_READ_LT: 4147 case NFS4_READ_LT:
4148 case NFS4_READW_LT: 4148 case NFS4_READW_LT:
4149 filp = find_readable_file(lock_stp->st_file); 4149 filp = find_readable_file(lock_stp->st_file);
4150 if (filp) 4150 if (filp)
4151 get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ); 4151 get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
4152 file_lock.fl_type = F_RDLCK; 4152 file_lock.fl_type = F_RDLCK;
4153 break; 4153 break;
4154 case NFS4_WRITE_LT: 4154 case NFS4_WRITE_LT:
4155 case NFS4_WRITEW_LT: 4155 case NFS4_WRITEW_LT:
4156 filp = find_writeable_file(lock_stp->st_file); 4156 filp = find_writeable_file(lock_stp->st_file);
4157 if (filp) 4157 if (filp)
4158 get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE); 4158 get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
4159 file_lock.fl_type = F_WRLCK; 4159 file_lock.fl_type = F_WRLCK;
4160 break; 4160 break;
4161 default: 4161 default:
4162 status = nfserr_inval; 4162 status = nfserr_inval;
4163 goto out; 4163 goto out;
4164 } 4164 }
4165 if (!filp) { 4165 if (!filp) {
4166 status = nfserr_openmode; 4166 status = nfserr_openmode;
4167 goto out; 4167 goto out;
4168 } 4168 }
4169 file_lock.fl_owner = (fl_owner_t)lock_sop; 4169 file_lock.fl_owner = (fl_owner_t)lock_sop;
4170 file_lock.fl_pid = current->tgid; 4170 file_lock.fl_pid = current->tgid;
4171 file_lock.fl_file = filp; 4171 file_lock.fl_file = filp;
4172 file_lock.fl_flags = FL_POSIX; 4172 file_lock.fl_flags = FL_POSIX;
4173 file_lock.fl_lmops = &nfsd_posix_mng_ops; 4173 file_lock.fl_lmops = &nfsd_posix_mng_ops;
4174 4174
4175 file_lock.fl_start = lock->lk_offset; 4175 file_lock.fl_start = lock->lk_offset;
4176 file_lock.fl_end = last_byte_offset(lock->lk_offset, lock->lk_length); 4176 file_lock.fl_end = last_byte_offset(lock->lk_offset, lock->lk_length);
4177 nfs4_transform_lock_offset(&file_lock); 4177 nfs4_transform_lock_offset(&file_lock);
4178 4178
4179 /* 4179 /*
4180 * Try to lock the file in the VFS. 4180 * Try to lock the file in the VFS.
4181 * Note: locks.c uses the BKL to protect the inode's lock list. 4181 * Note: locks.c uses the BKL to protect the inode's lock list.
4182 */ 4182 */
4183 4183
4184 err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock); 4184 err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock);
4185 switch (-err) { 4185 switch (-err) {
4186 case 0: /* success! */ 4186 case 0: /* success! */
4187 update_stateid(&lock_stp->st_stid.sc_stateid); 4187 update_stateid(&lock_stp->st_stid.sc_stateid);
4188 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 4188 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid,
4189 sizeof(stateid_t)); 4189 sizeof(stateid_t));
4190 status = 0; 4190 status = 0;
4191 break; 4191 break;
4192 case (EAGAIN): /* conflock holds conflicting lock */ 4192 case (EAGAIN): /* conflock holds conflicting lock */
4193 status = nfserr_denied; 4193 status = nfserr_denied;
4194 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n"); 4194 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
4195 nfs4_set_lock_denied(&conflock, &lock->lk_denied); 4195 nfs4_set_lock_denied(&conflock, &lock->lk_denied);
4196 break; 4196 break;
4197 case (EDEADLK): 4197 case (EDEADLK):
4198 status = nfserr_deadlock; 4198 status = nfserr_deadlock;
4199 break; 4199 break;
4200 default: 4200 default:
4201 dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err); 4201 dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
4202 status = nfserrno(err); 4202 status = nfserrno(err);
4203 break; 4203 break;
4204 } 4204 }
4205 out: 4205 out:
4206 if (status && new_state) 4206 if (status && new_state)
4207 release_lockowner(lock_sop); 4207 release_lockowner(lock_sop);
4208 if (!cstate->replay_owner) 4208 if (!cstate->replay_owner)
4209 nfs4_unlock_state(); 4209 nfs4_unlock_state();
4210 return status; 4210 return status;
4211 } 4211 }
4212 4212
4213 /* 4213 /*
4214 * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN, 4214 * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN,
4215 * so we do a temporary open here just to get an open file to pass to 4215 * so we do a temporary open here just to get an open file to pass to
4216 * vfs_test_lock. (Arguably perhaps test_lock should be done with an 4216 * vfs_test_lock. (Arguably perhaps test_lock should be done with an
4217 * inode operation.) 4217 * inode operation.)
4218 */ 4218 */
4219 static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) 4219 static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
4220 { 4220 {
4221 struct file *file; 4221 struct file *file;
4222 int err; 4222 int err;
4223 4223
4224 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); 4224 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
4225 if (err) 4225 if (err)
4226 return err; 4226 return err;
4227 err = vfs_test_lock(file, lock); 4227 err = vfs_test_lock(file, lock);
4228 nfsd_close(file); 4228 nfsd_close(file);
4229 return err; 4229 return err;
4230 } 4230 }
4231 4231
4232 /* 4232 /*
4233 * LOCKT operation 4233 * LOCKT operation
4234 */ 4234 */
4235 __be32 4235 __be32
4236 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4236 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4237 struct nfsd4_lockt *lockt) 4237 struct nfsd4_lockt *lockt)
4238 { 4238 {
4239 struct inode *inode; 4239 struct inode *inode;
4240 struct file_lock file_lock; 4240 struct file_lock file_lock;
4241 struct nfs4_lockowner *lo; 4241 struct nfs4_lockowner *lo;
4242 int error; 4242 int error;
4243 __be32 status; 4243 __be32 status;
4244 4244
4245 if (locks_in_grace()) 4245 if (locks_in_grace())
4246 return nfserr_grace; 4246 return nfserr_grace;
4247 4247
4248 if (check_lock_length(lockt->lt_offset, lockt->lt_length)) 4248 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
4249 return nfserr_inval; 4249 return nfserr_inval;
4250 4250
4251 nfs4_lock_state(); 4251 nfs4_lock_state();
4252 4252
4253 status = nfserr_stale_clientid; 4253 status = nfserr_stale_clientid;
4254 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid)) 4254 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid))
4255 goto out; 4255 goto out;
4256 4256
4257 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) 4257 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
4258 goto out; 4258 goto out;
4259 4259
4260 inode = cstate->current_fh.fh_dentry->d_inode; 4260 inode = cstate->current_fh.fh_dentry->d_inode;
4261 locks_init_lock(&file_lock); 4261 locks_init_lock(&file_lock);
4262 switch (lockt->lt_type) { 4262 switch (lockt->lt_type) {
4263 case NFS4_READ_LT: 4263 case NFS4_READ_LT:
4264 case NFS4_READW_LT: 4264 case NFS4_READW_LT:
4265 file_lock.fl_type = F_RDLCK; 4265 file_lock.fl_type = F_RDLCK;
4266 break; 4266 break;
4267 case NFS4_WRITE_LT: 4267 case NFS4_WRITE_LT:
4268 case NFS4_WRITEW_LT: 4268 case NFS4_WRITEW_LT:
4269 file_lock.fl_type = F_WRLCK; 4269 file_lock.fl_type = F_WRLCK;
4270 break; 4270 break;
4271 default: 4271 default:
4272 dprintk("NFSD: nfs4_lockt: bad lock type!\n"); 4272 dprintk("NFSD: nfs4_lockt: bad lock type!\n");
4273 status = nfserr_inval; 4273 status = nfserr_inval;
4274 goto out; 4274 goto out;
4275 } 4275 }
4276 4276
4277 lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner); 4277 lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner);
4278 if (lo) 4278 if (lo)
4279 file_lock.fl_owner = (fl_owner_t)lo; 4279 file_lock.fl_owner = (fl_owner_t)lo;
4280 file_lock.fl_pid = current->tgid; 4280 file_lock.fl_pid = current->tgid;
4281 file_lock.fl_flags = FL_POSIX; 4281 file_lock.fl_flags = FL_POSIX;
4282 4282
4283 file_lock.fl_start = lockt->lt_offset; 4283 file_lock.fl_start = lockt->lt_offset;
4284 file_lock.fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length); 4284 file_lock.fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
4285 4285
4286 nfs4_transform_lock_offset(&file_lock); 4286 nfs4_transform_lock_offset(&file_lock);
4287 4287
4288 status = nfs_ok; 4288 status = nfs_ok;
4289 error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); 4289 error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
4290 if (error) { 4290 if (error) {
4291 status = nfserrno(error); 4291 status = nfserrno(error);
4292 goto out; 4292 goto out;
4293 } 4293 }
4294 if (file_lock.fl_type != F_UNLCK) { 4294 if (file_lock.fl_type != F_UNLCK) {
4295 status = nfserr_denied; 4295 status = nfserr_denied;
4296 nfs4_set_lock_denied(&file_lock, &lockt->lt_denied); 4296 nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
4297 } 4297 }
4298 out: 4298 out:
4299 nfs4_unlock_state(); 4299 nfs4_unlock_state();
4300 return status; 4300 return status;
4301 } 4301 }
4302 4302
4303 __be32 4303 __be32
4304 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4304 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4305 struct nfsd4_locku *locku) 4305 struct nfsd4_locku *locku)
4306 { 4306 {
4307 struct nfs4_ol_stateid *stp; 4307 struct nfs4_ol_stateid *stp;
4308 struct file *filp = NULL; 4308 struct file *filp = NULL;
4309 struct file_lock file_lock; 4309 struct file_lock file_lock;
4310 __be32 status; 4310 __be32 status;
4311 int err; 4311 int err;
4312 4312
4313 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n", 4313 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
4314 (long long) locku->lu_offset, 4314 (long long) locku->lu_offset,
4315 (long long) locku->lu_length); 4315 (long long) locku->lu_length);
4316 4316
4317 if (check_lock_length(locku->lu_offset, locku->lu_length)) 4317 if (check_lock_length(locku->lu_offset, locku->lu_length))
4318 return nfserr_inval; 4318 return nfserr_inval;
4319 4319
4320 nfs4_lock_state(); 4320 nfs4_lock_state();
4321 4321
4322 status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid, 4322 status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid,
4323 &locku->lu_stateid, NFS4_LOCK_STID, &stp); 4323 &locku->lu_stateid, NFS4_LOCK_STID, &stp);
4324 if (status) 4324 if (status)
4325 goto out; 4325 goto out;
4326 filp = find_any_file(stp->st_file); 4326 filp = find_any_file(stp->st_file);
4327 if (!filp) { 4327 if (!filp) {
4328 status = nfserr_lock_range; 4328 status = nfserr_lock_range;
4329 goto out; 4329 goto out;
4330 } 4330 }
4331 BUG_ON(!filp); 4331 BUG_ON(!filp);
4332 locks_init_lock(&file_lock); 4332 locks_init_lock(&file_lock);
4333 file_lock.fl_type = F_UNLCK; 4333 file_lock.fl_type = F_UNLCK;
4334 file_lock.fl_owner = (fl_owner_t)lockowner(stp->st_stateowner); 4334 file_lock.fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
4335 file_lock.fl_pid = current->tgid; 4335 file_lock.fl_pid = current->tgid;
4336 file_lock.fl_file = filp; 4336 file_lock.fl_file = filp;
4337 file_lock.fl_flags = FL_POSIX; 4337 file_lock.fl_flags = FL_POSIX;
4338 file_lock.fl_lmops = &nfsd_posix_mng_ops; 4338 file_lock.fl_lmops = &nfsd_posix_mng_ops;
4339 file_lock.fl_start = locku->lu_offset; 4339 file_lock.fl_start = locku->lu_offset;
4340 4340
4341 file_lock.fl_end = last_byte_offset(locku->lu_offset, locku->lu_length); 4341 file_lock.fl_end = last_byte_offset(locku->lu_offset, locku->lu_length);
4342 nfs4_transform_lock_offset(&file_lock); 4342 nfs4_transform_lock_offset(&file_lock);
4343 4343
4344 /* 4344 /*
4345 * Try to unlock the file in the VFS. 4345 * Try to unlock the file in the VFS.
4346 */ 4346 */
4347 err = vfs_lock_file(filp, F_SETLK, &file_lock, NULL); 4347 err = vfs_lock_file(filp, F_SETLK, &file_lock, NULL);
4348 if (err) { 4348 if (err) {
4349 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n"); 4349 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
4350 goto out_nfserr; 4350 goto out_nfserr;
4351 } 4351 }
4352 /* 4352 /*
4353 * OK, unlock succeeded; the only thing left to do is update the stateid. 4353 * OK, unlock succeeded; the only thing left to do is update the stateid.
4354 */ 4354 */
4355 update_stateid(&stp->st_stid.sc_stateid); 4355 update_stateid(&stp->st_stid.sc_stateid);
4356 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4356 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4357 4357
4358 out: 4358 out:
4359 if (!cstate->replay_owner) 4359 if (!cstate->replay_owner)
4360 nfs4_unlock_state(); 4360 nfs4_unlock_state();
4361 return status; 4361 return status;
4362 4362
4363 out_nfserr: 4363 out_nfserr:
4364 status = nfserrno(err); 4364 status = nfserrno(err);
4365 goto out; 4365 goto out;
4366 } 4366 }
4367 4367
4368 /* 4368 /*
4369 * returns 4369 * returns
4370 * 1: locks held by lockowner 4370 * 1: locks held by lockowner
4371 * 0: no locks held by lockowner 4371 * 0: no locks held by lockowner
4372 */ 4372 */
4373 static int 4373 static int
4374 check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) 4374 check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4375 { 4375 {
4376 struct file_lock **flpp; 4376 struct file_lock **flpp;
4377 struct inode *inode = filp->fi_inode; 4377 struct inode *inode = filp->fi_inode;
4378 int status = 0; 4378 int status = 0;
4379 4379
4380 lock_flocks(); 4380 lock_flocks();
4381 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { 4381 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
4382 if ((*flpp)->fl_owner == (fl_owner_t)lowner) { 4382 if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
4383 status = 1; 4383 status = 1;
4384 goto out; 4384 goto out;
4385 } 4385 }
4386 } 4386 }
4387 out: 4387 out:
4388 unlock_flocks(); 4388 unlock_flocks();
4389 return status; 4389 return status;
4390 } 4390 }
4391 4391
4392 __be32 4392 __be32
4393 nfsd4_release_lockowner(struct svc_rqst *rqstp, 4393 nfsd4_release_lockowner(struct svc_rqst *rqstp,
4394 struct nfsd4_compound_state *cstate, 4394 struct nfsd4_compound_state *cstate,
4395 struct nfsd4_release_lockowner *rlockowner) 4395 struct nfsd4_release_lockowner *rlockowner)
4396 { 4396 {
4397 clientid_t *clid = &rlockowner->rl_clientid; 4397 clientid_t *clid = &rlockowner->rl_clientid;
4398 struct nfs4_stateowner *sop; 4398 struct nfs4_stateowner *sop;
4399 struct nfs4_lockowner *lo; 4399 struct nfs4_lockowner *lo;
4400 struct nfs4_ol_stateid *stp; 4400 struct nfs4_ol_stateid *stp;
4401 struct xdr_netobj *owner = &rlockowner->rl_owner; 4401 struct xdr_netobj *owner = &rlockowner->rl_owner;
4402 struct list_head matches; 4402 struct list_head matches;
4403 unsigned int hashval = ownerstr_hashval(clid->cl_id, owner); 4403 unsigned int hashval = ownerstr_hashval(clid->cl_id, owner);
4404 __be32 status; 4404 __be32 status;
4405 4405
4406 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", 4406 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
4407 clid->cl_boot, clid->cl_id); 4407 clid->cl_boot, clid->cl_id);
4408 4408
4409 /* XXX check for lease expiration */ 4409 /* XXX check for lease expiration */
4410 4410
4411 status = nfserr_stale_clientid; 4411 status = nfserr_stale_clientid;
4412 if (STALE_CLIENTID(clid)) 4412 if (STALE_CLIENTID(clid))
4413 return status; 4413 return status;
4414 4414
4415 nfs4_lock_state(); 4415 nfs4_lock_state();
4416 4416
4417 status = nfserr_locks_held; 4417 status = nfserr_locks_held;
4418 INIT_LIST_HEAD(&matches); 4418 INIT_LIST_HEAD(&matches);
4419 4419
4420 list_for_each_entry(sop, &ownerstr_hashtbl[hashval], so_strhash) { 4420 list_for_each_entry(sop, &ownerstr_hashtbl[hashval], so_strhash) {
4421 if (sop->so_is_open_owner) 4421 if (sop->so_is_open_owner)
4422 continue; 4422 continue;
4423 if (!same_owner_str(sop, owner, clid)) 4423 if (!same_owner_str(sop, owner, clid))
4424 continue; 4424 continue;
4425 list_for_each_entry(stp, &sop->so_stateids, 4425 list_for_each_entry(stp, &sop->so_stateids,
4426 st_perstateowner) { 4426 st_perstateowner) {
4427 lo = lockowner(sop); 4427 lo = lockowner(sop);
4428 if (check_for_locks(stp->st_file, lo)) 4428 if (check_for_locks(stp->st_file, lo))
4429 goto out; 4429 goto out;
4430 list_add(&lo->lo_list, &matches); 4430 list_add(&lo->lo_list, &matches);
4431 } 4431 }
4432 } 4432 }
4433 /* Clients probably won't expect us to return with some (but not all) 4433 /* Clients probably won't expect us to return with some (but not all)
4434 * of the lockowner state released; so don't release any until all 4434 * of the lockowner state released; so don't release any until all
4435 * have been checked. */ 4435 * have been checked. */
4436 status = nfs_ok; 4436 status = nfs_ok;
4437 while (!list_empty(&matches)) { 4437 while (!list_empty(&matches)) {
4438 lo = list_entry(matches.next, struct nfs4_lockowner, 4438 lo = list_entry(matches.next, struct nfs4_lockowner,
4439 lo_list); 4439 lo_list);
4440 /* unhash_stateowner deletes so_perclient only 4440 /* unhash_stateowner deletes so_perclient only
4441 * for openowners. */ 4441 * for openowners. */
4442 list_del(&lo->lo_list); 4442 list_del(&lo->lo_list);
4443 release_lockowner(lo); 4443 release_lockowner(lo);
4444 } 4444 }
4445 out: 4445 out:
4446 nfs4_unlock_state(); 4446 nfs4_unlock_state();
4447 return status; 4447 return status;
4448 } 4448 }
4449 4449
4450 static inline struct nfs4_client_reclaim * 4450 static inline struct nfs4_client_reclaim *
4451 alloc_reclaim(void) 4451 alloc_reclaim(void)
4452 { 4452 {
4453 return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL); 4453 return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
4454 } 4454 }
4455 4455
4456 int 4456 int
4457 nfs4_has_reclaimed_state(const char *name, bool use_exchange_id) 4457 nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
4458 { 4458 {
4459 unsigned int strhashval = clientstr_hashval(name); 4459 unsigned int strhashval = clientstr_hashval(name);
4460 struct nfs4_client *clp; 4460 struct nfs4_client *clp;
4461 4461
4462 clp = find_confirmed_client_by_str(name, strhashval); 4462 clp = find_confirmed_client_by_str(name, strhashval);
4463 if (!clp) 4463 if (!clp)
4464 return 0; 4464 return 0;
4465 return test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); 4465 return test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
4466 } 4466 }
4467 4467
4468 /* 4468 /*
4469 * failure => all reset bets are off, nfserr_no_grace... 4469 * failure => all reset bets are off, nfserr_no_grace...
4470 */ 4470 */
4471 int 4471 int
4472 nfs4_client_to_reclaim(const char *name) 4472 nfs4_client_to_reclaim(const char *name)
4473 { 4473 {
4474 unsigned int strhashval; 4474 unsigned int strhashval;
4475 struct nfs4_client_reclaim *crp = NULL; 4475 struct nfs4_client_reclaim *crp = NULL;
4476 4476
4477 dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name); 4477 dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
4478 crp = alloc_reclaim(); 4478 crp = alloc_reclaim();
4479 if (!crp) 4479 if (!crp)
4480 return 0; 4480 return 0;
4481 strhashval = clientstr_hashval(name); 4481 strhashval = clientstr_hashval(name);
4482 INIT_LIST_HEAD(&crp->cr_strhash); 4482 INIT_LIST_HEAD(&crp->cr_strhash);
4483 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]); 4483 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]);
4484 memcpy(crp->cr_recdir, name, HEXDIR_LEN); 4484 memcpy(crp->cr_recdir, name, HEXDIR_LEN);
4485 reclaim_str_hashtbl_size++; 4485 reclaim_str_hashtbl_size++;
4486 return 1; 4486 return 1;
4487 } 4487 }
4488 4488
4489 void 4489 void
4490 nfs4_release_reclaim(void) 4490 nfs4_release_reclaim(void)
4491 { 4491 {
4492 struct nfs4_client_reclaim *crp = NULL; 4492 struct nfs4_client_reclaim *crp = NULL;
4493 int i; 4493 int i;
4494 4494
4495 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 4495 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4496 while (!list_empty(&reclaim_str_hashtbl[i])) { 4496 while (!list_empty(&reclaim_str_hashtbl[i])) {
4497 crp = list_entry(reclaim_str_hashtbl[i].next, 4497 crp = list_entry(reclaim_str_hashtbl[i].next,
4498 struct nfs4_client_reclaim, cr_strhash); 4498 struct nfs4_client_reclaim, cr_strhash);
4499 list_del(&crp->cr_strhash); 4499 list_del(&crp->cr_strhash);
4500 kfree(crp); 4500 kfree(crp);
4501 reclaim_str_hashtbl_size--; 4501 reclaim_str_hashtbl_size--;
4502 } 4502 }
4503 } 4503 }
4504 BUG_ON(reclaim_str_hashtbl_size); 4504 BUG_ON(reclaim_str_hashtbl_size);
4505 } 4505 }
4506 4506
4507 /* 4507 /*
4508 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */ 4508 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
4509 struct nfs4_client_reclaim * 4509 struct nfs4_client_reclaim *
4510 nfsd4_find_reclaim_client(struct nfs4_client *clp) 4510 nfsd4_find_reclaim_client(struct nfs4_client *clp)
4511 { 4511 {
4512 unsigned int strhashval; 4512 unsigned int strhashval;
4513 struct nfs4_client_reclaim *crp = NULL; 4513 struct nfs4_client_reclaim *crp = NULL;
4514 4514
4515 dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n", 4515 dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n",
4516 clp->cl_name.len, clp->cl_name.data, 4516 clp->cl_name.len, clp->cl_name.data,
4517 clp->cl_recdir); 4517 clp->cl_recdir);
4518 4518
4519 /* find clp->cl_name in reclaim_str_hashtbl */ 4519 /* find clp->cl_name in reclaim_str_hashtbl */
4520 strhashval = clientstr_hashval(clp->cl_recdir); 4520 strhashval = clientstr_hashval(clp->cl_recdir);
4521 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) { 4521 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) {
4522 if (same_name(crp->cr_recdir, clp->cl_recdir)) { 4522 if (same_name(crp->cr_recdir, clp->cl_recdir)) {
4523 return crp; 4523 return crp;
4524 } 4524 }
4525 } 4525 }
4526 return NULL; 4526 return NULL;
4527 } 4527 }
4528 4528
4529 /* 4529 /*
4530 * Called from OPEN. Look for clientid in reclaim list. 4530 * Called from OPEN. Look for clientid in reclaim list.
4531 */ 4531 */
4532 __be32 4532 __be32
4533 nfs4_check_open_reclaim(clientid_t *clid) 4533 nfs4_check_open_reclaim(clientid_t *clid)
4534 { 4534 {
4535 struct nfs4_client *clp; 4535 struct nfs4_client *clp;
4536 4536
4537 /* find clientid in conf_id_hashtbl */ 4537 /* find clientid in conf_id_hashtbl */
4538 clp = find_confirmed_client(clid); 4538 clp = find_confirmed_client(clid);
4539 if (clp == NULL) 4539 if (clp == NULL)
4540 return nfserr_reclaim_bad; 4540 return nfserr_reclaim_bad;
4541 4541
4542 return nfsd4_client_record_check(clp) ? nfserr_reclaim_bad : nfs_ok; 4542 return nfsd4_client_record_check(clp) ? nfserr_reclaim_bad : nfs_ok;
4543 } 4543 }
4544 4544
4545 #ifdef CONFIG_NFSD_FAULT_INJECTION 4545 #ifdef CONFIG_NFSD_FAULT_INJECTION
4546 4546
4547 void nfsd_forget_clients(u64 num) 4547 void nfsd_forget_clients(u64 num)
4548 { 4548 {
4549 struct nfs4_client *clp, *next; 4549 struct nfs4_client *clp, *next;
4550 int count = 0; 4550 int count = 0;
4551 4551
4552 nfs4_lock_state(); 4552 nfs4_lock_state();
4553 list_for_each_entry_safe(clp, next, &client_lru, cl_lru) { 4553 list_for_each_entry_safe(clp, next, &client_lru, cl_lru) {
4554 nfsd4_client_record_remove(clp); 4554 nfsd4_client_record_remove(clp);
4555 expire_client(clp); 4555 expire_client(clp);
4556 if (++count == num) 4556 if (++count == num)
4557 break; 4557 break;
4558 } 4558 }
4559 nfs4_unlock_state(); 4559 nfs4_unlock_state();
4560 4560
4561 printk(KERN_INFO "NFSD: Forgot %d clients", count); 4561 printk(KERN_INFO "NFSD: Forgot %d clients", count);
4562 } 4562 }
4563 4563
4564 static void release_lockowner_sop(struct nfs4_stateowner *sop) 4564 static void release_lockowner_sop(struct nfs4_stateowner *sop)
4565 { 4565 {
4566 release_lockowner(lockowner(sop)); 4566 release_lockowner(lockowner(sop));
4567 } 4567 }
4568 4568
4569 static void release_openowner_sop(struct nfs4_stateowner *sop) 4569 static void release_openowner_sop(struct nfs4_stateowner *sop)
4570 { 4570 {
4571 release_openowner(openowner(sop)); 4571 release_openowner(openowner(sop));
4572 } 4572 }
4573 4573
4574 static int nfsd_release_n_owners(u64 num, bool is_open_owner, 4574 static int nfsd_release_n_owners(u64 num, bool is_open_owner,
4575 void (*release_sop)(struct nfs4_stateowner *)) 4575 void (*release_sop)(struct nfs4_stateowner *))
4576 { 4576 {
4577 int i, count = 0; 4577 int i, count = 0;
4578 struct nfs4_stateowner *sop, *next; 4578 struct nfs4_stateowner *sop, *next;
4579 4579
4580 for (i = 0; i < OWNER_HASH_SIZE; i++) { 4580 for (i = 0; i < OWNER_HASH_SIZE; i++) {
4581 list_for_each_entry_safe(sop, next, &ownerstr_hashtbl[i], so_strhash) { 4581 list_for_each_entry_safe(sop, next, &ownerstr_hashtbl[i], so_strhash) {
4582 if (sop->so_is_open_owner != is_open_owner) 4582 if (sop->so_is_open_owner != is_open_owner)
4583 continue; 4583 continue;
4584 release_sop(sop); 4584 release_sop(sop);
4585 if (++count == num) 4585 if (++count == num)
4586 return count; 4586 return count;
4587 } 4587 }
4588 } 4588 }
4589 return count; 4589 return count;
4590 } 4590 }
4591 4591
4592 void nfsd_forget_locks(u64 num) 4592 void nfsd_forget_locks(u64 num)
4593 { 4593 {
4594 int count; 4594 int count;
4595 4595
4596 nfs4_lock_state(); 4596 nfs4_lock_state();
4597 count = nfsd_release_n_owners(num, false, release_lockowner_sop); 4597 count = nfsd_release_n_owners(num, false, release_lockowner_sop);
4598 nfs4_unlock_state(); 4598 nfs4_unlock_state();
4599 4599
4600 printk(KERN_INFO "NFSD: Forgot %d locks", count); 4600 printk(KERN_INFO "NFSD: Forgot %d locks", count);
4601 } 4601 }
4602 4602
4603 void nfsd_forget_openowners(u64 num) 4603 void nfsd_forget_openowners(u64 num)
4604 { 4604 {
4605 int count; 4605 int count;
4606 4606
4607 nfs4_lock_state(); 4607 nfs4_lock_state();
4608 count = nfsd_release_n_owners(num, true, release_openowner_sop); 4608 count = nfsd_release_n_owners(num, true, release_openowner_sop);
4609 nfs4_unlock_state(); 4609 nfs4_unlock_state();
4610 4610
4611 printk(KERN_INFO "NFSD: Forgot %d open owners", count); 4611 printk(KERN_INFO "NFSD: Forgot %d open owners", count);
4612 } 4612 }
4613 4613
4614 int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegation *)) 4614 int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegation *))
4615 { 4615 {
4616 int i, count = 0; 4616 int i, count = 0;
4617 struct nfs4_file *fp, *fnext; 4617 struct nfs4_file *fp, *fnext;
4618 struct nfs4_delegation *dp, *dnext; 4618 struct nfs4_delegation *dp, *dnext;
4619 4619
4620 for (i = 0; i < FILE_HASH_SIZE; i++) { 4620 for (i = 0; i < FILE_HASH_SIZE; i++) {
4621 list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) { 4621 list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) {
4622 list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) { 4622 list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) {
4623 deleg_func(dp); 4623 deleg_func(dp);
4624 if (++count == num) 4624 if (++count == num)
4625 return count; 4625 return count;
4626 } 4626 }
4627 } 4627 }
4628 } 4628 }
4629 4629
4630 return count; 4630 return count;
4631 } 4631 }
4632 4632
4633 void nfsd_forget_delegations(u64 num) 4633 void nfsd_forget_delegations(u64 num)
4634 { 4634 {
4635 unsigned int count; 4635 unsigned int count;
4636 4636
4637 nfs4_lock_state(); 4637 nfs4_lock_state();
4638 count = nfsd_process_n_delegations(num, unhash_delegation); 4638 count = nfsd_process_n_delegations(num, unhash_delegation);
4639 nfs4_unlock_state(); 4639 nfs4_unlock_state();
4640 4640
4641 printk(KERN_INFO "NFSD: Forgot %d delegations", count); 4641 printk(KERN_INFO "NFSD: Forgot %d delegations", count);
4642 } 4642 }
4643 4643
4644 void nfsd_recall_delegations(u64 num) 4644 void nfsd_recall_delegations(u64 num)
4645 { 4645 {
4646 unsigned int count; 4646 unsigned int count;
4647 4647
4648 nfs4_lock_state(); 4648 nfs4_lock_state();
4649 spin_lock(&recall_lock); 4649 spin_lock(&recall_lock);
4650 count = nfsd_process_n_delegations(num, nfsd_break_one_deleg); 4650 count = nfsd_process_n_delegations(num, nfsd_break_one_deleg);
4651 spin_unlock(&recall_lock); 4651 spin_unlock(&recall_lock);
4652 nfs4_unlock_state(); 4652 nfs4_unlock_state();
4653 4653
4654 printk(KERN_INFO "NFSD: Recalled %d delegations", count); 4654 printk(KERN_INFO "NFSD: Recalled %d delegations", count);
4655 } 4655 }
4656 4656
4657 #endif /* CONFIG_NFSD_FAULT_INJECTION */ 4657 #endif /* CONFIG_NFSD_FAULT_INJECTION */
4658 4658
4659 /* initialization to perform at module load time: */ 4659 /* initialization to perform at module load time: */
4660 4660
4661 void 4661 void
4662 nfs4_state_init(void) 4662 nfs4_state_init(void)
4663 { 4663 {
4664 int i; 4664 int i;
4665 4665
4666 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 4666 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4667 INIT_LIST_HEAD(&conf_id_hashtbl[i]); 4667 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
4668 INIT_LIST_HEAD(&conf_str_hashtbl[i]); 4668 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
4669 INIT_LIST_HEAD(&unconf_str_hashtbl[i]); 4669 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
4670 INIT_LIST_HEAD(&unconf_id_hashtbl[i]); 4670 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
4671 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]); 4671 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
4672 } 4672 }
4673 for (i = 0; i < SESSION_HASH_SIZE; i++) 4673 for (i = 0; i < SESSION_HASH_SIZE; i++)
4674 INIT_LIST_HEAD(&sessionid_hashtbl[i]); 4674 INIT_LIST_HEAD(&sessionid_hashtbl[i]);
4675 for (i = 0; i < FILE_HASH_SIZE; i++) { 4675 for (i = 0; i < FILE_HASH_SIZE; i++) {
4676 INIT_LIST_HEAD(&file_hashtbl[i]); 4676 INIT_LIST_HEAD(&file_hashtbl[i]);
4677 } 4677 }
4678 for (i = 0; i < OWNER_HASH_SIZE; i++) { 4678 for (i = 0; i < OWNER_HASH_SIZE; i++) {
4679 INIT_LIST_HEAD(&ownerstr_hashtbl[i]); 4679 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
4680 } 4680 }
4681 for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++) 4681 for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++)
4682 INIT_LIST_HEAD(&lockowner_ino_hashtbl[i]); 4682 INIT_LIST_HEAD(&lockowner_ino_hashtbl[i]);
4683 INIT_LIST_HEAD(&close_lru); 4683 INIT_LIST_HEAD(&close_lru);
4684 INIT_LIST_HEAD(&client_lru); 4684 INIT_LIST_HEAD(&client_lru);
4685 INIT_LIST_HEAD(&del_recall_lru); 4685 INIT_LIST_HEAD(&del_recall_lru);
4686 reclaim_str_hashtbl_size = 0; 4686 reclaim_str_hashtbl_size = 0;
4687 } 4687 }
4688 4688
4689 /* 4689 /*
4690 * Since the lifetime of a delegation isn't limited to that of an open, a 4690 * Since the lifetime of a delegation isn't limited to that of an open, a
4691 * client may quite reasonably hang on to a delegation as long as it has 4691 * client may quite reasonably hang on to a delegation as long as it has
4692 * the inode cached. This becomes an obvious problem the first time a 4692 * the inode cached. This becomes an obvious problem the first time a
4693 * client's inode cache approaches the size of the server's total memory. 4693 * client's inode cache approaches the size of the server's total memory.
4694 * 4694 *
4695 * For now we avoid this problem by imposing a hard limit on the number 4695 * For now we avoid this problem by imposing a hard limit on the number
4696 * of delegations, which varies according to the server's memory size. 4696 * of delegations, which varies according to the server's memory size.
4697 */ 4697 */
4698 static void 4698 static void
4699 set_max_delegations(void) 4699 set_max_delegations(void)
4700 { 4700 {
4701 /* 4701 /*
4702 * Allow at most 4 delegations per megabyte of RAM. Quick 4702 * Allow at most 4 delegations per megabyte of RAM. Quick
4703 * estimates suggest that in the worst case (where every delegation 4703 * estimates suggest that in the worst case (where every delegation
4704 * is for a different inode), a delegation could take about 1.5K, 4704 * is for a different inode), a delegation could take about 1.5K,
4705 * giving a worst case usage of about 6% of memory. 4705 * giving a worst case usage of about 6% of memory.
4706 */ 4706 */
4707 max_delegations = nr_free_buffer_pages() >> (20 - 2 - PAGE_SHIFT); 4707 max_delegations = nr_free_buffer_pages() >> (20 - 2 - PAGE_SHIFT);
4708 } 4708 }
4709 4709
4710 /* initialization to perform when the nfsd service is started: */ 4710 /* initialization to perform when the nfsd service is started: */
4711 4711
4712 int 4712 int
4713 nfs4_state_start(void) 4713 nfs4_state_start(void)
4714 { 4714 {
4715 int ret; 4715 int ret;
4716 4716
4717 /* 4717 /*
4718 * FIXME: For now, we hang most of the pernet global stuff off of 4718 * FIXME: For now, we hang most of the pernet global stuff off of
4719 * init_net until nfsd is fully containerized. Eventually, we'll 4719 * init_net until nfsd is fully containerized. Eventually, we'll
4720 * need to pass a net pointer into this function, take a reference 4720 * need to pass a net pointer into this function, take a reference
4721 * to that instead and then do most of the rest of this on a per-net 4721 * to that instead and then do most of the rest of this on a per-net
4722 * basis. 4722 * basis.
4723 */ 4723 */
4724 get_net(&init_net); 4724 get_net(&init_net);
4725 nfsd4_client_tracking_init(&init_net); 4725 nfsd4_client_tracking_init(&init_net);
4726 boot_time = get_seconds(); 4726 boot_time = get_seconds();
4727 locks_start_grace(&nfsd4_manager); 4727 locks_start_grace(&nfsd4_manager);
4728 grace_ended = false; 4728 grace_ended = false;
4729 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4729 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4730 nfsd4_grace); 4730 nfsd4_grace);
4731 ret = set_callback_cred(); 4731 ret = set_callback_cred();
4732 if (ret) { 4732 if (ret) {
4733 ret = -ENOMEM; 4733 ret = -ENOMEM;
4734 goto out_recovery; 4734 goto out_recovery;
4735 } 4735 }
4736 laundry_wq = create_singlethread_workqueue("nfsd4"); 4736 laundry_wq = create_singlethread_workqueue("nfsd4");
4737 if (laundry_wq == NULL) { 4737 if (laundry_wq == NULL) {
4738 ret = -ENOMEM; 4738 ret = -ENOMEM;
4739 goto out_recovery; 4739 goto out_recovery;
4740 } 4740 }
4741 ret = nfsd4_create_callback_queue(); 4741 ret = nfsd4_create_callback_queue();
4742 if (ret) 4742 if (ret)
4743 goto out_free_laundry; 4743 goto out_free_laundry;
4744 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ); 4744 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ);
4745 set_max_delegations(); 4745 set_max_delegations();
4746 return 0; 4746 return 0;
4747 out_free_laundry: 4747 out_free_laundry:
4748 destroy_workqueue(laundry_wq); 4748 destroy_workqueue(laundry_wq);
4749 out_recovery: 4749 out_recovery:
4750 nfsd4_client_tracking_exit(&init_net); 4750 nfsd4_client_tracking_exit(&init_net);
4751 put_net(&init_net); 4751 put_net(&init_net);
4752 return ret; 4752 return ret;
4753 } 4753 }
4754 4754
4755 static void 4755 static void
4756 __nfs4_state_shutdown(void) 4756 __nfs4_state_shutdown(void)
4757 { 4757 {
4758 int i; 4758 int i;
4759 struct nfs4_client *clp = NULL; 4759 struct nfs4_client *clp = NULL;
4760 struct nfs4_delegation *dp = NULL; 4760 struct nfs4_delegation *dp = NULL;
4761 struct list_head *pos, *next, reaplist; 4761 struct list_head *pos, *next, reaplist;
4762 4762
4763 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 4763 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4764 while (!list_empty(&conf_id_hashtbl[i])) { 4764 while (!list_empty(&conf_id_hashtbl[i])) {
4765 clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); 4765 clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
4766 expire_client(clp); 4766 expire_client(clp);
4767 } 4767 }
4768 while (!list_empty(&unconf_str_hashtbl[i])) { 4768 while (!list_empty(&unconf_str_hashtbl[i])) {
4769 clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash); 4769 clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
4770 expire_client(clp); 4770 expire_client(clp);
4771 } 4771 }
4772 } 4772 }
4773 INIT_LIST_HEAD(&reaplist); 4773 INIT_LIST_HEAD(&reaplist);
4774 spin_lock(&recall_lock); 4774 spin_lock(&recall_lock);
4775 list_for_each_safe(pos, next, &del_recall_lru) { 4775 list_for_each_safe(pos, next, &del_recall_lru) {
4776 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 4776 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
4777 list_move(&dp->dl_recall_lru, &reaplist); 4777 list_move(&dp->dl_recall_lru, &reaplist);
4778 } 4778 }
4779 spin_unlock(&recall_lock); 4779 spin_unlock(&recall_lock);
4780 list_for_each_safe(pos, next, &reaplist) { 4780 list_for_each_safe(pos, next, &reaplist) {
4781 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 4781 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
4782 unhash_delegation(dp); 4782 unhash_delegation(dp);
4783 } 4783 }
4784 4784
4785 nfsd4_client_tracking_exit(&init_net); 4785 nfsd4_client_tracking_exit(&init_net);
4786 put_net(&init_net); 4786 put_net(&init_net);
4787 } 4787 }
4788 4788
4789 void 4789 void
4790 nfs4_state_shutdown(void) 4790 nfs4_state_shutdown(void)
4791 { 4791 {
4792 cancel_delayed_work_sync(&laundromat_work); 4792 cancel_delayed_work_sync(&laundromat_work);
4793 destroy_workqueue(laundry_wq); 4793 destroy_workqueue(laundry_wq);
4794 locks_end_grace(&nfsd4_manager); 4794 locks_end_grace(&nfsd4_manager);
4795 nfs4_lock_state(); 4795 nfs4_lock_state();
4796 __nfs4_state_shutdown(); 4796 __nfs4_state_shutdown();
4797 nfs4_unlock_state(); 4797 nfs4_unlock_state();
4798 nfsd4_destroy_callback_queue(); 4798 nfsd4_destroy_callback_queue();
4799 } 4799 }
4800 4800
4801 static void 4801 static void
4802 get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid) 4802 get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
4803 { 4803 {
4804 if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid)) 4804 if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
4805 memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t)); 4805 memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
4806 } 4806 }
4807 4807
4808 static void 4808 static void
4809 put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid) 4809 put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
4810 { 4810 {
4811 if (cstate->minorversion) { 4811 if (cstate->minorversion) {
4812 memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t)); 4812 memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t));
4813 SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); 4813 SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
4814 } 4814 }
4815 } 4815 }
4816 4816
4817 void 4817 void
4818 clear_current_stateid(struct nfsd4_compound_state *cstate) 4818 clear_current_stateid(struct nfsd4_compound_state *cstate)
4819 { 4819 {
4820 CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); 4820 CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
4821 } 4821 }
4822 4822
4823 /* 4823 /*
4824 * functions to set current state id 4824 * functions to set current state id
4825 */ 4825 */
4826 void 4826 void
4827 nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp) 4827 nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
4828 { 4828 {
4829 put_stateid(cstate, &odp->od_stateid); 4829 put_stateid(cstate, &odp->od_stateid);
4830 } 4830 }
4831 4831
4832 void 4832 void
4833 nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 4833 nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
4834 { 4834 {
4835 put_stateid(cstate, &open->op_stateid); 4835 put_stateid(cstate, &open->op_stateid);
4836 } 4836 }
4837 4837
4838 void 4838 void
4839 nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close) 4839 nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
4840 { 4840 {
4841 put_stateid(cstate, &close->cl_stateid); 4841 put_stateid(cstate, &close->cl_stateid);
4842 } 4842 }
4843 4843
4844 void 4844 void
4845 nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lock) 4845 nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lock)
4846 { 4846 {
4847 put_stateid(cstate, &lock->lk_resp_stateid); 4847 put_stateid(cstate, &lock->lk_resp_stateid);
4848 } 4848 }
4849 4849
4850 /* 4850 /*
4851 * functions to consume current state id 4851 * functions to consume current state id
4852 */ 4852 */
4853 4853
4854 void 4854 void
4855 nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp) 4855 nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
4856 { 4856 {
4857 get_stateid(cstate, &odp->od_stateid); 4857 get_stateid(cstate, &odp->od_stateid);
4858 } 4858 }
4859 4859
4860 void 4860 void
4861 nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, struct nfsd4_delegreturn *drp) 4861 nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, struct nfsd4_delegreturn *drp)
4862 { 4862 {
4863 get_stateid(cstate, &drp->dr_stateid); 4863 get_stateid(cstate, &drp->dr_stateid);
4864 } 4864 }
4865 4865
4866 void 4866 void
4867 nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, struct nfsd4_free_stateid *fsp) 4867 nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, struct nfsd4_free_stateid *fsp)
4868 { 4868 {
4869 get_stateid(cstate, &fsp->fr_stateid); 4869 get_stateid(cstate, &fsp->fr_stateid);
4870 } 4870 }
4871 4871
4872 void 4872 void
4873 nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) 4873 nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr)
4874 { 4874 {
4875 get_stateid(cstate, &setattr->sa_stateid); 4875 get_stateid(cstate, &setattr->sa_stateid);
4876 } 4876 }
4877 4877
4878 void 4878 void
4879 nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close) 4879 nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
4880 { 4880 {
4881 get_stateid(cstate, &close->cl_stateid); 4881 get_stateid(cstate, &close->cl_stateid);
4882 } 4882 }
4883 4883
4884 void 4884 void
4885 nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku) 4885 nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku)
4886 { 4886 {
4887 get_stateid(cstate, &locku->lu_stateid); 4887 get_stateid(cstate, &locku->lu_stateid);
4888 } 4888 }
4889 4889
4890 void 4890 void
4891 nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, struct nfsd4_read *read) 4891 nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, struct nfsd4_read *read)
4892 { 4892 {
4893 get_stateid(cstate, &read->rd_stateid); 4893 get_stateid(cstate, &read->rd_stateid);
4894 } 4894 }
4895 4895
4896 void 4896 void
4897 nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, struct nfsd4_write *write) 4897 nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, struct nfsd4_write *write)
4898 { 4898 {
4899 get_stateid(cstate, &write->wr_stateid); 4899 get_stateid(cstate, &write->wr_stateid);
4900 } 4900 }
4901 4901
1 /* 1 /*
2 * Server-side XDR for NFSv4 2 * Server-side XDR 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 * TODO: Neil Brown made the following observation: We currently 35 * TODO: Neil Brown made the following observation: We currently
36 * initially reserve NFSD_BUFSIZE space on the transmit queue and 36 * initially reserve NFSD_BUFSIZE space on the transmit queue and
37 * never release any of that until the request is complete. 37 * never release any of that until the request is complete.
38 * It would be good to calculate a new maximum response size while 38 * It would be good to calculate a new maximum response size while
39 * decoding the COMPOUND, and call svc_reserve with this number 39 * decoding the COMPOUND, and call svc_reserve with this number
40 * at the end of nfs4svc_decode_compoundargs. 40 * at the end of nfs4svc_decode_compoundargs.
41 */ 41 */
42 42
43 #include <linux/slab.h> 43 #include <linux/slab.h>
44 #include <linux/namei.h> 44 #include <linux/namei.h>
45 #include <linux/statfs.h> 45 #include <linux/statfs.h>
46 #include <linux/utsname.h> 46 #include <linux/utsname.h>
47 #include <linux/pagemap.h> 47 #include <linux/pagemap.h>
48 #include <linux/sunrpc/svcauth_gss.h> 48 #include <linux/sunrpc/svcauth_gss.h>
49 49
50 #include "idmap.h" 50 #include "idmap.h"
51 #include "acl.h" 51 #include "acl.h"
52 #include "xdr4.h" 52 #include "xdr4.h"
53 #include "vfs.h" 53 #include "vfs.h"
54 #include "state.h" 54 #include "state.h"
55 #include "cache.h" 55 #include "cache.h"
56 56
57 #define NFSDDBG_FACILITY NFSDDBG_XDR 57 #define NFSDDBG_FACILITY NFSDDBG_XDR
58 58
59 /* 59 /*
60 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing 60 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
61 * directory in order to indicate to the client that a filesystem boundary is present 61 * directory in order to indicate to the client that a filesystem boundary is present
62 * We use a fixed fsid for a referral 62 * We use a fixed fsid for a referral
63 */ 63 */
64 #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL 64 #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL
65 #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL 65 #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL
66 66
67 static __be32 67 static __be32
68 check_filename(char *str, int len, __be32 err) 68 check_filename(char *str, int len, __be32 err)
69 { 69 {
70 int i; 70 int i;
71 71
72 if (len == 0) 72 if (len == 0)
73 return nfserr_inval; 73 return nfserr_inval;
74 if (isdotent(str, len)) 74 if (isdotent(str, len))
75 return err; 75 return err;
76 for (i = 0; i < len; i++) 76 for (i = 0; i < len; i++)
77 if (str[i] == '/') 77 if (str[i] == '/')
78 return err; 78 return err;
79 return 0; 79 return 0;
80 } 80 }
81 81
82 #define DECODE_HEAD \ 82 #define DECODE_HEAD \
83 __be32 *p; \ 83 __be32 *p; \
84 __be32 status 84 __be32 status
85 #define DECODE_TAIL \ 85 #define DECODE_TAIL \
86 status = 0; \ 86 status = 0; \
87 out: \ 87 out: \
88 return status; \ 88 return status; \
89 xdr_error: \ 89 xdr_error: \
90 dprintk("NFSD: xdr error (%s:%d)\n", \ 90 dprintk("NFSD: xdr error (%s:%d)\n", \
91 __FILE__, __LINE__); \ 91 __FILE__, __LINE__); \
92 status = nfserr_bad_xdr; \ 92 status = nfserr_bad_xdr; \
93 goto out 93 goto out
94 94
95 #define READ32(x) (x) = ntohl(*p++) 95 #define READ32(x) (x) = ntohl(*p++)
96 #define READ64(x) do { \ 96 #define READ64(x) do { \
97 (x) = (u64)ntohl(*p++) << 32; \ 97 (x) = (u64)ntohl(*p++) << 32; \
98 (x) |= ntohl(*p++); \ 98 (x) |= ntohl(*p++); \
99 } while (0) 99 } while (0)
100 #define READTIME(x) do { \ 100 #define READTIME(x) do { \
101 p++; \ 101 p++; \
102 (x) = ntohl(*p++); \ 102 (x) = ntohl(*p++); \
103 p++; \ 103 p++; \
104 } while (0) 104 } while (0)
105 #define READMEM(x,nbytes) do { \ 105 #define READMEM(x,nbytes) do { \
106 x = (char *)p; \ 106 x = (char *)p; \
107 p += XDR_QUADLEN(nbytes); \ 107 p += XDR_QUADLEN(nbytes); \
108 } while (0) 108 } while (0)
109 #define SAVEMEM(x,nbytes) do { \ 109 #define SAVEMEM(x,nbytes) do { \
110 if (!(x = (p==argp->tmp || p == argp->tmpp) ? \ 110 if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
111 savemem(argp, p, nbytes) : \ 111 savemem(argp, p, nbytes) : \
112 (char *)p)) { \ 112 (char *)p)) { \
113 dprintk("NFSD: xdr error (%s:%d)\n", \ 113 dprintk("NFSD: xdr error (%s:%d)\n", \
114 __FILE__, __LINE__); \ 114 __FILE__, __LINE__); \
115 goto xdr_error; \ 115 goto xdr_error; \
116 } \ 116 } \
117 p += XDR_QUADLEN(nbytes); \ 117 p += XDR_QUADLEN(nbytes); \
118 } while (0) 118 } while (0)
119 #define COPYMEM(x,nbytes) do { \ 119 #define COPYMEM(x,nbytes) do { \
120 memcpy((x), p, nbytes); \ 120 memcpy((x), p, nbytes); \
121 p += XDR_QUADLEN(nbytes); \ 121 p += XDR_QUADLEN(nbytes); \
122 } while (0) 122 } while (0)
123 123
124 /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */ 124 /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
125 #define READ_BUF(nbytes) do { \ 125 #define READ_BUF(nbytes) do { \
126 if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \ 126 if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \
127 p = argp->p; \ 127 p = argp->p; \
128 argp->p += XDR_QUADLEN(nbytes); \ 128 argp->p += XDR_QUADLEN(nbytes); \
129 } else if (!(p = read_buf(argp, nbytes))) { \ 129 } else if (!(p = read_buf(argp, nbytes))) { \
130 dprintk("NFSD: xdr error (%s:%d)\n", \ 130 dprintk("NFSD: xdr error (%s:%d)\n", \
131 __FILE__, __LINE__); \ 131 __FILE__, __LINE__); \
132 goto xdr_error; \ 132 goto xdr_error; \
133 } \ 133 } \
134 } while (0) 134 } while (0)
135 135
136 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) 136 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
137 { 137 {
138 /* We want more bytes than seem to be available. 138 /* We want more bytes than seem to be available.
139 * Maybe we need a new page, maybe we have just run out 139 * Maybe we need a new page, maybe we have just run out
140 */ 140 */
141 unsigned int avail = (char *)argp->end - (char *)argp->p; 141 unsigned int avail = (char *)argp->end - (char *)argp->p;
142 __be32 *p; 142 __be32 *p;
143 if (avail + argp->pagelen < nbytes) 143 if (avail + argp->pagelen < nbytes)
144 return NULL; 144 return NULL;
145 if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ 145 if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
146 return NULL; 146 return NULL;
147 /* ok, we can do it with the current plus the next page */ 147 /* ok, we can do it with the current plus the next page */
148 if (nbytes <= sizeof(argp->tmp)) 148 if (nbytes <= sizeof(argp->tmp))
149 p = argp->tmp; 149 p = argp->tmp;
150 else { 150 else {
151 kfree(argp->tmpp); 151 kfree(argp->tmpp);
152 p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL); 152 p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
153 if (!p) 153 if (!p)
154 return NULL; 154 return NULL;
155 155
156 } 156 }
157 /* 157 /*
158 * The following memcpy is safe because read_buf is always 158 * The following memcpy is safe because read_buf is always
159 * called with nbytes > avail, and the two cases above both 159 * called with nbytes > avail, and the two cases above both
160 * guarantee p points to at least nbytes bytes. 160 * guarantee p points to at least nbytes bytes.
161 */ 161 */
162 memcpy(p, argp->p, avail); 162 memcpy(p, argp->p, avail);
163 /* step to next page */ 163 /* step to next page */
164 argp->p = page_address(argp->pagelist[0]); 164 argp->p = page_address(argp->pagelist[0]);
165 argp->pagelist++; 165 argp->pagelist++;
166 if (argp->pagelen < PAGE_SIZE) { 166 if (argp->pagelen < PAGE_SIZE) {
167 argp->end = argp->p + (argp->pagelen>>2); 167 argp->end = argp->p + (argp->pagelen>>2);
168 argp->pagelen = 0; 168 argp->pagelen = 0;
169 } else { 169 } else {
170 argp->end = argp->p + (PAGE_SIZE>>2); 170 argp->end = argp->p + (PAGE_SIZE>>2);
171 argp->pagelen -= PAGE_SIZE; 171 argp->pagelen -= PAGE_SIZE;
172 } 172 }
173 memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); 173 memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
174 argp->p += XDR_QUADLEN(nbytes - avail); 174 argp->p += XDR_QUADLEN(nbytes - avail);
175 return p; 175 return p;
176 } 176 }
177 177
178 static int zero_clientid(clientid_t *clid) 178 static int zero_clientid(clientid_t *clid)
179 { 179 {
180 return (clid->cl_boot == 0) && (clid->cl_id == 0); 180 return (clid->cl_boot == 0) && (clid->cl_id == 0);
181 } 181 }
182 182
183 static int 183 static int
184 defer_free(struct nfsd4_compoundargs *argp, 184 defer_free(struct nfsd4_compoundargs *argp,
185 void (*release)(const void *), void *p) 185 void (*release)(const void *), void *p)
186 { 186 {
187 struct tmpbuf *tb; 187 struct tmpbuf *tb;
188 188
189 tb = kmalloc(sizeof(*tb), GFP_KERNEL); 189 tb = kmalloc(sizeof(*tb), GFP_KERNEL);
190 if (!tb) 190 if (!tb)
191 return -ENOMEM; 191 return -ENOMEM;
192 tb->buf = p; 192 tb->buf = p;
193 tb->release = release; 193 tb->release = release;
194 tb->next = argp->to_free; 194 tb->next = argp->to_free;
195 argp->to_free = tb; 195 argp->to_free = tb;
196 return 0; 196 return 0;
197 } 197 }
198 198
199 static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) 199 static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
200 { 200 {
201 if (p == argp->tmp) { 201 if (p == argp->tmp) {
202 p = kmemdup(argp->tmp, nbytes, GFP_KERNEL); 202 p = kmemdup(argp->tmp, nbytes, GFP_KERNEL);
203 if (!p) 203 if (!p)
204 return NULL; 204 return NULL;
205 } else { 205 } else {
206 BUG_ON(p != argp->tmpp); 206 BUG_ON(p != argp->tmpp);
207 argp->tmpp = NULL; 207 argp->tmpp = NULL;
208 } 208 }
209 if (defer_free(argp, kfree, p)) { 209 if (defer_free(argp, kfree, p)) {
210 kfree(p); 210 kfree(p);
211 return NULL; 211 return NULL;
212 } else 212 } else
213 return (char *)p; 213 return (char *)p;
214 } 214 }
215 215
216 static __be32 216 static __be32
217 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) 217 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
218 { 218 {
219 u32 bmlen; 219 u32 bmlen;
220 DECODE_HEAD; 220 DECODE_HEAD;
221 221
222 bmval[0] = 0; 222 bmval[0] = 0;
223 bmval[1] = 0; 223 bmval[1] = 0;
224 bmval[2] = 0; 224 bmval[2] = 0;
225 225
226 READ_BUF(4); 226 READ_BUF(4);
227 READ32(bmlen); 227 READ32(bmlen);
228 if (bmlen > 1000) 228 if (bmlen > 1000)
229 goto xdr_error; 229 goto xdr_error;
230 230
231 READ_BUF(bmlen << 2); 231 READ_BUF(bmlen << 2);
232 if (bmlen > 0) 232 if (bmlen > 0)
233 READ32(bmval[0]); 233 READ32(bmval[0]);
234 if (bmlen > 1) 234 if (bmlen > 1)
235 READ32(bmval[1]); 235 READ32(bmval[1]);
236 if (bmlen > 2) 236 if (bmlen > 2)
237 READ32(bmval[2]); 237 READ32(bmval[2]);
238 238
239 DECODE_TAIL; 239 DECODE_TAIL;
240 } 240 }
241 241
242 static __be32 242 static __be32
243 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, 243 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
244 struct iattr *iattr, struct nfs4_acl **acl) 244 struct iattr *iattr, struct nfs4_acl **acl)
245 { 245 {
246 int expected_len, len = 0; 246 int expected_len, len = 0;
247 u32 dummy32; 247 u32 dummy32;
248 char *buf; 248 char *buf;
249 int host_err; 249 int host_err;
250 250
251 DECODE_HEAD; 251 DECODE_HEAD;
252 iattr->ia_valid = 0; 252 iattr->ia_valid = 0;
253 if ((status = nfsd4_decode_bitmap(argp, bmval))) 253 if ((status = nfsd4_decode_bitmap(argp, bmval)))
254 return status; 254 return status;
255 255
256 READ_BUF(4); 256 READ_BUF(4);
257 READ32(expected_len); 257 READ32(expected_len);
258 258
259 if (bmval[0] & FATTR4_WORD0_SIZE) { 259 if (bmval[0] & FATTR4_WORD0_SIZE) {
260 READ_BUF(8); 260 READ_BUF(8);
261 len += 8; 261 len += 8;
262 READ64(iattr->ia_size); 262 READ64(iattr->ia_size);
263 iattr->ia_valid |= ATTR_SIZE; 263 iattr->ia_valid |= ATTR_SIZE;
264 } 264 }
265 if (bmval[0] & FATTR4_WORD0_ACL) { 265 if (bmval[0] & FATTR4_WORD0_ACL) {
266 int nace; 266 int nace;
267 struct nfs4_ace *ace; 267 struct nfs4_ace *ace;
268 268
269 READ_BUF(4); len += 4; 269 READ_BUF(4); len += 4;
270 READ32(nace); 270 READ32(nace);
271 271
272 if (nace > NFS4_ACL_MAX) 272 if (nace > NFS4_ACL_MAX)
273 return nfserr_resource; 273 return nfserr_resource;
274 274
275 *acl = nfs4_acl_new(nace); 275 *acl = nfs4_acl_new(nace);
276 if (*acl == NULL) { 276 if (*acl == NULL) {
277 host_err = -ENOMEM; 277 host_err = -ENOMEM;
278 goto out_nfserr; 278 goto out_nfserr;
279 } 279 }
280 defer_free(argp, kfree, *acl); 280 defer_free(argp, kfree, *acl);
281 281
282 (*acl)->naces = nace; 282 (*acl)->naces = nace;
283 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { 283 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
284 READ_BUF(16); len += 16; 284 READ_BUF(16); len += 16;
285 READ32(ace->type); 285 READ32(ace->type);
286 READ32(ace->flag); 286 READ32(ace->flag);
287 READ32(ace->access_mask); 287 READ32(ace->access_mask);
288 READ32(dummy32); 288 READ32(dummy32);
289 READ_BUF(dummy32); 289 READ_BUF(dummy32);
290 len += XDR_QUADLEN(dummy32) << 2; 290 len += XDR_QUADLEN(dummy32) << 2;
291 READMEM(buf, dummy32); 291 READMEM(buf, dummy32);
292 ace->whotype = nfs4_acl_get_whotype(buf, dummy32); 292 ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
293 status = nfs_ok; 293 status = nfs_ok;
294 if (ace->whotype != NFS4_ACL_WHO_NAMED) 294 if (ace->whotype != NFS4_ACL_WHO_NAMED)
295 ace->who = 0; 295 ace->who = 0;
296 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 296 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
297 status = nfsd_map_name_to_gid(argp->rqstp, 297 status = nfsd_map_name_to_gid(argp->rqstp,
298 buf, dummy32, &ace->who); 298 buf, dummy32, &ace->who);
299 else 299 else
300 status = nfsd_map_name_to_uid(argp->rqstp, 300 status = nfsd_map_name_to_uid(argp->rqstp,
301 buf, dummy32, &ace->who); 301 buf, dummy32, &ace->who);
302 if (status) 302 if (status)
303 return status; 303 return status;
304 } 304 }
305 } else 305 } else
306 *acl = NULL; 306 *acl = NULL;
307 if (bmval[1] & FATTR4_WORD1_MODE) { 307 if (bmval[1] & FATTR4_WORD1_MODE) {
308 READ_BUF(4); 308 READ_BUF(4);
309 len += 4; 309 len += 4;
310 READ32(iattr->ia_mode); 310 READ32(iattr->ia_mode);
311 iattr->ia_mode &= (S_IFMT | S_IALLUGO); 311 iattr->ia_mode &= (S_IFMT | S_IALLUGO);
312 iattr->ia_valid |= ATTR_MODE; 312 iattr->ia_valid |= ATTR_MODE;
313 } 313 }
314 if (bmval[1] & FATTR4_WORD1_OWNER) { 314 if (bmval[1] & FATTR4_WORD1_OWNER) {
315 READ_BUF(4); 315 READ_BUF(4);
316 len += 4; 316 len += 4;
317 READ32(dummy32); 317 READ32(dummy32);
318 READ_BUF(dummy32); 318 READ_BUF(dummy32);
319 len += (XDR_QUADLEN(dummy32) << 2); 319 len += (XDR_QUADLEN(dummy32) << 2);
320 READMEM(buf, dummy32); 320 READMEM(buf, dummy32);
321 if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) 321 if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
322 return status; 322 return status;
323 iattr->ia_valid |= ATTR_UID; 323 iattr->ia_valid |= ATTR_UID;
324 } 324 }
325 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { 325 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
326 READ_BUF(4); 326 READ_BUF(4);
327 len += 4; 327 len += 4;
328 READ32(dummy32); 328 READ32(dummy32);
329 READ_BUF(dummy32); 329 READ_BUF(dummy32);
330 len += (XDR_QUADLEN(dummy32) << 2); 330 len += (XDR_QUADLEN(dummy32) << 2);
331 READMEM(buf, dummy32); 331 READMEM(buf, dummy32);
332 if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) 332 if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
333 return status; 333 return status;
334 iattr->ia_valid |= ATTR_GID; 334 iattr->ia_valid |= ATTR_GID;
335 } 335 }
336 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { 336 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
337 READ_BUF(4); 337 READ_BUF(4);
338 len += 4; 338 len += 4;
339 READ32(dummy32); 339 READ32(dummy32);
340 switch (dummy32) { 340 switch (dummy32) {
341 case NFS4_SET_TO_CLIENT_TIME: 341 case NFS4_SET_TO_CLIENT_TIME:
342 /* We require the high 32 bits of 'seconds' to be 0, and we ignore 342 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
343 all 32 bits of 'nseconds'. */ 343 all 32 bits of 'nseconds'. */
344 READ_BUF(12); 344 READ_BUF(12);
345 len += 12; 345 len += 12;
346 READ32(dummy32); 346 READ32(dummy32);
347 if (dummy32) 347 if (dummy32)
348 return nfserr_inval; 348 return nfserr_inval;
349 READ32(iattr->ia_atime.tv_sec); 349 READ32(iattr->ia_atime.tv_sec);
350 READ32(iattr->ia_atime.tv_nsec); 350 READ32(iattr->ia_atime.tv_nsec);
351 if (iattr->ia_atime.tv_nsec >= (u32)1000000000) 351 if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
352 return nfserr_inval; 352 return nfserr_inval;
353 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); 353 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
354 break; 354 break;
355 case NFS4_SET_TO_SERVER_TIME: 355 case NFS4_SET_TO_SERVER_TIME:
356 iattr->ia_valid |= ATTR_ATIME; 356 iattr->ia_valid |= ATTR_ATIME;
357 break; 357 break;
358 default: 358 default:
359 goto xdr_error; 359 goto xdr_error;
360 } 360 }
361 } 361 }
362 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { 362 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
363 READ_BUF(4); 363 READ_BUF(4);
364 len += 4; 364 len += 4;
365 READ32(dummy32); 365 READ32(dummy32);
366 switch (dummy32) { 366 switch (dummy32) {
367 case NFS4_SET_TO_CLIENT_TIME: 367 case NFS4_SET_TO_CLIENT_TIME:
368 /* We require the high 32 bits of 'seconds' to be 0, and we ignore 368 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
369 all 32 bits of 'nseconds'. */ 369 all 32 bits of 'nseconds'. */
370 READ_BUF(12); 370 READ_BUF(12);
371 len += 12; 371 len += 12;
372 READ32(dummy32); 372 READ32(dummy32);
373 if (dummy32) 373 if (dummy32)
374 return nfserr_inval; 374 return nfserr_inval;
375 READ32(iattr->ia_mtime.tv_sec); 375 READ32(iattr->ia_mtime.tv_sec);
376 READ32(iattr->ia_mtime.tv_nsec); 376 READ32(iattr->ia_mtime.tv_nsec);
377 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000) 377 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
378 return nfserr_inval; 378 return nfserr_inval;
379 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); 379 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
380 break; 380 break;
381 case NFS4_SET_TO_SERVER_TIME: 381 case NFS4_SET_TO_SERVER_TIME:
382 iattr->ia_valid |= ATTR_MTIME; 382 iattr->ia_valid |= ATTR_MTIME;
383 break; 383 break;
384 default: 384 default:
385 goto xdr_error; 385 goto xdr_error;
386 } 386 }
387 } 387 }
388 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0 388 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
389 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1 389 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
390 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) 390 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
391 READ_BUF(expected_len - len); 391 READ_BUF(expected_len - len);
392 else if (len != expected_len) 392 else if (len != expected_len)
393 goto xdr_error; 393 goto xdr_error;
394 394
395 DECODE_TAIL; 395 DECODE_TAIL;
396 396
397 out_nfserr: 397 out_nfserr:
398 status = nfserrno(host_err); 398 status = nfserrno(host_err);
399 goto out; 399 goto out;
400 } 400 }
401 401
402 static __be32 402 static __be32
403 nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid) 403 nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
404 { 404 {
405 DECODE_HEAD; 405 DECODE_HEAD;
406 406
407 READ_BUF(sizeof(stateid_t)); 407 READ_BUF(sizeof(stateid_t));
408 READ32(sid->si_generation); 408 READ32(sid->si_generation);
409 COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); 409 COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
410 410
411 DECODE_TAIL; 411 DECODE_TAIL;
412 } 412 }
413 413
414 static __be32 414 static __be32
415 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) 415 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
416 { 416 {
417 DECODE_HEAD; 417 DECODE_HEAD;
418 418
419 READ_BUF(4); 419 READ_BUF(4);
420 READ32(access->ac_req_access); 420 READ32(access->ac_req_access);
421 421
422 DECODE_TAIL; 422 DECODE_TAIL;
423 } 423 }
424 424
425 static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) 425 static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
426 { 426 {
427 DECODE_HEAD; 427 DECODE_HEAD;
428 428
429 READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); 429 READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
430 COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); 430 COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
431 READ32(bcts->dir); 431 READ32(bcts->dir);
432 /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker 432 /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker
433 * could help us figure out we should be using it. */ 433 * could help us figure out we should be using it. */
434 DECODE_TAIL; 434 DECODE_TAIL;
435 } 435 }
436 436
437 static __be32 437 static __be32
438 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) 438 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
439 { 439 {
440 DECODE_HEAD; 440 DECODE_HEAD;
441 441
442 READ_BUF(4); 442 READ_BUF(4);
443 READ32(close->cl_seqid); 443 READ32(close->cl_seqid);
444 return nfsd4_decode_stateid(argp, &close->cl_stateid); 444 return nfsd4_decode_stateid(argp, &close->cl_stateid);
445 445
446 DECODE_TAIL; 446 DECODE_TAIL;
447 } 447 }
448 448
449 449
450 static __be32 450 static __be32
451 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) 451 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
452 { 452 {
453 DECODE_HEAD; 453 DECODE_HEAD;
454 454
455 READ_BUF(12); 455 READ_BUF(12);
456 READ64(commit->co_offset); 456 READ64(commit->co_offset);
457 READ32(commit->co_count); 457 READ32(commit->co_count);
458 458
459 DECODE_TAIL; 459 DECODE_TAIL;
460 } 460 }
461 461
462 static __be32 462 static __be32
463 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) 463 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
464 { 464 {
465 DECODE_HEAD; 465 DECODE_HEAD;
466 466
467 READ_BUF(4); 467 READ_BUF(4);
468 READ32(create->cr_type); 468 READ32(create->cr_type);
469 switch (create->cr_type) { 469 switch (create->cr_type) {
470 case NF4LNK: 470 case NF4LNK:
471 READ_BUF(4); 471 READ_BUF(4);
472 READ32(create->cr_linklen); 472 READ32(create->cr_linklen);
473 READ_BUF(create->cr_linklen); 473 READ_BUF(create->cr_linklen);
474 SAVEMEM(create->cr_linkname, create->cr_linklen); 474 SAVEMEM(create->cr_linkname, create->cr_linklen);
475 break; 475 break;
476 case NF4BLK: 476 case NF4BLK:
477 case NF4CHR: 477 case NF4CHR:
478 READ_BUF(8); 478 READ_BUF(8);
479 READ32(create->cr_specdata1); 479 READ32(create->cr_specdata1);
480 READ32(create->cr_specdata2); 480 READ32(create->cr_specdata2);
481 break; 481 break;
482 case NF4SOCK: 482 case NF4SOCK:
483 case NF4FIFO: 483 case NF4FIFO:
484 case NF4DIR: 484 case NF4DIR:
485 default: 485 default:
486 break; 486 break;
487 } 487 }
488 488
489 READ_BUF(4); 489 READ_BUF(4);
490 READ32(create->cr_namelen); 490 READ32(create->cr_namelen);
491 READ_BUF(create->cr_namelen); 491 READ_BUF(create->cr_namelen);
492 SAVEMEM(create->cr_name, create->cr_namelen); 492 SAVEMEM(create->cr_name, create->cr_namelen);
493 if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval))) 493 if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
494 return status; 494 return status;
495 495
496 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, 496 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
497 &create->cr_acl); 497 &create->cr_acl);
498 if (status) 498 if (status)
499 goto out; 499 goto out;
500 500
501 DECODE_TAIL; 501 DECODE_TAIL;
502 } 502 }
503 503
504 static inline __be32 504 static inline __be32
505 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) 505 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
506 { 506 {
507 return nfsd4_decode_stateid(argp, &dr->dr_stateid); 507 return nfsd4_decode_stateid(argp, &dr->dr_stateid);
508 } 508 }
509 509
510 static inline __be32 510 static inline __be32
511 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) 511 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
512 { 512 {
513 return nfsd4_decode_bitmap(argp, getattr->ga_bmval); 513 return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
514 } 514 }
515 515
516 static __be32 516 static __be32
517 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) 517 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
518 { 518 {
519 DECODE_HEAD; 519 DECODE_HEAD;
520 520
521 READ_BUF(4); 521 READ_BUF(4);
522 READ32(link->li_namelen); 522 READ32(link->li_namelen);
523 READ_BUF(link->li_namelen); 523 READ_BUF(link->li_namelen);
524 SAVEMEM(link->li_name, link->li_namelen); 524 SAVEMEM(link->li_name, link->li_namelen);
525 if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval))) 525 if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval)))
526 return status; 526 return status;
527 527
528 DECODE_TAIL; 528 DECODE_TAIL;
529 } 529 }
530 530
531 static __be32 531 static __be32
532 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) 532 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
533 { 533 {
534 DECODE_HEAD; 534 DECODE_HEAD;
535 535
536 /* 536 /*
537 * type, reclaim(boolean), offset, length, new_lock_owner(boolean) 537 * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
538 */ 538 */
539 READ_BUF(28); 539 READ_BUF(28);
540 READ32(lock->lk_type); 540 READ32(lock->lk_type);
541 if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT)) 541 if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
542 goto xdr_error; 542 goto xdr_error;
543 READ32(lock->lk_reclaim); 543 READ32(lock->lk_reclaim);
544 READ64(lock->lk_offset); 544 READ64(lock->lk_offset);
545 READ64(lock->lk_length); 545 READ64(lock->lk_length);
546 READ32(lock->lk_is_new); 546 READ32(lock->lk_is_new);
547 547
548 if (lock->lk_is_new) { 548 if (lock->lk_is_new) {
549 READ_BUF(4); 549 READ_BUF(4);
550 READ32(lock->lk_new_open_seqid); 550 READ32(lock->lk_new_open_seqid);
551 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid); 551 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
552 if (status) 552 if (status)
553 return status; 553 return status;
554 READ_BUF(8 + sizeof(clientid_t)); 554 READ_BUF(8 + sizeof(clientid_t));
555 READ32(lock->lk_new_lock_seqid); 555 READ32(lock->lk_new_lock_seqid);
556 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t)); 556 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
557 READ32(lock->lk_new_owner.len); 557 READ32(lock->lk_new_owner.len);
558 READ_BUF(lock->lk_new_owner.len); 558 READ_BUF(lock->lk_new_owner.len);
559 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len); 559 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
560 } else { 560 } else {
561 status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid); 561 status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
562 if (status) 562 if (status)
563 return status; 563 return status;
564 READ_BUF(4); 564 READ_BUF(4);
565 READ32(lock->lk_old_lock_seqid); 565 READ32(lock->lk_old_lock_seqid);
566 } 566 }
567 567
568 DECODE_TAIL; 568 DECODE_TAIL;
569 } 569 }
570 570
571 static __be32 571 static __be32
572 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) 572 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
573 { 573 {
574 DECODE_HEAD; 574 DECODE_HEAD;
575 575
576 READ_BUF(32); 576 READ_BUF(32);
577 READ32(lockt->lt_type); 577 READ32(lockt->lt_type);
578 if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT)) 578 if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
579 goto xdr_error; 579 goto xdr_error;
580 READ64(lockt->lt_offset); 580 READ64(lockt->lt_offset);
581 READ64(lockt->lt_length); 581 READ64(lockt->lt_length);
582 COPYMEM(&lockt->lt_clientid, 8); 582 COPYMEM(&lockt->lt_clientid, 8);
583 READ32(lockt->lt_owner.len); 583 READ32(lockt->lt_owner.len);
584 READ_BUF(lockt->lt_owner.len); 584 READ_BUF(lockt->lt_owner.len);
585 READMEM(lockt->lt_owner.data, lockt->lt_owner.len); 585 READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
586 586
587 DECODE_TAIL; 587 DECODE_TAIL;
588 } 588 }
589 589
590 static __be32 590 static __be32
591 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) 591 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
592 { 592 {
593 DECODE_HEAD; 593 DECODE_HEAD;
594 594
595 READ_BUF(8); 595 READ_BUF(8);
596 READ32(locku->lu_type); 596 READ32(locku->lu_type);
597 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) 597 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
598 goto xdr_error; 598 goto xdr_error;
599 READ32(locku->lu_seqid); 599 READ32(locku->lu_seqid);
600 status = nfsd4_decode_stateid(argp, &locku->lu_stateid); 600 status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
601 if (status) 601 if (status)
602 return status; 602 return status;
603 READ_BUF(16); 603 READ_BUF(16);
604 READ64(locku->lu_offset); 604 READ64(locku->lu_offset);
605 READ64(locku->lu_length); 605 READ64(locku->lu_length);
606 606
607 DECODE_TAIL; 607 DECODE_TAIL;
608 } 608 }
609 609
610 static __be32 610 static __be32
611 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) 611 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
612 { 612 {
613 DECODE_HEAD; 613 DECODE_HEAD;
614 614
615 READ_BUF(4); 615 READ_BUF(4);
616 READ32(lookup->lo_len); 616 READ32(lookup->lo_len);
617 READ_BUF(lookup->lo_len); 617 READ_BUF(lookup->lo_len);
618 SAVEMEM(lookup->lo_name, lookup->lo_len); 618 SAVEMEM(lookup->lo_name, lookup->lo_len);
619 if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent))) 619 if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent)))
620 return status; 620 return status;
621 621
622 DECODE_TAIL; 622 DECODE_TAIL;
623 } 623 }
624 624
625 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when) 625 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
626 { 626 {
627 __be32 *p; 627 __be32 *p;
628 u32 w; 628 u32 w;
629 629
630 READ_BUF(4); 630 READ_BUF(4);
631 READ32(w); 631 READ32(w);
632 *share_access = w & NFS4_SHARE_ACCESS_MASK; 632 *share_access = w & NFS4_SHARE_ACCESS_MASK;
633 *deleg_want = w & NFS4_SHARE_WANT_MASK; 633 *deleg_want = w & NFS4_SHARE_WANT_MASK;
634 if (deleg_when) 634 if (deleg_when)
635 *deleg_when = w & NFS4_SHARE_WHEN_MASK; 635 *deleg_when = w & NFS4_SHARE_WHEN_MASK;
636 636
637 switch (w & NFS4_SHARE_ACCESS_MASK) { 637 switch (w & NFS4_SHARE_ACCESS_MASK) {
638 case NFS4_SHARE_ACCESS_READ: 638 case NFS4_SHARE_ACCESS_READ:
639 case NFS4_SHARE_ACCESS_WRITE: 639 case NFS4_SHARE_ACCESS_WRITE:
640 case NFS4_SHARE_ACCESS_BOTH: 640 case NFS4_SHARE_ACCESS_BOTH:
641 break; 641 break;
642 default: 642 default:
643 return nfserr_bad_xdr; 643 return nfserr_bad_xdr;
644 } 644 }
645 w &= ~NFS4_SHARE_ACCESS_MASK; 645 w &= ~NFS4_SHARE_ACCESS_MASK;
646 if (!w) 646 if (!w)
647 return nfs_ok; 647 return nfs_ok;
648 if (!argp->minorversion) 648 if (!argp->minorversion)
649 return nfserr_bad_xdr; 649 return nfserr_bad_xdr;
650 switch (w & NFS4_SHARE_WANT_MASK) { 650 switch (w & NFS4_SHARE_WANT_MASK) {
651 case NFS4_SHARE_WANT_NO_PREFERENCE: 651 case NFS4_SHARE_WANT_NO_PREFERENCE:
652 case NFS4_SHARE_WANT_READ_DELEG: 652 case NFS4_SHARE_WANT_READ_DELEG:
653 case NFS4_SHARE_WANT_WRITE_DELEG: 653 case NFS4_SHARE_WANT_WRITE_DELEG:
654 case NFS4_SHARE_WANT_ANY_DELEG: 654 case NFS4_SHARE_WANT_ANY_DELEG:
655 case NFS4_SHARE_WANT_NO_DELEG: 655 case NFS4_SHARE_WANT_NO_DELEG:
656 case NFS4_SHARE_WANT_CANCEL: 656 case NFS4_SHARE_WANT_CANCEL:
657 break; 657 break;
658 default: 658 default:
659 return nfserr_bad_xdr; 659 return nfserr_bad_xdr;
660 } 660 }
661 w &= ~NFS4_SHARE_WANT_MASK; 661 w &= ~NFS4_SHARE_WANT_MASK;
662 if (!w) 662 if (!w)
663 return nfs_ok; 663 return nfs_ok;
664 664
665 if (!deleg_when) /* open_downgrade */ 665 if (!deleg_when) /* open_downgrade */
666 return nfserr_inval; 666 return nfserr_inval;
667 switch (w) { 667 switch (w) {
668 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL: 668 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
669 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED: 669 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
670 case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL | 670 case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
671 NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED): 671 NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
672 return nfs_ok; 672 return nfs_ok;
673 } 673 }
674 xdr_error: 674 xdr_error:
675 return nfserr_bad_xdr; 675 return nfserr_bad_xdr;
676 } 676 }
677 677
678 static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x) 678 static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
679 { 679 {
680 __be32 *p; 680 __be32 *p;
681 681
682 READ_BUF(4); 682 READ_BUF(4);
683 READ32(*x); 683 READ32(*x);
684 /* Note: unlinke access bits, deny bits may be zero. */ 684 /* Note: unlinke access bits, deny bits may be zero. */
685 if (*x & ~NFS4_SHARE_DENY_BOTH) 685 if (*x & ~NFS4_SHARE_DENY_BOTH)
686 return nfserr_bad_xdr; 686 return nfserr_bad_xdr;
687 return nfs_ok; 687 return nfs_ok;
688 xdr_error: 688 xdr_error:
689 return nfserr_bad_xdr; 689 return nfserr_bad_xdr;
690 } 690 }
691 691
692 static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o) 692 static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
693 { 693 {
694 __be32 *p; 694 __be32 *p;
695 695
696 READ_BUF(4); 696 READ_BUF(4);
697 READ32(o->len); 697 READ32(o->len);
698 698
699 if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT) 699 if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
700 return nfserr_bad_xdr; 700 return nfserr_bad_xdr;
701 701
702 READ_BUF(o->len); 702 READ_BUF(o->len);
703 SAVEMEM(o->data, o->len); 703 SAVEMEM(o->data, o->len);
704 return nfs_ok; 704 return nfs_ok;
705 xdr_error: 705 xdr_error:
706 return nfserr_bad_xdr; 706 return nfserr_bad_xdr;
707 } 707 }
708 708
709 static __be32 709 static __be32
710 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 710 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
711 { 711 {
712 DECODE_HEAD; 712 DECODE_HEAD;
713 u32 dummy; 713 u32 dummy;
714 714
715 memset(open->op_bmval, 0, sizeof(open->op_bmval)); 715 memset(open->op_bmval, 0, sizeof(open->op_bmval));
716 open->op_iattr.ia_valid = 0; 716 open->op_iattr.ia_valid = 0;
717 open->op_openowner = NULL; 717 open->op_openowner = NULL;
718 718
719 /* seqid, share_access, share_deny, clientid, ownerlen */ 719 /* seqid, share_access, share_deny, clientid, ownerlen */
720 READ_BUF(4); 720 READ_BUF(4);
721 READ32(open->op_seqid); 721 READ32(open->op_seqid);
722 /* decode, yet ignore deleg_when until supported */ 722 /* decode, yet ignore deleg_when until supported */
723 status = nfsd4_decode_share_access(argp, &open->op_share_access, 723 status = nfsd4_decode_share_access(argp, &open->op_share_access,
724 &open->op_deleg_want, &dummy); 724 &open->op_deleg_want, &dummy);
725 if (status) 725 if (status)
726 goto xdr_error; 726 goto xdr_error;
727 status = nfsd4_decode_share_deny(argp, &open->op_share_deny); 727 status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
728 if (status) 728 if (status)
729 goto xdr_error; 729 goto xdr_error;
730 READ_BUF(sizeof(clientid_t)); 730 READ_BUF(sizeof(clientid_t));
731 COPYMEM(&open->op_clientid, sizeof(clientid_t)); 731 COPYMEM(&open->op_clientid, sizeof(clientid_t));
732 status = nfsd4_decode_opaque(argp, &open->op_owner); 732 status = nfsd4_decode_opaque(argp, &open->op_owner);
733 if (status) 733 if (status)
734 goto xdr_error; 734 goto xdr_error;
735 READ_BUF(4); 735 READ_BUF(4);
736 READ32(open->op_create); 736 READ32(open->op_create);
737 switch (open->op_create) { 737 switch (open->op_create) {
738 case NFS4_OPEN_NOCREATE: 738 case NFS4_OPEN_NOCREATE:
739 break; 739 break;
740 case NFS4_OPEN_CREATE: 740 case NFS4_OPEN_CREATE:
741 READ_BUF(4); 741 READ_BUF(4);
742 READ32(open->op_createmode); 742 READ32(open->op_createmode);
743 switch (open->op_createmode) { 743 switch (open->op_createmode) {
744 case NFS4_CREATE_UNCHECKED: 744 case NFS4_CREATE_UNCHECKED:
745 case NFS4_CREATE_GUARDED: 745 case NFS4_CREATE_GUARDED:
746 status = nfsd4_decode_fattr(argp, open->op_bmval, 746 status = nfsd4_decode_fattr(argp, open->op_bmval,
747 &open->op_iattr, &open->op_acl); 747 &open->op_iattr, &open->op_acl);
748 if (status) 748 if (status)
749 goto out; 749 goto out;
750 break; 750 break;
751 case NFS4_CREATE_EXCLUSIVE: 751 case NFS4_CREATE_EXCLUSIVE:
752 READ_BUF(NFS4_VERIFIER_SIZE); 752 READ_BUF(NFS4_VERIFIER_SIZE);
753 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE); 753 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
754 break; 754 break;
755 case NFS4_CREATE_EXCLUSIVE4_1: 755 case NFS4_CREATE_EXCLUSIVE4_1:
756 if (argp->minorversion < 1) 756 if (argp->minorversion < 1)
757 goto xdr_error; 757 goto xdr_error;
758 READ_BUF(NFS4_VERIFIER_SIZE); 758 READ_BUF(NFS4_VERIFIER_SIZE);
759 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE); 759 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
760 status = nfsd4_decode_fattr(argp, open->op_bmval, 760 status = nfsd4_decode_fattr(argp, open->op_bmval,
761 &open->op_iattr, &open->op_acl); 761 &open->op_iattr, &open->op_acl);
762 if (status) 762 if (status)
763 goto out; 763 goto out;
764 break; 764 break;
765 default: 765 default:
766 goto xdr_error; 766 goto xdr_error;
767 } 767 }
768 break; 768 break;
769 default: 769 default:
770 goto xdr_error; 770 goto xdr_error;
771 } 771 }
772 772
773 /* open_claim */ 773 /* open_claim */
774 READ_BUF(4); 774 READ_BUF(4);
775 READ32(open->op_claim_type); 775 READ32(open->op_claim_type);
776 switch (open->op_claim_type) { 776 switch (open->op_claim_type) {
777 case NFS4_OPEN_CLAIM_NULL: 777 case NFS4_OPEN_CLAIM_NULL:
778 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 778 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
779 READ_BUF(4); 779 READ_BUF(4);
780 READ32(open->op_fname.len); 780 READ32(open->op_fname.len);
781 READ_BUF(open->op_fname.len); 781 READ_BUF(open->op_fname.len);
782 SAVEMEM(open->op_fname.data, open->op_fname.len); 782 SAVEMEM(open->op_fname.data, open->op_fname.len);
783 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 783 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
784 return status; 784 return status;
785 break; 785 break;
786 case NFS4_OPEN_CLAIM_PREVIOUS: 786 case NFS4_OPEN_CLAIM_PREVIOUS:
787 READ_BUF(4); 787 READ_BUF(4);
788 READ32(open->op_delegate_type); 788 READ32(open->op_delegate_type);
789 break; 789 break;
790 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 790 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
791 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid); 791 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
792 if (status) 792 if (status)
793 return status; 793 return status;
794 READ_BUF(4); 794 READ_BUF(4);
795 READ32(open->op_fname.len); 795 READ32(open->op_fname.len);
796 READ_BUF(open->op_fname.len); 796 READ_BUF(open->op_fname.len);
797 SAVEMEM(open->op_fname.data, open->op_fname.len); 797 SAVEMEM(open->op_fname.data, open->op_fname.len);
798 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 798 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
799 return status; 799 return status;
800 break; 800 break;
801 case NFS4_OPEN_CLAIM_FH: 801 case NFS4_OPEN_CLAIM_FH:
802 case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 802 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
803 if (argp->minorversion < 1) 803 if (argp->minorversion < 1)
804 goto xdr_error; 804 goto xdr_error;
805 /* void */ 805 /* void */
806 break; 806 break;
807 case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 807 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
808 if (argp->minorversion < 1) 808 if (argp->minorversion < 1)
809 goto xdr_error; 809 goto xdr_error;
810 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid); 810 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
811 if (status) 811 if (status)
812 return status; 812 return status;
813 break; 813 break;
814 default: 814 default:
815 goto xdr_error; 815 goto xdr_error;
816 } 816 }
817 817
818 DECODE_TAIL; 818 DECODE_TAIL;
819 } 819 }
820 820
821 static __be32 821 static __be32
822 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) 822 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
823 { 823 {
824 DECODE_HEAD; 824 DECODE_HEAD;
825 825
826 status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); 826 status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
827 if (status) 827 if (status)
828 return status; 828 return status;
829 READ_BUF(4); 829 READ_BUF(4);
830 READ32(open_conf->oc_seqid); 830 READ32(open_conf->oc_seqid);
831 831
832 DECODE_TAIL; 832 DECODE_TAIL;
833 } 833 }
834 834
835 static __be32 835 static __be32
836 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) 836 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
837 { 837 {
838 DECODE_HEAD; 838 DECODE_HEAD;
839 839
840 status = nfsd4_decode_stateid(argp, &open_down->od_stateid); 840 status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
841 if (status) 841 if (status)
842 return status; 842 return status;
843 READ_BUF(4); 843 READ_BUF(4);
844 READ32(open_down->od_seqid); 844 READ32(open_down->od_seqid);
845 status = nfsd4_decode_share_access(argp, &open_down->od_share_access, 845 status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
846 &open_down->od_deleg_want, NULL); 846 &open_down->od_deleg_want, NULL);
847 if (status) 847 if (status)
848 return status; 848 return status;
849 status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny); 849 status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
850 if (status) 850 if (status)
851 return status; 851 return status;
852 DECODE_TAIL; 852 DECODE_TAIL;
853 } 853 }
854 854
855 static __be32 855 static __be32
856 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) 856 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
857 { 857 {
858 DECODE_HEAD; 858 DECODE_HEAD;
859 859
860 READ_BUF(4); 860 READ_BUF(4);
861 READ32(putfh->pf_fhlen); 861 READ32(putfh->pf_fhlen);
862 if (putfh->pf_fhlen > NFS4_FHSIZE) 862 if (putfh->pf_fhlen > NFS4_FHSIZE)
863 goto xdr_error; 863 goto xdr_error;
864 READ_BUF(putfh->pf_fhlen); 864 READ_BUF(putfh->pf_fhlen);
865 SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen); 865 SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
866 866
867 DECODE_TAIL; 867 DECODE_TAIL;
868 } 868 }
869 869
870 static __be32 870 static __be32
871 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) 871 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
872 { 872 {
873 DECODE_HEAD; 873 DECODE_HEAD;
874 874
875 status = nfsd4_decode_stateid(argp, &read->rd_stateid); 875 status = nfsd4_decode_stateid(argp, &read->rd_stateid);
876 if (status) 876 if (status)
877 return status; 877 return status;
878 READ_BUF(12); 878 READ_BUF(12);
879 READ64(read->rd_offset); 879 READ64(read->rd_offset);
880 READ32(read->rd_length); 880 READ32(read->rd_length);
881 881
882 DECODE_TAIL; 882 DECODE_TAIL;
883 } 883 }
884 884
885 static __be32 885 static __be32
886 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) 886 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
887 { 887 {
888 DECODE_HEAD; 888 DECODE_HEAD;
889 889
890 READ_BUF(24); 890 READ_BUF(24);
891 READ64(readdir->rd_cookie); 891 READ64(readdir->rd_cookie);
892 COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data)); 892 COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
893 READ32(readdir->rd_dircount); /* just in case you needed a useless field... */ 893 READ32(readdir->rd_dircount); /* just in case you needed a useless field... */
894 READ32(readdir->rd_maxcount); 894 READ32(readdir->rd_maxcount);
895 if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval))) 895 if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
896 goto out; 896 goto out;
897 897
898 DECODE_TAIL; 898 DECODE_TAIL;
899 } 899 }
900 900
901 static __be32 901 static __be32
902 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) 902 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
903 { 903 {
904 DECODE_HEAD; 904 DECODE_HEAD;
905 905
906 READ_BUF(4); 906 READ_BUF(4);
907 READ32(remove->rm_namelen); 907 READ32(remove->rm_namelen);
908 READ_BUF(remove->rm_namelen); 908 READ_BUF(remove->rm_namelen);
909 SAVEMEM(remove->rm_name, remove->rm_namelen); 909 SAVEMEM(remove->rm_name, remove->rm_namelen);
910 if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent))) 910 if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent)))
911 return status; 911 return status;
912 912
913 DECODE_TAIL; 913 DECODE_TAIL;
914 } 914 }
915 915
916 static __be32 916 static __be32
917 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) 917 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
918 { 918 {
919 DECODE_HEAD; 919 DECODE_HEAD;
920 920
921 READ_BUF(4); 921 READ_BUF(4);
922 READ32(rename->rn_snamelen); 922 READ32(rename->rn_snamelen);
923 READ_BUF(rename->rn_snamelen + 4); 923 READ_BUF(rename->rn_snamelen + 4);
924 SAVEMEM(rename->rn_sname, rename->rn_snamelen); 924 SAVEMEM(rename->rn_sname, rename->rn_snamelen);
925 READ32(rename->rn_tnamelen); 925 READ32(rename->rn_tnamelen);
926 READ_BUF(rename->rn_tnamelen); 926 READ_BUF(rename->rn_tnamelen);
927 SAVEMEM(rename->rn_tname, rename->rn_tnamelen); 927 SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
928 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent))) 928 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent)))
929 return status; 929 return status;
930 if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval))) 930 if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval)))
931 return status; 931 return status;
932 932
933 DECODE_TAIL; 933 DECODE_TAIL;
934 } 934 }
935 935
936 static __be32 936 static __be32
937 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) 937 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
938 { 938 {
939 DECODE_HEAD; 939 DECODE_HEAD;
940 940
941 READ_BUF(sizeof(clientid_t)); 941 READ_BUF(sizeof(clientid_t));
942 COPYMEM(clientid, sizeof(clientid_t)); 942 COPYMEM(clientid, sizeof(clientid_t));
943 943
944 DECODE_TAIL; 944 DECODE_TAIL;
945 } 945 }
946 946
947 static __be32 947 static __be32
948 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, 948 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
949 struct nfsd4_secinfo *secinfo) 949 struct nfsd4_secinfo *secinfo)
950 { 950 {
951 DECODE_HEAD; 951 DECODE_HEAD;
952 952
953 READ_BUF(4); 953 READ_BUF(4);
954 READ32(secinfo->si_namelen); 954 READ32(secinfo->si_namelen);
955 READ_BUF(secinfo->si_namelen); 955 READ_BUF(secinfo->si_namelen);
956 SAVEMEM(secinfo->si_name, secinfo->si_namelen); 956 SAVEMEM(secinfo->si_name, secinfo->si_namelen);
957 status = check_filename(secinfo->si_name, secinfo->si_namelen, 957 status = check_filename(secinfo->si_name, secinfo->si_namelen,
958 nfserr_noent); 958 nfserr_noent);
959 if (status) 959 if (status)
960 return status; 960 return status;
961 DECODE_TAIL; 961 DECODE_TAIL;
962 } 962 }
963 963
964 static __be32 964 static __be32
965 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp, 965 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
966 struct nfsd4_secinfo_no_name *sin) 966 struct nfsd4_secinfo_no_name *sin)
967 { 967 {
968 DECODE_HEAD; 968 DECODE_HEAD;
969 969
970 READ_BUF(4); 970 READ_BUF(4);
971 READ32(sin->sin_style); 971 READ32(sin->sin_style);
972 DECODE_TAIL; 972 DECODE_TAIL;
973 } 973 }
974 974
975 static __be32 975 static __be32
976 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 976 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
977 { 977 {
978 __be32 status; 978 __be32 status;
979 979
980 status = nfsd4_decode_stateid(argp, &setattr->sa_stateid); 980 status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
981 if (status) 981 if (status)
982 return status; 982 return status;
983 return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr, 983 return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
984 &setattr->sa_acl); 984 &setattr->sa_acl);
985 } 985 }
986 986
987 static __be32 987 static __be32
988 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) 988 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
989 { 989 {
990 DECODE_HEAD; 990 DECODE_HEAD;
991 991
992 READ_BUF(NFS4_VERIFIER_SIZE); 992 READ_BUF(NFS4_VERIFIER_SIZE);
993 COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE); 993 COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
994 994
995 status = nfsd4_decode_opaque(argp, &setclientid->se_name); 995 status = nfsd4_decode_opaque(argp, &setclientid->se_name);
996 if (status) 996 if (status)
997 return nfserr_bad_xdr; 997 return nfserr_bad_xdr;
998 READ_BUF(8); 998 READ_BUF(8);
999 READ32(setclientid->se_callback_prog); 999 READ32(setclientid->se_callback_prog);
1000 READ32(setclientid->se_callback_netid_len); 1000 READ32(setclientid->se_callback_netid_len);
1001 1001
1002 READ_BUF(setclientid->se_callback_netid_len + 4); 1002 READ_BUF(setclientid->se_callback_netid_len + 4);
1003 SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len); 1003 SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
1004 READ32(setclientid->se_callback_addr_len); 1004 READ32(setclientid->se_callback_addr_len);
1005 1005
1006 READ_BUF(setclientid->se_callback_addr_len + 4); 1006 READ_BUF(setclientid->se_callback_addr_len + 4);
1007 SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len); 1007 SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
1008 READ32(setclientid->se_callback_ident); 1008 READ32(setclientid->se_callback_ident);
1009 1009
1010 DECODE_TAIL; 1010 DECODE_TAIL;
1011 } 1011 }
1012 1012
1013 static __be32 1013 static __be32
1014 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) 1014 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
1015 { 1015 {
1016 DECODE_HEAD; 1016 DECODE_HEAD;
1017 1017
1018 READ_BUF(8 + NFS4_VERIFIER_SIZE); 1018 READ_BUF(8 + NFS4_VERIFIER_SIZE);
1019 COPYMEM(&scd_c->sc_clientid, 8); 1019 COPYMEM(&scd_c->sc_clientid, 8);
1020 COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE); 1020 COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
1021 1021
1022 DECODE_TAIL; 1022 DECODE_TAIL;
1023 } 1023 }
1024 1024
1025 /* Also used for NVERIFY */ 1025 /* Also used for NVERIFY */
1026 static __be32 1026 static __be32
1027 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) 1027 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
1028 { 1028 {
1029 #if 0 1029 #if 0
1030 struct nfsd4_compoundargs save = { 1030 struct nfsd4_compoundargs save = {
1031 .p = argp->p, 1031 .p = argp->p,
1032 .end = argp->end, 1032 .end = argp->end,
1033 .rqstp = argp->rqstp, 1033 .rqstp = argp->rqstp,
1034 }; 1034 };
1035 u32 ve_bmval[2]; 1035 u32 ve_bmval[2];
1036 struct iattr ve_iattr; /* request */ 1036 struct iattr ve_iattr; /* request */
1037 struct nfs4_acl *ve_acl; /* request */ 1037 struct nfs4_acl *ve_acl; /* request */
1038 #endif 1038 #endif
1039 DECODE_HEAD; 1039 DECODE_HEAD;
1040 1040
1041 if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval))) 1041 if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
1042 goto out; 1042 goto out;
1043 1043
1044 /* For convenience's sake, we compare raw xdr'd attributes in 1044 /* For convenience's sake, we compare raw xdr'd attributes in
1045 * nfsd4_proc_verify; however we still decode here just to return 1045 * nfsd4_proc_verify; however we still decode here just to return
1046 * correct error in case of bad xdr. */ 1046 * correct error in case of bad xdr. */
1047 #if 0 1047 #if 0
1048 status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl); 1048 status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl);
1049 if (status == nfserr_inval) { 1049 if (status == nfserr_inval) {
1050 status = nfserrno(status); 1050 status = nfserrno(status);
1051 goto out; 1051 goto out;
1052 } 1052 }
1053 #endif 1053 #endif
1054 READ_BUF(4); 1054 READ_BUF(4);
1055 READ32(verify->ve_attrlen); 1055 READ32(verify->ve_attrlen);
1056 READ_BUF(verify->ve_attrlen); 1056 READ_BUF(verify->ve_attrlen);
1057 SAVEMEM(verify->ve_attrval, verify->ve_attrlen); 1057 SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
1058 1058
1059 DECODE_TAIL; 1059 DECODE_TAIL;
1060 } 1060 }
1061 1061
1062 static __be32 1062 static __be32
1063 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) 1063 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1064 { 1064 {
1065 int avail; 1065 int avail;
1066 int v; 1066 int v;
1067 int len; 1067 int len;
1068 DECODE_HEAD; 1068 DECODE_HEAD;
1069 1069
1070 status = nfsd4_decode_stateid(argp, &write->wr_stateid); 1070 status = nfsd4_decode_stateid(argp, &write->wr_stateid);
1071 if (status) 1071 if (status)
1072 return status; 1072 return status;
1073 READ_BUF(16); 1073 READ_BUF(16);
1074 READ64(write->wr_offset); 1074 READ64(write->wr_offset);
1075 READ32(write->wr_stable_how); 1075 READ32(write->wr_stable_how);
1076 if (write->wr_stable_how > 2) 1076 if (write->wr_stable_how > 2)
1077 goto xdr_error; 1077 goto xdr_error;
1078 READ32(write->wr_buflen); 1078 READ32(write->wr_buflen);
1079 1079
1080 /* Sorry .. no magic macros for this.. * 1080 /* Sorry .. no magic macros for this.. *
1081 * READ_BUF(write->wr_buflen); 1081 * READ_BUF(write->wr_buflen);
1082 * SAVEMEM(write->wr_buf, write->wr_buflen); 1082 * SAVEMEM(write->wr_buf, write->wr_buflen);
1083 */ 1083 */
1084 avail = (char*)argp->end - (char*)argp->p; 1084 avail = (char*)argp->end - (char*)argp->p;
1085 if (avail + argp->pagelen < write->wr_buflen) { 1085 if (avail + argp->pagelen < write->wr_buflen) {
1086 dprintk("NFSD: xdr error (%s:%d)\n", 1086 dprintk("NFSD: xdr error (%s:%d)\n",
1087 __FILE__, __LINE__); 1087 __FILE__, __LINE__);
1088 goto xdr_error; 1088 goto xdr_error;
1089 } 1089 }
1090 argp->rqstp->rq_vec[0].iov_base = p; 1090 argp->rqstp->rq_vec[0].iov_base = p;
1091 argp->rqstp->rq_vec[0].iov_len = avail; 1091 argp->rqstp->rq_vec[0].iov_len = avail;
1092 v = 0; 1092 v = 0;
1093 len = write->wr_buflen; 1093 len = write->wr_buflen;
1094 while (len > argp->rqstp->rq_vec[v].iov_len) { 1094 while (len > argp->rqstp->rq_vec[v].iov_len) {
1095 len -= argp->rqstp->rq_vec[v].iov_len; 1095 len -= argp->rqstp->rq_vec[v].iov_len;
1096 v++; 1096 v++;
1097 argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]); 1097 argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]);
1098 argp->pagelist++; 1098 argp->pagelist++;
1099 if (argp->pagelen >= PAGE_SIZE) { 1099 if (argp->pagelen >= PAGE_SIZE) {
1100 argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE; 1100 argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE;
1101 argp->pagelen -= PAGE_SIZE; 1101 argp->pagelen -= PAGE_SIZE;
1102 } else { 1102 } else {
1103 argp->rqstp->rq_vec[v].iov_len = argp->pagelen; 1103 argp->rqstp->rq_vec[v].iov_len = argp->pagelen;
1104 argp->pagelen -= len; 1104 argp->pagelen -= len;
1105 } 1105 }
1106 } 1106 }
1107 argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); 1107 argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
1108 argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); 1108 argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
1109 argp->rqstp->rq_vec[v].iov_len = len; 1109 argp->rqstp->rq_vec[v].iov_len = len;
1110 write->wr_vlen = v+1; 1110 write->wr_vlen = v+1;
1111 1111
1112 DECODE_TAIL; 1112 DECODE_TAIL;
1113 } 1113 }
1114 1114
1115 static __be32 1115 static __be32
1116 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) 1116 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1117 { 1117 {
1118 DECODE_HEAD; 1118 DECODE_HEAD;
1119 1119
1120 READ_BUF(12); 1120 READ_BUF(12);
1121 COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); 1121 COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1122 READ32(rlockowner->rl_owner.len); 1122 READ32(rlockowner->rl_owner.len);
1123 READ_BUF(rlockowner->rl_owner.len); 1123 READ_BUF(rlockowner->rl_owner.len);
1124 READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len); 1124 READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1125 1125
1126 if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid)) 1126 if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1127 return nfserr_inval; 1127 return nfserr_inval;
1128 DECODE_TAIL; 1128 DECODE_TAIL;
1129 } 1129 }
1130 1130
1131 static __be32 1131 static __be32
1132 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, 1132 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1133 struct nfsd4_exchange_id *exid) 1133 struct nfsd4_exchange_id *exid)
1134 { 1134 {
1135 int dummy, tmp; 1135 int dummy, tmp;
1136 DECODE_HEAD; 1136 DECODE_HEAD;
1137 1137
1138 READ_BUF(NFS4_VERIFIER_SIZE); 1138 READ_BUF(NFS4_VERIFIER_SIZE);
1139 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE); 1139 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
1140 1140
1141 status = nfsd4_decode_opaque(argp, &exid->clname); 1141 status = nfsd4_decode_opaque(argp, &exid->clname);
1142 if (status) 1142 if (status)
1143 return nfserr_bad_xdr; 1143 return nfserr_bad_xdr;
1144 1144
1145 READ_BUF(4); 1145 READ_BUF(4);
1146 READ32(exid->flags); 1146 READ32(exid->flags);
1147 1147
1148 /* Ignore state_protect4_a */ 1148 /* Ignore state_protect4_a */
1149 READ_BUF(4); 1149 READ_BUF(4);
1150 READ32(exid->spa_how); 1150 READ32(exid->spa_how);
1151 switch (exid->spa_how) { 1151 switch (exid->spa_how) {
1152 case SP4_NONE: 1152 case SP4_NONE:
1153 break; 1153 break;
1154 case SP4_MACH_CRED: 1154 case SP4_MACH_CRED:
1155 /* spo_must_enforce */ 1155 /* spo_must_enforce */
1156 READ_BUF(4); 1156 READ_BUF(4);
1157 READ32(dummy); 1157 READ32(dummy);
1158 READ_BUF(dummy * 4); 1158 READ_BUF(dummy * 4);
1159 p += dummy; 1159 p += dummy;
1160 1160
1161 /* spo_must_allow */ 1161 /* spo_must_allow */
1162 READ_BUF(4); 1162 READ_BUF(4);
1163 READ32(dummy); 1163 READ32(dummy);
1164 READ_BUF(dummy * 4); 1164 READ_BUF(dummy * 4);
1165 p += dummy; 1165 p += dummy;
1166 break; 1166 break;
1167 case SP4_SSV: 1167 case SP4_SSV:
1168 /* ssp_ops */ 1168 /* ssp_ops */
1169 READ_BUF(4); 1169 READ_BUF(4);
1170 READ32(dummy); 1170 READ32(dummy);
1171 READ_BUF(dummy * 4); 1171 READ_BUF(dummy * 4);
1172 p += dummy; 1172 p += dummy;
1173 1173
1174 READ_BUF(4); 1174 READ_BUF(4);
1175 READ32(dummy); 1175 READ32(dummy);
1176 READ_BUF(dummy * 4); 1176 READ_BUF(dummy * 4);
1177 p += dummy; 1177 p += dummy;
1178 1178
1179 /* ssp_hash_algs<> */ 1179 /* ssp_hash_algs<> */
1180 READ_BUF(4); 1180 READ_BUF(4);
1181 READ32(tmp); 1181 READ32(tmp);
1182 while (tmp--) { 1182 while (tmp--) {
1183 READ_BUF(4); 1183 READ_BUF(4);
1184 READ32(dummy); 1184 READ32(dummy);
1185 READ_BUF(dummy); 1185 READ_BUF(dummy);
1186 p += XDR_QUADLEN(dummy); 1186 p += XDR_QUADLEN(dummy);
1187 } 1187 }
1188 1188
1189 /* ssp_encr_algs<> */ 1189 /* ssp_encr_algs<> */
1190 READ_BUF(4); 1190 READ_BUF(4);
1191 READ32(tmp); 1191 READ32(tmp);
1192 while (tmp--) { 1192 while (tmp--) {
1193 READ_BUF(4); 1193 READ_BUF(4);
1194 READ32(dummy); 1194 READ32(dummy);
1195 READ_BUF(dummy); 1195 READ_BUF(dummy);
1196 p += XDR_QUADLEN(dummy); 1196 p += XDR_QUADLEN(dummy);
1197 } 1197 }
1198 1198
1199 /* ssp_window and ssp_num_gss_handles */ 1199 /* ssp_window and ssp_num_gss_handles */
1200 READ_BUF(8); 1200 READ_BUF(8);
1201 READ32(dummy); 1201 READ32(dummy);
1202 READ32(dummy); 1202 READ32(dummy);
1203 break; 1203 break;
1204 default: 1204 default:
1205 goto xdr_error; 1205 goto xdr_error;
1206 } 1206 }
1207 1207
1208 /* Ignore Implementation ID */ 1208 /* Ignore Implementation ID */
1209 READ_BUF(4); /* nfs_impl_id4 array length */ 1209 READ_BUF(4); /* nfs_impl_id4 array length */
1210 READ32(dummy); 1210 READ32(dummy);
1211 1211
1212 if (dummy > 1) 1212 if (dummy > 1)
1213 goto xdr_error; 1213 goto xdr_error;
1214 1214
1215 if (dummy == 1) { 1215 if (dummy == 1) {
1216 /* nii_domain */ 1216 /* nii_domain */
1217 READ_BUF(4); 1217 READ_BUF(4);
1218 READ32(dummy); 1218 READ32(dummy);
1219 READ_BUF(dummy); 1219 READ_BUF(dummy);
1220 p += XDR_QUADLEN(dummy); 1220 p += XDR_QUADLEN(dummy);
1221 1221
1222 /* nii_name */ 1222 /* nii_name */
1223 READ_BUF(4); 1223 READ_BUF(4);
1224 READ32(dummy); 1224 READ32(dummy);
1225 READ_BUF(dummy); 1225 READ_BUF(dummy);
1226 p += XDR_QUADLEN(dummy); 1226 p += XDR_QUADLEN(dummy);
1227 1227
1228 /* nii_date */ 1228 /* nii_date */
1229 READ_BUF(12); 1229 READ_BUF(12);
1230 p += 3; 1230 p += 3;
1231 } 1231 }
1232 DECODE_TAIL; 1232 DECODE_TAIL;
1233 } 1233 }
1234 1234
1235 static __be32 1235 static __be32
1236 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, 1236 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1237 struct nfsd4_create_session *sess) 1237 struct nfsd4_create_session *sess)
1238 { 1238 {
1239 DECODE_HEAD; 1239 DECODE_HEAD;
1240 1240
1241 u32 dummy; 1241 u32 dummy;
1242 char *machine_name; 1242 char *machine_name;
1243 int i; 1243 int i;
1244 int nr_secflavs; 1244 int nr_secflavs;
1245 1245
1246 READ_BUF(16); 1246 READ_BUF(16);
1247 COPYMEM(&sess->clientid, 8); 1247 COPYMEM(&sess->clientid, 8);
1248 READ32(sess->seqid); 1248 READ32(sess->seqid);
1249 READ32(sess->flags); 1249 READ32(sess->flags);
1250 1250
1251 /* Fore channel attrs */ 1251 /* Fore channel attrs */
1252 READ_BUF(28); 1252 READ_BUF(28);
1253 READ32(dummy); /* headerpadsz is always 0 */ 1253 READ32(dummy); /* headerpadsz is always 0 */
1254 READ32(sess->fore_channel.maxreq_sz); 1254 READ32(sess->fore_channel.maxreq_sz);
1255 READ32(sess->fore_channel.maxresp_sz); 1255 READ32(sess->fore_channel.maxresp_sz);
1256 READ32(sess->fore_channel.maxresp_cached); 1256 READ32(sess->fore_channel.maxresp_cached);
1257 READ32(sess->fore_channel.maxops); 1257 READ32(sess->fore_channel.maxops);
1258 READ32(sess->fore_channel.maxreqs); 1258 READ32(sess->fore_channel.maxreqs);
1259 READ32(sess->fore_channel.nr_rdma_attrs); 1259 READ32(sess->fore_channel.nr_rdma_attrs);
1260 if (sess->fore_channel.nr_rdma_attrs == 1) { 1260 if (sess->fore_channel.nr_rdma_attrs == 1) {
1261 READ_BUF(4); 1261 READ_BUF(4);
1262 READ32(sess->fore_channel.rdma_attrs); 1262 READ32(sess->fore_channel.rdma_attrs);
1263 } else if (sess->fore_channel.nr_rdma_attrs > 1) { 1263 } else if (sess->fore_channel.nr_rdma_attrs > 1) {
1264 dprintk("Too many fore channel attr bitmaps!\n"); 1264 dprintk("Too many fore channel attr bitmaps!\n");
1265 goto xdr_error; 1265 goto xdr_error;
1266 } 1266 }
1267 1267
1268 /* Back channel attrs */ 1268 /* Back channel attrs */
1269 READ_BUF(28); 1269 READ_BUF(28);
1270 READ32(dummy); /* headerpadsz is always 0 */ 1270 READ32(dummy); /* headerpadsz is always 0 */
1271 READ32(sess->back_channel.maxreq_sz); 1271 READ32(sess->back_channel.maxreq_sz);
1272 READ32(sess->back_channel.maxresp_sz); 1272 READ32(sess->back_channel.maxresp_sz);
1273 READ32(sess->back_channel.maxresp_cached); 1273 READ32(sess->back_channel.maxresp_cached);
1274 READ32(sess->back_channel.maxops); 1274 READ32(sess->back_channel.maxops);
1275 READ32(sess->back_channel.maxreqs); 1275 READ32(sess->back_channel.maxreqs);
1276 READ32(sess->back_channel.nr_rdma_attrs); 1276 READ32(sess->back_channel.nr_rdma_attrs);
1277 if (sess->back_channel.nr_rdma_attrs == 1) { 1277 if (sess->back_channel.nr_rdma_attrs == 1) {
1278 READ_BUF(4); 1278 READ_BUF(4);
1279 READ32(sess->back_channel.rdma_attrs); 1279 READ32(sess->back_channel.rdma_attrs);
1280 } else if (sess->back_channel.nr_rdma_attrs > 1) { 1280 } else if (sess->back_channel.nr_rdma_attrs > 1) {
1281 dprintk("Too many back channel attr bitmaps!\n"); 1281 dprintk("Too many back channel attr bitmaps!\n");
1282 goto xdr_error; 1282 goto xdr_error;
1283 } 1283 }
1284 1284
1285 READ_BUF(8); 1285 READ_BUF(8);
1286 READ32(sess->callback_prog); 1286 READ32(sess->callback_prog);
1287 1287
1288 /* callback_sec_params4 */ 1288 /* callback_sec_params4 */
1289 READ32(nr_secflavs); 1289 READ32(nr_secflavs);
1290 for (i = 0; i < nr_secflavs; ++i) { 1290 for (i = 0; i < nr_secflavs; ++i) {
1291 READ_BUF(4); 1291 READ_BUF(4);
1292 READ32(dummy); 1292 READ32(dummy);
1293 switch (dummy) { 1293 switch (dummy) {
1294 case RPC_AUTH_NULL: 1294 case RPC_AUTH_NULL:
1295 /* Nothing to read */ 1295 /* Nothing to read */
1296 break; 1296 break;
1297 case RPC_AUTH_UNIX: 1297 case RPC_AUTH_UNIX:
1298 READ_BUF(8); 1298 READ_BUF(8);
1299 /* stamp */ 1299 /* stamp */
1300 READ32(dummy); 1300 READ32(dummy);
1301 1301
1302 /* machine name */ 1302 /* machine name */
1303 READ32(dummy); 1303 READ32(dummy);
1304 READ_BUF(dummy); 1304 READ_BUF(dummy);
1305 SAVEMEM(machine_name, dummy); 1305 SAVEMEM(machine_name, dummy);
1306 1306
1307 /* uid, gid */ 1307 /* uid, gid */
1308 READ_BUF(8); 1308 READ_BUF(8);
1309 READ32(sess->uid); 1309 READ32(sess->uid);
1310 READ32(sess->gid); 1310 READ32(sess->gid);
1311 1311
1312 /* more gids */ 1312 /* more gids */
1313 READ_BUF(4); 1313 READ_BUF(4);
1314 READ32(dummy); 1314 READ32(dummy);
1315 READ_BUF(dummy * 4); 1315 READ_BUF(dummy * 4);
1316 break; 1316 break;
1317 case RPC_AUTH_GSS: 1317 case RPC_AUTH_GSS:
1318 dprintk("RPC_AUTH_GSS callback secflavor " 1318 dprintk("RPC_AUTH_GSS callback secflavor "
1319 "not supported!\n"); 1319 "not supported!\n");
1320 READ_BUF(8); 1320 READ_BUF(8);
1321 /* gcbp_service */ 1321 /* gcbp_service */
1322 READ32(dummy); 1322 READ32(dummy);
1323 /* gcbp_handle_from_server */ 1323 /* gcbp_handle_from_server */
1324 READ32(dummy); 1324 READ32(dummy);
1325 READ_BUF(dummy); 1325 READ_BUF(dummy);
1326 p += XDR_QUADLEN(dummy); 1326 p += XDR_QUADLEN(dummy);
1327 /* gcbp_handle_from_client */ 1327 /* gcbp_handle_from_client */
1328 READ_BUF(4); 1328 READ_BUF(4);
1329 READ32(dummy); 1329 READ32(dummy);
1330 READ_BUF(dummy); 1330 READ_BUF(dummy);
1331 break; 1331 break;
1332 default: 1332 default:
1333 dprintk("Illegal callback secflavor\n"); 1333 dprintk("Illegal callback secflavor\n");
1334 return nfserr_inval; 1334 return nfserr_inval;
1335 } 1335 }
1336 } 1336 }
1337 DECODE_TAIL; 1337 DECODE_TAIL;
1338 } 1338 }
1339 1339
1340 static __be32 1340 static __be32
1341 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp, 1341 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1342 struct nfsd4_destroy_session *destroy_session) 1342 struct nfsd4_destroy_session *destroy_session)
1343 { 1343 {
1344 DECODE_HEAD; 1344 DECODE_HEAD;
1345 READ_BUF(NFS4_MAX_SESSIONID_LEN); 1345 READ_BUF(NFS4_MAX_SESSIONID_LEN);
1346 COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN); 1346 COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1347 1347
1348 DECODE_TAIL; 1348 DECODE_TAIL;
1349 } 1349 }
1350 1350
1351 static __be32 1351 static __be32
1352 nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp, 1352 nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1353 struct nfsd4_free_stateid *free_stateid) 1353 struct nfsd4_free_stateid *free_stateid)
1354 { 1354 {
1355 DECODE_HEAD; 1355 DECODE_HEAD;
1356 1356
1357 READ_BUF(sizeof(stateid_t)); 1357 READ_BUF(sizeof(stateid_t));
1358 READ32(free_stateid->fr_stateid.si_generation); 1358 READ32(free_stateid->fr_stateid.si_generation);
1359 COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t)); 1359 COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
1360 1360
1361 DECODE_TAIL; 1361 DECODE_TAIL;
1362 } 1362 }
1363 1363
1364 static __be32 1364 static __be32
1365 nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, 1365 nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1366 struct nfsd4_sequence *seq) 1366 struct nfsd4_sequence *seq)
1367 { 1367 {
1368 DECODE_HEAD; 1368 DECODE_HEAD;
1369 1369
1370 READ_BUF(NFS4_MAX_SESSIONID_LEN + 16); 1370 READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
1371 COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 1371 COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1372 READ32(seq->seqid); 1372 READ32(seq->seqid);
1373 READ32(seq->slotid); 1373 READ32(seq->slotid);
1374 READ32(seq->maxslots); 1374 READ32(seq->maxslots);
1375 READ32(seq->cachethis); 1375 READ32(seq->cachethis);
1376 1376
1377 DECODE_TAIL; 1377 DECODE_TAIL;
1378 } 1378 }
1379 1379
1380 static __be32 1380 static __be32
1381 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid) 1381 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1382 { 1382 {
1383 int i; 1383 int i;
1384 __be32 *p, status; 1384 __be32 *p, status;
1385 struct nfsd4_test_stateid_id *stateid; 1385 struct nfsd4_test_stateid_id *stateid;
1386 1386
1387 READ_BUF(4); 1387 READ_BUF(4);
1388 test_stateid->ts_num_ids = ntohl(*p++); 1388 test_stateid->ts_num_ids = ntohl(*p++);
1389 1389
1390 INIT_LIST_HEAD(&test_stateid->ts_stateid_list); 1390 INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
1391 1391
1392 for (i = 0; i < test_stateid->ts_num_ids; i++) { 1392 for (i = 0; i < test_stateid->ts_num_ids; i++) {
1393 stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL); 1393 stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
1394 if (!stateid) { 1394 if (!stateid) {
1395 status = PTR_ERR(stateid); 1395 status = PTR_ERR(stateid);
1396 goto out; 1396 goto out;
1397 } 1397 }
1398 1398
1399 defer_free(argp, kfree, stateid); 1399 defer_free(argp, kfree, stateid);
1400 INIT_LIST_HEAD(&stateid->ts_id_list); 1400 INIT_LIST_HEAD(&stateid->ts_id_list);
1401 list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list); 1401 list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
1402 1402
1403 status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid); 1403 status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
1404 if (status) 1404 if (status)
1405 goto out; 1405 goto out;
1406 } 1406 }
1407 1407
1408 status = 0; 1408 status = 0;
1409 out: 1409 out:
1410 return status; 1410 return status;
1411 xdr_error: 1411 xdr_error:
1412 dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__); 1412 dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
1413 status = nfserr_bad_xdr; 1413 status = nfserr_bad_xdr;
1414 goto out; 1414 goto out;
1415 } 1415 }
1416 1416
1417 static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc) 1417 static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
1418 { 1418 {
1419 DECODE_HEAD; 1419 DECODE_HEAD;
1420 1420
1421 READ_BUF(8); 1421 READ_BUF(8);
1422 COPYMEM(&dc->clientid, 8); 1422 COPYMEM(&dc->clientid, 8);
1423 1423
1424 DECODE_TAIL; 1424 DECODE_TAIL;
1425 } 1425 }
1426 1426
1427 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) 1427 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
1428 { 1428 {
1429 DECODE_HEAD; 1429 DECODE_HEAD;
1430 1430
1431 READ_BUF(4); 1431 READ_BUF(4);
1432 READ32(rc->rca_one_fs); 1432 READ32(rc->rca_one_fs);
1433 1433
1434 DECODE_TAIL; 1434 DECODE_TAIL;
1435 } 1435 }
1436 1436
1437 static __be32 1437 static __be32
1438 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) 1438 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
1439 { 1439 {
1440 return nfs_ok; 1440 return nfs_ok;
1441 } 1441 }
1442 1442
1443 static __be32 1443 static __be32
1444 nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) 1444 nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
1445 { 1445 {
1446 return nfserr_notsupp; 1446 return nfserr_notsupp;
1447 } 1447 }
1448 1448
1449 typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); 1449 typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
1450 1450
1451 static nfsd4_dec nfsd4_dec_ops[] = { 1451 static nfsd4_dec nfsd4_dec_ops[] = {
1452 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, 1452 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
1453 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, 1453 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
1454 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, 1454 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
1455 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, 1455 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
1456 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, 1456 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
1457 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, 1457 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
1458 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, 1458 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
1459 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, 1459 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
1460 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, 1460 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
1461 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, 1461 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
1462 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, 1462 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
1463 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, 1463 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
1464 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, 1464 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
1465 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, 1465 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
1466 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, 1466 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
1467 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, 1467 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
1468 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, 1468 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
1469 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, 1469 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
1470 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, 1470 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
1471 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, 1471 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
1472 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop, 1472 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop,
1473 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, 1473 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
1474 [OP_READ] = (nfsd4_dec)nfsd4_decode_read, 1474 [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
1475 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, 1475 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
1476 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, 1476 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
1477 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, 1477 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
1478 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, 1478 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
1479 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew, 1479 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew,
1480 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, 1480 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
1481 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, 1481 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
1482 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, 1482 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
1483 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, 1483 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
1484 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid, 1484 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid,
1485 [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm, 1485 [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
1486 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, 1486 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
1487 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, 1487 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
1488 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, 1488 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
1489 }; 1489 };
1490 1490
1491 static nfsd4_dec nfsd41_dec_ops[] = { 1491 static nfsd4_dec nfsd41_dec_ops[] = {
1492 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, 1492 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
1493 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, 1493 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
1494 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, 1494 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
1495 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, 1495 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
1496 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, 1496 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
1497 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, 1497 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
1498 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, 1498 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
1499 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, 1499 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
1500 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, 1500 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
1501 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, 1501 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
1502 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, 1502 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
1503 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, 1503 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
1504 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, 1504 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
1505 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, 1505 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
1506 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, 1506 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
1507 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, 1507 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
1508 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, 1508 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
1509 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp, 1509 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp,
1510 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, 1510 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
1511 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, 1511 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
1512 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp, 1512 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp,
1513 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, 1513 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
1514 [OP_READ] = (nfsd4_dec)nfsd4_decode_read, 1514 [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
1515 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, 1515 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
1516 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, 1516 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
1517 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, 1517 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
1518 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, 1518 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
1519 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp, 1519 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp,
1520 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, 1520 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
1521 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, 1521 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
1522 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, 1522 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
1523 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, 1523 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
1524 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, 1524 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp,
1525 [OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp, 1525 [OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp,
1526 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, 1526 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
1527 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, 1527 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
1528 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp, 1528 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,
1529 1529
1530 /* new operations for NFSv4.1 */ 1530 /* new operations for NFSv4.1 */
1531 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, 1531 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp,
1532 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, 1532 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1533 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, 1533 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
1534 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, 1534 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
1535 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, 1535 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session,
1536 [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid, 1536 [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid,
1537 [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, 1537 [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
1538 [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp, 1538 [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp,
1539 [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp, 1539 [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp,
1540 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, 1540 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
1541 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, 1541 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
1542 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, 1542 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
1543 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name, 1543 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1544 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, 1544 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
1545 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, 1545 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
1546 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, 1546 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid,
1547 [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, 1547 [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
1548 [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid, 1548 [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid,
1549 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, 1549 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
1550 }; 1550 };
1551 1551
1552 struct nfsd4_minorversion_ops { 1552 struct nfsd4_minorversion_ops {
1553 nfsd4_dec *decoders; 1553 nfsd4_dec *decoders;
1554 int nops; 1554 int nops;
1555 }; 1555 };
1556 1556
1557 static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { 1557 static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
1558 [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, 1558 [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
1559 [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, 1559 [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
1560 }; 1560 };
1561 1561
1562 static __be32 1562 static __be32
1563 nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 1563 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1564 { 1564 {
1565 DECODE_HEAD; 1565 DECODE_HEAD;
1566 struct nfsd4_op *op; 1566 struct nfsd4_op *op;
1567 struct nfsd4_minorversion_ops *ops; 1567 struct nfsd4_minorversion_ops *ops;
1568 bool cachethis = false; 1568 bool cachethis = false;
1569 int i; 1569 int i;
1570 1570
1571 /* 1571 /*
1572 * XXX: According to spec, we should check the tag 1572 * XXX: According to spec, we should check the tag
1573 * for UTF-8 compliance. I'm postponing this for 1573 * for UTF-8 compliance. I'm postponing this for
1574 * now because it seems that some clients do use 1574 * now because it seems that some clients do use
1575 * binary tags. 1575 * binary tags.
1576 */ 1576 */
1577 READ_BUF(4); 1577 READ_BUF(4);
1578 READ32(argp->taglen); 1578 READ32(argp->taglen);
1579 READ_BUF(argp->taglen + 8); 1579 READ_BUF(argp->taglen + 8);
1580 SAVEMEM(argp->tag, argp->taglen); 1580 SAVEMEM(argp->tag, argp->taglen);
1581 READ32(argp->minorversion); 1581 READ32(argp->minorversion);
1582 READ32(argp->opcnt); 1582 READ32(argp->opcnt);
1583 1583
1584 if (argp->taglen > NFSD4_MAX_TAGLEN) 1584 if (argp->taglen > NFSD4_MAX_TAGLEN)
1585 goto xdr_error; 1585 goto xdr_error;
1586 if (argp->opcnt > 100) 1586 if (argp->opcnt > 100)
1587 goto xdr_error; 1587 goto xdr_error;
1588 1588
1589 if (argp->opcnt > ARRAY_SIZE(argp->iops)) { 1589 if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
1590 argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL); 1590 argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
1591 if (!argp->ops) { 1591 if (!argp->ops) {
1592 argp->ops = argp->iops; 1592 argp->ops = argp->iops;
1593 dprintk("nfsd: couldn't allocate room for COMPOUND\n"); 1593 dprintk("nfsd: couldn't allocate room for COMPOUND\n");
1594 goto xdr_error; 1594 goto xdr_error;
1595 } 1595 }
1596 } 1596 }
1597 1597
1598 if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion)) 1598 if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion))
1599 argp->opcnt = 0; 1599 argp->opcnt = 0;
1600 1600
1601 ops = &nfsd4_minorversion[argp->minorversion]; 1601 ops = &nfsd4_minorversion[argp->minorversion];
1602 for (i = 0; i < argp->opcnt; i++) { 1602 for (i = 0; i < argp->opcnt; i++) {
1603 op = &argp->ops[i]; 1603 op = &argp->ops[i];
1604 op->replay = NULL; 1604 op->replay = NULL;
1605 1605
1606 /* 1606 /*
1607 * We can't use READ_BUF() here because we need to handle 1607 * We can't use READ_BUF() here because we need to handle
1608 * a missing opcode as an OP_WRITE + 1. So we need to check 1608 * a missing opcode as an OP_WRITE + 1. So we need to check
1609 * to see if we're truly at the end of our buffer or if there 1609 * to see if we're truly at the end of our buffer or if there
1610 * is another page we need to flip to. 1610 * is another page we need to flip to.
1611 */ 1611 */
1612 1612
1613 if (argp->p == argp->end) { 1613 if (argp->p == argp->end) {
1614 if (argp->pagelen < 4) { 1614 if (argp->pagelen < 4) {
1615 /* There isn't an opcode still on the wire */ 1615 /* There isn't an opcode still on the wire */
1616 op->opnum = OP_WRITE + 1; 1616 op->opnum = OP_WRITE + 1;
1617 op->status = nfserr_bad_xdr; 1617 op->status = nfserr_bad_xdr;
1618 argp->opcnt = i+1; 1618 argp->opcnt = i+1;
1619 break; 1619 break;
1620 } 1620 }
1621 1621
1622 /* 1622 /*
1623 * False alarm. We just hit a page boundary, but there 1623 * False alarm. We just hit a page boundary, but there
1624 * is still data available. Move pointer across page 1624 * is still data available. Move pointer across page
1625 * boundary. *snip from READ_BUF* 1625 * boundary. *snip from READ_BUF*
1626 */ 1626 */
1627 argp->p = page_address(argp->pagelist[0]); 1627 argp->p = page_address(argp->pagelist[0]);
1628 argp->pagelist++; 1628 argp->pagelist++;
1629 if (argp->pagelen < PAGE_SIZE) { 1629 if (argp->pagelen < PAGE_SIZE) {
1630 argp->end = argp->p + (argp->pagelen>>2); 1630 argp->end = argp->p + (argp->pagelen>>2);
1631 argp->pagelen = 0; 1631 argp->pagelen = 0;
1632 } else { 1632 } else {
1633 argp->end = argp->p + (PAGE_SIZE>>2); 1633 argp->end = argp->p + (PAGE_SIZE>>2);
1634 argp->pagelen -= PAGE_SIZE; 1634 argp->pagelen -= PAGE_SIZE;
1635 } 1635 }
1636 } 1636 }
1637 op->opnum = ntohl(*argp->p++); 1637 op->opnum = ntohl(*argp->p++);
1638 1638
1639 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP) 1639 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1640 op->status = ops->decoders[op->opnum](argp, &op->u); 1640 op->status = ops->decoders[op->opnum](argp, &op->u);
1641 else { 1641 else {
1642 op->opnum = OP_ILLEGAL; 1642 op->opnum = OP_ILLEGAL;
1643 op->status = nfserr_op_illegal; 1643 op->status = nfserr_op_illegal;
1644 } 1644 }
1645 1645
1646 if (op->status) { 1646 if (op->status) {
1647 argp->opcnt = i+1; 1647 argp->opcnt = i+1;
1648 break; 1648 break;
1649 } 1649 }
1650 /* 1650 /*
1651 * We'll try to cache the result in the DRC if any one 1651 * We'll try to cache the result in the DRC if any one
1652 * op in the compound wants to be cached: 1652 * op in the compound wants to be cached:
1653 */ 1653 */
1654 cachethis |= nfsd4_cache_this_op(op); 1654 cachethis |= nfsd4_cache_this_op(op);
1655 } 1655 }
1656 /* Sessions make the DRC unnecessary: */ 1656 /* Sessions make the DRC unnecessary: */
1657 if (argp->minorversion) 1657 if (argp->minorversion)
1658 cachethis = false; 1658 cachethis = false;
1659 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; 1659 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
1660 1660
1661 DECODE_TAIL; 1661 DECODE_TAIL;
1662 } 1662 }
1663 1663
1664 #define WRITE32(n) *p++ = htonl(n) 1664 #define WRITE32(n) *p++ = htonl(n)
1665 #define WRITE64(n) do { \ 1665 #define WRITE64(n) do { \
1666 *p++ = htonl((u32)((n) >> 32)); \ 1666 *p++ = htonl((u32)((n) >> 32)); \
1667 *p++ = htonl((u32)(n)); \ 1667 *p++ = htonl((u32)(n)); \
1668 } while (0) 1668 } while (0)
1669 #define WRITEMEM(ptr,nbytes) do { if (nbytes > 0) { \ 1669 #define WRITEMEM(ptr,nbytes) do { if (nbytes > 0) { \
1670 *(p + XDR_QUADLEN(nbytes) -1) = 0; \ 1670 *(p + XDR_QUADLEN(nbytes) -1) = 0; \
1671 memcpy(p, ptr, nbytes); \ 1671 memcpy(p, ptr, nbytes); \
1672 p += XDR_QUADLEN(nbytes); \ 1672 p += XDR_QUADLEN(nbytes); \
1673 }} while (0) 1673 }} while (0)
1674 1674
1675 static void write32(__be32 **p, u32 n) 1675 static void write32(__be32 **p, u32 n)
1676 { 1676 {
1677 *(*p)++ = n; 1677 *(*p)++ = n;
1678 } 1678 }
1679 1679
1680 static void write64(__be32 **p, u64 n) 1680 static void write64(__be32 **p, u64 n)
1681 { 1681 {
1682 write32(p, (u32)(n >> 32)); 1682 write32(p, (u32)(n >> 32));
1683 write32(p, (u32)n); 1683 write32(p, (u32)n);
1684 } 1684 }
1685 1685
1686 static void write_change(__be32 **p, struct kstat *stat, struct inode *inode) 1686 static void write_change(__be32 **p, struct kstat *stat, struct inode *inode)
1687 { 1687 {
1688 if (IS_I_VERSION(inode)) { 1688 if (IS_I_VERSION(inode)) {
1689 write64(p, inode->i_version); 1689 write64(p, inode->i_version);
1690 } else { 1690 } else {
1691 write32(p, stat->ctime.tv_sec); 1691 write32(p, stat->ctime.tv_sec);
1692 write32(p, stat->ctime.tv_nsec); 1692 write32(p, stat->ctime.tv_nsec);
1693 } 1693 }
1694 } 1694 }
1695 1695
1696 static void write_cinfo(__be32 **p, struct nfsd4_change_info *c) 1696 static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
1697 { 1697 {
1698 write32(p, c->atomic); 1698 write32(p, c->atomic);
1699 if (c->change_supported) { 1699 if (c->change_supported) {
1700 write64(p, c->before_change); 1700 write64(p, c->before_change);
1701 write64(p, c->after_change); 1701 write64(p, c->after_change);
1702 } else { 1702 } else {
1703 write32(p, c->before_ctime_sec); 1703 write32(p, c->before_ctime_sec);
1704 write32(p, c->before_ctime_nsec); 1704 write32(p, c->before_ctime_nsec);
1705 write32(p, c->after_ctime_sec); 1705 write32(p, c->after_ctime_sec);
1706 write32(p, c->after_ctime_nsec); 1706 write32(p, c->after_ctime_nsec);
1707 } 1707 }
1708 } 1708 }
1709 1709
1710 #define RESERVE_SPACE(nbytes) do { \ 1710 #define RESERVE_SPACE(nbytes) do { \
1711 p = resp->p; \ 1711 p = resp->p; \
1712 BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end); \ 1712 BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end); \
1713 } while (0) 1713 } while (0)
1714 #define ADJUST_ARGS() resp->p = p 1714 #define ADJUST_ARGS() resp->p = p
1715 1715
1716 /* 1716 /*
1717 * Header routine to setup seqid operation replay cache 1717 * Header routine to setup seqid operation replay cache
1718 */ 1718 */
1719 #define ENCODE_SEQID_OP_HEAD \ 1719 #define ENCODE_SEQID_OP_HEAD \
1720 __be32 *save; \ 1720 __be32 *save; \
1721 \ 1721 \
1722 save = resp->p; 1722 save = resp->p;
1723 1723
1724 /* 1724 /*
1725 * Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This 1725 * Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This
1726 * is where sequence id's are incremented, and the replay cache is filled. 1726 * is where sequence id's are incremented, and the replay cache is filled.
1727 * Note that we increment sequence id's here, at the last moment, so we're sure 1727 * Note that we increment sequence id's here, at the last moment, so we're sure
1728 * we know whether the error to be returned is a sequence id mutating error. 1728 * we know whether the error to be returned is a sequence id mutating error.
1729 */ 1729 */
1730 1730
1731 static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, __be32 nfserr) 1731 static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, __be32 nfserr)
1732 { 1732 {
1733 struct nfs4_stateowner *stateowner = resp->cstate.replay_owner; 1733 struct nfs4_stateowner *stateowner = resp->cstate.replay_owner;
1734 1734
1735 if (seqid_mutating_err(ntohl(nfserr)) && stateowner) { 1735 if (seqid_mutating_err(ntohl(nfserr)) && stateowner) {
1736 stateowner->so_seqid++; 1736 stateowner->so_seqid++;
1737 stateowner->so_replay.rp_status = nfserr; 1737 stateowner->so_replay.rp_status = nfserr;
1738 stateowner->so_replay.rp_buflen = 1738 stateowner->so_replay.rp_buflen =
1739 (char *)resp->p - (char *)save; 1739 (char *)resp->p - (char *)save;
1740 memcpy(stateowner->so_replay.rp_buf, save, 1740 memcpy(stateowner->so_replay.rp_buf, save,
1741 stateowner->so_replay.rp_buflen); 1741 stateowner->so_replay.rp_buflen);
1742 nfsd4_purge_closed_stateid(stateowner); 1742 nfsd4_purge_closed_stateid(stateowner);
1743 } 1743 }
1744 } 1744 }
1745 1745
1746 /* Encode as an array of strings the string given with components 1746 /* Encode as an array of strings the string given with components
1747 * separated @sep. 1747 * separated @sep.
1748 */ 1748 */
1749 static __be32 nfsd4_encode_components(char sep, char *components, 1749 static __be32 nfsd4_encode_components(char sep, char *components,
1750 __be32 **pp, int *buflen) 1750 __be32 **pp, int *buflen)
1751 { 1751 {
1752 __be32 *p = *pp; 1752 __be32 *p = *pp;
1753 __be32 *countp = p; 1753 __be32 *countp = p;
1754 int strlen, count=0; 1754 int strlen, count=0;
1755 char *str, *end; 1755 char *str, *end;
1756 1756
1757 dprintk("nfsd4_encode_components(%s)\n", components); 1757 dprintk("nfsd4_encode_components(%s)\n", components);
1758 if ((*buflen -= 4) < 0) 1758 if ((*buflen -= 4) < 0)
1759 return nfserr_resource; 1759 return nfserr_resource;
1760 WRITE32(0); /* We will fill this in with @count later */ 1760 WRITE32(0); /* We will fill this in with @count later */
1761 end = str = components; 1761 end = str = components;
1762 while (*end) { 1762 while (*end) {
1763 for (; *end && (*end != sep); end++) 1763 for (; *end && (*end != sep); end++)
1764 ; /* Point to end of component */ 1764 ; /* Point to end of component */
1765 strlen = end - str; 1765 strlen = end - str;
1766 if (strlen) { 1766 if (strlen) {
1767 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) 1767 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
1768 return nfserr_resource; 1768 return nfserr_resource;
1769 WRITE32(strlen); 1769 WRITE32(strlen);
1770 WRITEMEM(str, strlen); 1770 WRITEMEM(str, strlen);
1771 count++; 1771 count++;
1772 } 1772 }
1773 else 1773 else
1774 end++; 1774 end++;
1775 str = end; 1775 str = end;
1776 } 1776 }
1777 *pp = p; 1777 *pp = p;
1778 p = countp; 1778 p = countp;
1779 WRITE32(count); 1779 WRITE32(count);
1780 return 0; 1780 return 0;
1781 } 1781 }
1782 1782
1783 /* 1783 /*
1784 * encode a location element of a fs_locations structure 1784 * encode a location element of a fs_locations structure
1785 */ 1785 */
1786 static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, 1786 static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1787 __be32 **pp, int *buflen) 1787 __be32 **pp, int *buflen)
1788 { 1788 {
1789 __be32 status; 1789 __be32 status;
1790 __be32 *p = *pp; 1790 __be32 *p = *pp;
1791 1791
1792 status = nfsd4_encode_components(':', location->hosts, &p, buflen); 1792 status = nfsd4_encode_components(':', location->hosts, &p, buflen);
1793 if (status) 1793 if (status)
1794 return status; 1794 return status;
1795 status = nfsd4_encode_components('/', location->path, &p, buflen); 1795 status = nfsd4_encode_components('/', location->path, &p, buflen);
1796 if (status) 1796 if (status)
1797 return status; 1797 return status;
1798 *pp = p; 1798 *pp = p;
1799 return 0; 1799 return 0;
1800 } 1800 }
1801 1801
1802 /* 1802 /*
1803 * Encode a path in RFC3530 'pathname4' format 1803 * Encode a path in RFC3530 'pathname4' format
1804 */ 1804 */
1805 static __be32 nfsd4_encode_path(const struct path *root, 1805 static __be32 nfsd4_encode_path(const struct path *root,
1806 const struct path *path, __be32 **pp, int *buflen) 1806 const struct path *path, __be32 **pp, int *buflen)
1807 { 1807 {
1808 struct path cur = { 1808 struct path cur = {
1809 .mnt = path->mnt, 1809 .mnt = path->mnt,
1810 .dentry = path->dentry, 1810 .dentry = path->dentry,
1811 }; 1811 };
1812 __be32 *p = *pp; 1812 __be32 *p = *pp;
1813 struct dentry **components = NULL; 1813 struct dentry **components = NULL;
1814 unsigned int ncomponents = 0; 1814 unsigned int ncomponents = 0;
1815 __be32 err = nfserr_jukebox; 1815 __be32 err = nfserr_jukebox;
1816 1816
1817 dprintk("nfsd4_encode_components("); 1817 dprintk("nfsd4_encode_components(");
1818 1818
1819 path_get(&cur); 1819 path_get(&cur);
1820 /* First walk the path up to the nfsd root, and store the 1820 /* First walk the path up to the nfsd root, and store the
1821 * dentries/path components in an array. 1821 * dentries/path components in an array.
1822 */ 1822 */
1823 for (;;) { 1823 for (;;) {
1824 if (cur.dentry == root->dentry && cur.mnt == root->mnt) 1824 if (cur.dentry == root->dentry && cur.mnt == root->mnt)
1825 break; 1825 break;
1826 if (cur.dentry == cur.mnt->mnt_root) { 1826 if (cur.dentry == cur.mnt->mnt_root) {
1827 if (follow_up(&cur)) 1827 if (follow_up(&cur))
1828 continue; 1828 continue;
1829 goto out_free; 1829 goto out_free;
1830 } 1830 }
1831 if ((ncomponents & 15) == 0) { 1831 if ((ncomponents & 15) == 0) {
1832 struct dentry **new; 1832 struct dentry **new;
1833 new = krealloc(components, 1833 new = krealloc(components,
1834 sizeof(*new) * (ncomponents + 16), 1834 sizeof(*new) * (ncomponents + 16),
1835 GFP_KERNEL); 1835 GFP_KERNEL);
1836 if (!new) 1836 if (!new)
1837 goto out_free; 1837 goto out_free;
1838 components = new; 1838 components = new;
1839 } 1839 }
1840 components[ncomponents++] = cur.dentry; 1840 components[ncomponents++] = cur.dentry;
1841 cur.dentry = dget_parent(cur.dentry); 1841 cur.dentry = dget_parent(cur.dentry);
1842 } 1842 }
1843 1843
1844 *buflen -= 4; 1844 *buflen -= 4;
1845 if (*buflen < 0) 1845 if (*buflen < 0)
1846 goto out_free; 1846 goto out_free;
1847 WRITE32(ncomponents); 1847 WRITE32(ncomponents);
1848 1848
1849 while (ncomponents) { 1849 while (ncomponents) {
1850 struct dentry *dentry = components[ncomponents - 1]; 1850 struct dentry *dentry = components[ncomponents - 1];
1851 unsigned int len = dentry->d_name.len; 1851 unsigned int len = dentry->d_name.len;
1852 1852
1853 *buflen -= 4 + (XDR_QUADLEN(len) << 2); 1853 *buflen -= 4 + (XDR_QUADLEN(len) << 2);
1854 if (*buflen < 0) 1854 if (*buflen < 0)
1855 goto out_free; 1855 goto out_free;
1856 WRITE32(len); 1856 WRITE32(len);
1857 WRITEMEM(dentry->d_name.name, len); 1857 WRITEMEM(dentry->d_name.name, len);
1858 dprintk("/%s", dentry->d_name.name); 1858 dprintk("/%s", dentry->d_name.name);
1859 dput(dentry); 1859 dput(dentry);
1860 ncomponents--; 1860 ncomponents--;
1861 } 1861 }
1862 1862
1863 *pp = p; 1863 *pp = p;
1864 err = 0; 1864 err = 0;
1865 out_free: 1865 out_free:
1866 dprintk(")\n"); 1866 dprintk(")\n");
1867 while (ncomponents) 1867 while (ncomponents)
1868 dput(components[--ncomponents]); 1868 dput(components[--ncomponents]);
1869 kfree(components); 1869 kfree(components);
1870 path_put(&cur); 1870 path_put(&cur);
1871 return err; 1871 return err;
1872 } 1872 }
1873 1873
1874 static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp, 1874 static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp,
1875 const struct path *path, __be32 **pp, int *buflen) 1875 const struct path *path, __be32 **pp, int *buflen)
1876 { 1876 {
1877 struct svc_export *exp_ps; 1877 struct svc_export *exp_ps;
1878 __be32 res; 1878 __be32 res;
1879 1879
1880 exp_ps = rqst_find_fsidzero_export(rqstp); 1880 exp_ps = rqst_find_fsidzero_export(rqstp);
1881 if (IS_ERR(exp_ps)) 1881 if (IS_ERR(exp_ps))
1882 return nfserrno(PTR_ERR(exp_ps)); 1882 return nfserrno(PTR_ERR(exp_ps));
1883 res = nfsd4_encode_path(&exp_ps->ex_path, path, pp, buflen); 1883 res = nfsd4_encode_path(&exp_ps->ex_path, path, pp, buflen);
1884 exp_put(exp_ps); 1884 exp_put(exp_ps);
1885 return res; 1885 return res;
1886 } 1886 }
1887 1887
1888 /* 1888 /*
1889 * encode a fs_locations structure 1889 * encode a fs_locations structure
1890 */ 1890 */
1891 static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp, 1891 static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1892 struct svc_export *exp, 1892 struct svc_export *exp,
1893 __be32 **pp, int *buflen) 1893 __be32 **pp, int *buflen)
1894 { 1894 {
1895 __be32 status; 1895 __be32 status;
1896 int i; 1896 int i;
1897 __be32 *p = *pp; 1897 __be32 *p = *pp;
1898 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs; 1898 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1899 1899
1900 status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->ex_path, &p, buflen); 1900 status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->ex_path, &p, buflen);
1901 if (status) 1901 if (status)
1902 return status; 1902 return status;
1903 if ((*buflen -= 4) < 0) 1903 if ((*buflen -= 4) < 0)
1904 return nfserr_resource; 1904 return nfserr_resource;
1905 WRITE32(fslocs->locations_count); 1905 WRITE32(fslocs->locations_count);
1906 for (i=0; i<fslocs->locations_count; i++) { 1906 for (i=0; i<fslocs->locations_count; i++) {
1907 status = nfsd4_encode_fs_location4(&fslocs->locations[i], 1907 status = nfsd4_encode_fs_location4(&fslocs->locations[i],
1908 &p, buflen); 1908 &p, buflen);
1909 if (status) 1909 if (status)
1910 return status; 1910 return status;
1911 } 1911 }
1912 *pp = p; 1912 *pp = p;
1913 return 0; 1913 return 0;
1914 } 1914 }
1915 1915
1916 static u32 nfs4_file_type(umode_t mode) 1916 static u32 nfs4_file_type(umode_t mode)
1917 { 1917 {
1918 switch (mode & S_IFMT) { 1918 switch (mode & S_IFMT) {
1919 case S_IFIFO: return NF4FIFO; 1919 case S_IFIFO: return NF4FIFO;
1920 case S_IFCHR: return NF4CHR; 1920 case S_IFCHR: return NF4CHR;
1921 case S_IFDIR: return NF4DIR; 1921 case S_IFDIR: return NF4DIR;
1922 case S_IFBLK: return NF4BLK; 1922 case S_IFBLK: return NF4BLK;
1923 case S_IFLNK: return NF4LNK; 1923 case S_IFLNK: return NF4LNK;
1924 case S_IFREG: return NF4REG; 1924 case S_IFREG: return NF4REG;
1925 case S_IFSOCK: return NF4SOCK; 1925 case S_IFSOCK: return NF4SOCK;
1926 default: return NF4BAD; 1926 default: return NF4BAD;
1927 }; 1927 };
1928 } 1928 }
1929 1929
1930 static __be32 1930 static __be32
1931 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1931 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1932 __be32 **p, int *buflen) 1932 __be32 **p, int *buflen)
1933 { 1933 {
1934 int status; 1934 int status;
1935 1935
1936 if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4) 1936 if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
1937 return nfserr_resource; 1937 return nfserr_resource;
1938 if (whotype != NFS4_ACL_WHO_NAMED) 1938 if (whotype != NFS4_ACL_WHO_NAMED)
1939 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1)); 1939 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
1940 else if (group) 1940 else if (group)
1941 status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1)); 1941 status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
1942 else 1942 else
1943 status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1)); 1943 status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
1944 if (status < 0) 1944 if (status < 0)
1945 return nfserrno(status); 1945 return nfserrno(status);
1946 *p = xdr_encode_opaque(*p, NULL, status); 1946 *p = xdr_encode_opaque(*p, NULL, status);
1947 *buflen -= (XDR_QUADLEN(status) << 2) + 4; 1947 *buflen -= (XDR_QUADLEN(status) << 2) + 4;
1948 BUG_ON(*buflen < 0); 1948 BUG_ON(*buflen < 0);
1949 return 0; 1949 return 0;
1950 } 1950 }
1951 1951
1952 static inline __be32 1952 static inline __be32
1953 nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) 1953 nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
1954 { 1954 {
1955 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); 1955 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
1956 } 1956 }
1957 1957
1958 static inline __be32 1958 static inline __be32
1959 nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) 1959 nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
1960 { 1960 {
1961 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); 1961 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
1962 } 1962 }
1963 1963
1964 static inline __be32 1964 static inline __be32
1965 nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1965 nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1966 __be32 **p, int *buflen) 1966 __be32 **p, int *buflen)
1967 { 1967 {
1968 return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); 1968 return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
1969 } 1969 }
1970 1970
1971 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ 1971 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
1972 FATTR4_WORD0_RDATTR_ERROR) 1972 FATTR4_WORD0_RDATTR_ERROR)
1973 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID 1973 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
1974 1974
1975 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) 1975 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
1976 { 1976 {
1977 /* As per referral draft: */ 1977 /* As per referral draft: */
1978 if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS || 1978 if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
1979 *bmval1 & ~WORD1_ABSENT_FS_ATTRS) { 1979 *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
1980 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR || 1980 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
1981 *bmval0 & FATTR4_WORD0_FS_LOCATIONS) 1981 *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
1982 *rdattr_err = NFSERR_MOVED; 1982 *rdattr_err = NFSERR_MOVED;
1983 else 1983 else
1984 return nfserr_moved; 1984 return nfserr_moved;
1985 } 1985 }
1986 *bmval0 &= WORD0_ABSENT_FS_ATTRS; 1986 *bmval0 &= WORD0_ABSENT_FS_ATTRS;
1987 *bmval1 &= WORD1_ABSENT_FS_ATTRS; 1987 *bmval1 &= WORD1_ABSENT_FS_ATTRS;
1988 return 0; 1988 return 0;
1989 } 1989 }
1990 1990
1991 /* 1991 /*
1992 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle 1992 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
1993 * ourselves. 1993 * ourselves.
1994 * 1994 *
1995 * @countp is the buffer size in _words_; upon successful return this becomes 1995 * @countp is the buffer size in _words_; upon successful return this becomes
1996 * replaced with the number of words written. 1996 * replaced with the number of words written.
1997 */ 1997 */
1998 __be32 1998 __be32
1999 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 1999 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2000 struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, 2000 struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval,
2001 struct svc_rqst *rqstp, int ignore_crossmnt) 2001 struct svc_rqst *rqstp, int ignore_crossmnt)
2002 { 2002 {
2003 u32 bmval0 = bmval[0]; 2003 u32 bmval0 = bmval[0];
2004 u32 bmval1 = bmval[1]; 2004 u32 bmval1 = bmval[1];
2005 u32 bmval2 = bmval[2]; 2005 u32 bmval2 = bmval[2];
2006 struct kstat stat; 2006 struct kstat stat;
2007 struct svc_fh tempfh; 2007 struct svc_fh tempfh;
2008 struct kstatfs statfs; 2008 struct kstatfs statfs;
2009 int buflen = *countp << 2; 2009 int buflen = *countp << 2;
2010 __be32 *attrlenp; 2010 __be32 *attrlenp;
2011 u32 dummy; 2011 u32 dummy;
2012 u64 dummy64; 2012 u64 dummy64;
2013 u32 rdattr_err = 0; 2013 u32 rdattr_err = 0;
2014 __be32 *p = buffer; 2014 __be32 *p = buffer;
2015 __be32 status; 2015 __be32 status;
2016 int err; 2016 int err;
2017 int aclsupport = 0; 2017 int aclsupport = 0;
2018 struct nfs4_acl *acl = NULL; 2018 struct nfs4_acl *acl = NULL;
2019 struct nfsd4_compoundres *resp = rqstp->rq_resp; 2019 struct nfsd4_compoundres *resp = rqstp->rq_resp;
2020 u32 minorversion = resp->cstate.minorversion; 2020 u32 minorversion = resp->cstate.minorversion;
2021 struct path path = { 2021 struct path path = {
2022 .mnt = exp->ex_path.mnt, 2022 .mnt = exp->ex_path.mnt,
2023 .dentry = dentry, 2023 .dentry = dentry,
2024 }; 2024 };
2025 2025
2026 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); 2026 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2027 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); 2027 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
2028 BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion)); 2028 BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
2029 BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion)); 2029 BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
2030 2030
2031 if (exp->ex_fslocs.migrated) { 2031 if (exp->ex_fslocs.migrated) {
2032 BUG_ON(bmval[2]); 2032 BUG_ON(bmval[2]);
2033 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err); 2033 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
2034 if (status) 2034 if (status)
2035 goto out; 2035 goto out;
2036 } 2036 }
2037 2037
2038 err = vfs_getattr(exp->ex_path.mnt, dentry, &stat); 2038 err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
2039 if (err) 2039 if (err)
2040 goto out_nfserr; 2040 goto out_nfserr;
2041 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | 2041 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
2042 FATTR4_WORD0_MAXNAME)) || 2042 FATTR4_WORD0_MAXNAME)) ||
2043 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | 2043 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2044 FATTR4_WORD1_SPACE_TOTAL))) { 2044 FATTR4_WORD1_SPACE_TOTAL))) {
2045 err = vfs_statfs(&path, &statfs); 2045 err = vfs_statfs(&path, &statfs);
2046 if (err) 2046 if (err)
2047 goto out_nfserr; 2047 goto out_nfserr;
2048 } 2048 }
2049 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { 2049 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2050 fh_init(&tempfh, NFS4_FHSIZE); 2050 fh_init(&tempfh, NFS4_FHSIZE);
2051 status = fh_compose(&tempfh, exp, dentry, NULL); 2051 status = fh_compose(&tempfh, exp, dentry, NULL);
2052 if (status) 2052 if (status)
2053 goto out; 2053 goto out;
2054 fhp = &tempfh; 2054 fhp = &tempfh;
2055 } 2055 }
2056 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT 2056 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
2057 | FATTR4_WORD0_SUPPORTED_ATTRS)) { 2057 | FATTR4_WORD0_SUPPORTED_ATTRS)) {
2058 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); 2058 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2059 aclsupport = (err == 0); 2059 aclsupport = (err == 0);
2060 if (bmval0 & FATTR4_WORD0_ACL) { 2060 if (bmval0 & FATTR4_WORD0_ACL) {
2061 if (err == -EOPNOTSUPP) 2061 if (err == -EOPNOTSUPP)
2062 bmval0 &= ~FATTR4_WORD0_ACL; 2062 bmval0 &= ~FATTR4_WORD0_ACL;
2063 else if (err == -EINVAL) { 2063 else if (err == -EINVAL) {
2064 status = nfserr_attrnotsupp; 2064 status = nfserr_attrnotsupp;
2065 goto out; 2065 goto out;
2066 } else if (err != 0) 2066 } else if (err != 0)
2067 goto out_nfserr; 2067 goto out_nfserr;
2068 } 2068 }
2069 } 2069 }
2070 2070
2071 if (bmval2) { 2071 if (bmval2) {
2072 if ((buflen -= 16) < 0) 2072 if ((buflen -= 16) < 0)
2073 goto out_resource; 2073 goto out_resource;
2074 WRITE32(3); 2074 WRITE32(3);
2075 WRITE32(bmval0); 2075 WRITE32(bmval0);
2076 WRITE32(bmval1); 2076 WRITE32(bmval1);
2077 WRITE32(bmval2); 2077 WRITE32(bmval2);
2078 } else if (bmval1) { 2078 } else if (bmval1) {
2079 if ((buflen -= 12) < 0) 2079 if ((buflen -= 12) < 0)
2080 goto out_resource; 2080 goto out_resource;
2081 WRITE32(2); 2081 WRITE32(2);
2082 WRITE32(bmval0); 2082 WRITE32(bmval0);
2083 WRITE32(bmval1); 2083 WRITE32(bmval1);
2084 } else { 2084 } else {
2085 if ((buflen -= 8) < 0) 2085 if ((buflen -= 8) < 0)
2086 goto out_resource; 2086 goto out_resource;
2087 WRITE32(1); 2087 WRITE32(1);
2088 WRITE32(bmval0); 2088 WRITE32(bmval0);
2089 } 2089 }
2090 attrlenp = p++; /* to be backfilled later */ 2090 attrlenp = p++; /* to be backfilled later */
2091 2091
2092 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { 2092 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2093 u32 word0 = nfsd_suppattrs0(minorversion); 2093 u32 word0 = nfsd_suppattrs0(minorversion);
2094 u32 word1 = nfsd_suppattrs1(minorversion); 2094 u32 word1 = nfsd_suppattrs1(minorversion);
2095 u32 word2 = nfsd_suppattrs2(minorversion); 2095 u32 word2 = nfsd_suppattrs2(minorversion);
2096 2096
2097 if (!aclsupport) 2097 if (!aclsupport)
2098 word0 &= ~FATTR4_WORD0_ACL; 2098 word0 &= ~FATTR4_WORD0_ACL;
2099 if (!word2) { 2099 if (!word2) {
2100 if ((buflen -= 12) < 0) 2100 if ((buflen -= 12) < 0)
2101 goto out_resource; 2101 goto out_resource;
2102 WRITE32(2); 2102 WRITE32(2);
2103 WRITE32(word0); 2103 WRITE32(word0);
2104 WRITE32(word1); 2104 WRITE32(word1);
2105 } else { 2105 } else {
2106 if ((buflen -= 16) < 0) 2106 if ((buflen -= 16) < 0)
2107 goto out_resource; 2107 goto out_resource;
2108 WRITE32(3); 2108 WRITE32(3);
2109 WRITE32(word0); 2109 WRITE32(word0);
2110 WRITE32(word1); 2110 WRITE32(word1);
2111 WRITE32(word2); 2111 WRITE32(word2);
2112 } 2112 }
2113 } 2113 }
2114 if (bmval0 & FATTR4_WORD0_TYPE) { 2114 if (bmval0 & FATTR4_WORD0_TYPE) {
2115 if ((buflen -= 4) < 0) 2115 if ((buflen -= 4) < 0)
2116 goto out_resource; 2116 goto out_resource;
2117 dummy = nfs4_file_type(stat.mode); 2117 dummy = nfs4_file_type(stat.mode);
2118 if (dummy == NF4BAD) 2118 if (dummy == NF4BAD)
2119 goto out_serverfault; 2119 goto out_serverfault;
2120 WRITE32(dummy); 2120 WRITE32(dummy);
2121 } 2121 }
2122 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) { 2122 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2123 if ((buflen -= 4) < 0) 2123 if ((buflen -= 4) < 0)
2124 goto out_resource; 2124 goto out_resource;
2125 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) 2125 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2126 WRITE32(NFS4_FH_PERSISTENT); 2126 WRITE32(NFS4_FH_PERSISTENT);
2127 else 2127 else
2128 WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME); 2128 WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
2129 } 2129 }
2130 if (bmval0 & FATTR4_WORD0_CHANGE) { 2130 if (bmval0 & FATTR4_WORD0_CHANGE) {
2131 if ((buflen -= 8) < 0) 2131 if ((buflen -= 8) < 0)
2132 goto out_resource; 2132 goto out_resource;
2133 write_change(&p, &stat, dentry->d_inode); 2133 write_change(&p, &stat, dentry->d_inode);
2134 } 2134 }
2135 if (bmval0 & FATTR4_WORD0_SIZE) { 2135 if (bmval0 & FATTR4_WORD0_SIZE) {
2136 if ((buflen -= 8) < 0) 2136 if ((buflen -= 8) < 0)
2137 goto out_resource; 2137 goto out_resource;
2138 WRITE64(stat.size); 2138 WRITE64(stat.size);
2139 } 2139 }
2140 if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) { 2140 if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2141 if ((buflen -= 4) < 0) 2141 if ((buflen -= 4) < 0)
2142 goto out_resource; 2142 goto out_resource;
2143 WRITE32(1); 2143 WRITE32(1);
2144 } 2144 }
2145 if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) { 2145 if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
2146 if ((buflen -= 4) < 0) 2146 if ((buflen -= 4) < 0)
2147 goto out_resource; 2147 goto out_resource;
2148 WRITE32(1); 2148 WRITE32(1);
2149 } 2149 }
2150 if (bmval0 & FATTR4_WORD0_NAMED_ATTR) { 2150 if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
2151 if ((buflen -= 4) < 0) 2151 if ((buflen -= 4) < 0)
2152 goto out_resource; 2152 goto out_resource;
2153 WRITE32(0); 2153 WRITE32(0);
2154 } 2154 }
2155 if (bmval0 & FATTR4_WORD0_FSID) { 2155 if (bmval0 & FATTR4_WORD0_FSID) {
2156 if ((buflen -= 16) < 0) 2156 if ((buflen -= 16) < 0)
2157 goto out_resource; 2157 goto out_resource;
2158 if (exp->ex_fslocs.migrated) { 2158 if (exp->ex_fslocs.migrated) {
2159 WRITE64(NFS4_REFERRAL_FSID_MAJOR); 2159 WRITE64(NFS4_REFERRAL_FSID_MAJOR);
2160 WRITE64(NFS4_REFERRAL_FSID_MINOR); 2160 WRITE64(NFS4_REFERRAL_FSID_MINOR);
2161 } else switch(fsid_source(fhp)) { 2161 } else switch(fsid_source(fhp)) {
2162 case FSIDSOURCE_FSID: 2162 case FSIDSOURCE_FSID:
2163 WRITE64((u64)exp->ex_fsid); 2163 WRITE64((u64)exp->ex_fsid);
2164 WRITE64((u64)0); 2164 WRITE64((u64)0);
2165 break; 2165 break;
2166 case FSIDSOURCE_DEV: 2166 case FSIDSOURCE_DEV:
2167 WRITE32(0); 2167 WRITE32(0);
2168 WRITE32(MAJOR(stat.dev)); 2168 WRITE32(MAJOR(stat.dev));
2169 WRITE32(0); 2169 WRITE32(0);
2170 WRITE32(MINOR(stat.dev)); 2170 WRITE32(MINOR(stat.dev));
2171 break; 2171 break;
2172 case FSIDSOURCE_UUID: 2172 case FSIDSOURCE_UUID:
2173 WRITEMEM(exp->ex_uuid, 16); 2173 WRITEMEM(exp->ex_uuid, 16);
2174 break; 2174 break;
2175 } 2175 }
2176 } 2176 }
2177 if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) { 2177 if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2178 if ((buflen -= 4) < 0) 2178 if ((buflen -= 4) < 0)
2179 goto out_resource; 2179 goto out_resource;
2180 WRITE32(0); 2180 WRITE32(0);
2181 } 2181 }
2182 if (bmval0 & FATTR4_WORD0_LEASE_TIME) { 2182 if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2183 if ((buflen -= 4) < 0) 2183 if ((buflen -= 4) < 0)
2184 goto out_resource; 2184 goto out_resource;
2185 WRITE32(nfsd4_lease); 2185 WRITE32(nfsd4_lease);
2186 } 2186 }
2187 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { 2187 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2188 if ((buflen -= 4) < 0) 2188 if ((buflen -= 4) < 0)
2189 goto out_resource; 2189 goto out_resource;
2190 WRITE32(rdattr_err); 2190 WRITE32(rdattr_err);
2191 } 2191 }
2192 if (bmval0 & FATTR4_WORD0_ACL) { 2192 if (bmval0 & FATTR4_WORD0_ACL) {
2193 struct nfs4_ace *ace; 2193 struct nfs4_ace *ace;
2194 2194
2195 if (acl == NULL) { 2195 if (acl == NULL) {
2196 if ((buflen -= 4) < 0) 2196 if ((buflen -= 4) < 0)
2197 goto out_resource; 2197 goto out_resource;
2198 2198
2199 WRITE32(0); 2199 WRITE32(0);
2200 goto out_acl; 2200 goto out_acl;
2201 } 2201 }
2202 if ((buflen -= 4) < 0) 2202 if ((buflen -= 4) < 0)
2203 goto out_resource; 2203 goto out_resource;
2204 WRITE32(acl->naces); 2204 WRITE32(acl->naces);
2205 2205
2206 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { 2206 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2207 if ((buflen -= 4*3) < 0) 2207 if ((buflen -= 4*3) < 0)
2208 goto out_resource; 2208 goto out_resource;
2209 WRITE32(ace->type); 2209 WRITE32(ace->type);
2210 WRITE32(ace->flag); 2210 WRITE32(ace->flag);
2211 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); 2211 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
2212 status = nfsd4_encode_aclname(rqstp, ace->whotype, 2212 status = nfsd4_encode_aclname(rqstp, ace->whotype,
2213 ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP, 2213 ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,
2214 &p, &buflen); 2214 &p, &buflen);
2215 if (status == nfserr_resource) 2215 if (status == nfserr_resource)
2216 goto out_resource; 2216 goto out_resource;
2217 if (status) 2217 if (status)
2218 goto out; 2218 goto out;
2219 } 2219 }
2220 } 2220 }
2221 out_acl: 2221 out_acl:
2222 if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { 2222 if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2223 if ((buflen -= 4) < 0) 2223 if ((buflen -= 4) < 0)
2224 goto out_resource; 2224 goto out_resource;
2225 WRITE32(aclsupport ? 2225 WRITE32(aclsupport ?
2226 ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); 2226 ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2227 } 2227 }
2228 if (bmval0 & FATTR4_WORD0_CANSETTIME) { 2228 if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2229 if ((buflen -= 4) < 0) 2229 if ((buflen -= 4) < 0)
2230 goto out_resource; 2230 goto out_resource;
2231 WRITE32(1); 2231 WRITE32(1);
2232 } 2232 }
2233 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) { 2233 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2234 if ((buflen -= 4) < 0) 2234 if ((buflen -= 4) < 0)
2235 goto out_resource; 2235 goto out_resource;
2236 WRITE32(1); 2236 WRITE32(1);
2237 } 2237 }
2238 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) { 2238 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2239 if ((buflen -= 4) < 0) 2239 if ((buflen -= 4) < 0)
2240 goto out_resource; 2240 goto out_resource;
2241 WRITE32(1); 2241 WRITE32(1);
2242 } 2242 }
2243 if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) { 2243 if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2244 if ((buflen -= 4) < 0) 2244 if ((buflen -= 4) < 0)
2245 goto out_resource; 2245 goto out_resource;
2246 WRITE32(1); 2246 WRITE32(1);
2247 } 2247 }
2248 if (bmval0 & FATTR4_WORD0_FILEHANDLE) { 2248 if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2249 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4; 2249 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4;
2250 if (buflen < 0) 2250 if (buflen < 0)
2251 goto out_resource; 2251 goto out_resource;
2252 WRITE32(fhp->fh_handle.fh_size); 2252 WRITE32(fhp->fh_handle.fh_size);
2253 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size); 2253 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size);
2254 } 2254 }
2255 if (bmval0 & FATTR4_WORD0_FILEID) { 2255 if (bmval0 & FATTR4_WORD0_FILEID) {
2256 if ((buflen -= 8) < 0) 2256 if ((buflen -= 8) < 0)
2257 goto out_resource; 2257 goto out_resource;
2258 WRITE64(stat.ino); 2258 WRITE64(stat.ino);
2259 } 2259 }
2260 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) { 2260 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2261 if ((buflen -= 8) < 0) 2261 if ((buflen -= 8) < 0)
2262 goto out_resource; 2262 goto out_resource;
2263 WRITE64((u64) statfs.f_ffree); 2263 WRITE64((u64) statfs.f_ffree);
2264 } 2264 }
2265 if (bmval0 & FATTR4_WORD0_FILES_FREE) { 2265 if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2266 if ((buflen -= 8) < 0) 2266 if ((buflen -= 8) < 0)
2267 goto out_resource; 2267 goto out_resource;
2268 WRITE64((u64) statfs.f_ffree); 2268 WRITE64((u64) statfs.f_ffree);
2269 } 2269 }
2270 if (bmval0 & FATTR4_WORD0_FILES_TOTAL) { 2270 if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2271 if ((buflen -= 8) < 0) 2271 if ((buflen -= 8) < 0)
2272 goto out_resource; 2272 goto out_resource;
2273 WRITE64((u64) statfs.f_files); 2273 WRITE64((u64) statfs.f_files);
2274 } 2274 }
2275 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { 2275 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2276 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen); 2276 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
2277 if (status == nfserr_resource) 2277 if (status == nfserr_resource)
2278 goto out_resource; 2278 goto out_resource;
2279 if (status) 2279 if (status)
2280 goto out; 2280 goto out;
2281 } 2281 }
2282 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) { 2282 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2283 if ((buflen -= 4) < 0) 2283 if ((buflen -= 4) < 0)
2284 goto out_resource; 2284 goto out_resource;
2285 WRITE32(1); 2285 WRITE32(1);
2286 } 2286 }
2287 if (bmval0 & FATTR4_WORD0_MAXFILESIZE) { 2287 if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2288 if ((buflen -= 8) < 0) 2288 if ((buflen -= 8) < 0)
2289 goto out_resource; 2289 goto out_resource;
2290 WRITE64(~(u64)0); 2290 WRITE64(~(u64)0);
2291 } 2291 }
2292 if (bmval0 & FATTR4_WORD0_MAXLINK) { 2292 if (bmval0 & FATTR4_WORD0_MAXLINK) {
2293 if ((buflen -= 4) < 0) 2293 if ((buflen -= 4) < 0)
2294 goto out_resource; 2294 goto out_resource;
2295 WRITE32(255); 2295 WRITE32(255);
2296 } 2296 }
2297 if (bmval0 & FATTR4_WORD0_MAXNAME) { 2297 if (bmval0 & FATTR4_WORD0_MAXNAME) {
2298 if ((buflen -= 4) < 0) 2298 if ((buflen -= 4) < 0)
2299 goto out_resource; 2299 goto out_resource;
2300 WRITE32(statfs.f_namelen); 2300 WRITE32(statfs.f_namelen);
2301 } 2301 }
2302 if (bmval0 & FATTR4_WORD0_MAXREAD) { 2302 if (bmval0 & FATTR4_WORD0_MAXREAD) {
2303 if ((buflen -= 8) < 0) 2303 if ((buflen -= 8) < 0)
2304 goto out_resource; 2304 goto out_resource;
2305 WRITE64((u64) svc_max_payload(rqstp)); 2305 WRITE64((u64) svc_max_payload(rqstp));
2306 } 2306 }
2307 if (bmval0 & FATTR4_WORD0_MAXWRITE) { 2307 if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2308 if ((buflen -= 8) < 0) 2308 if ((buflen -= 8) < 0)
2309 goto out_resource; 2309 goto out_resource;
2310 WRITE64((u64) svc_max_payload(rqstp)); 2310 WRITE64((u64) svc_max_payload(rqstp));
2311 } 2311 }
2312 if (bmval1 & FATTR4_WORD1_MODE) { 2312 if (bmval1 & FATTR4_WORD1_MODE) {
2313 if ((buflen -= 4) < 0) 2313 if ((buflen -= 4) < 0)
2314 goto out_resource; 2314 goto out_resource;
2315 WRITE32(stat.mode & S_IALLUGO); 2315 WRITE32(stat.mode & S_IALLUGO);
2316 } 2316 }
2317 if (bmval1 & FATTR4_WORD1_NO_TRUNC) { 2317 if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2318 if ((buflen -= 4) < 0) 2318 if ((buflen -= 4) < 0)
2319 goto out_resource; 2319 goto out_resource;
2320 WRITE32(1); 2320 WRITE32(1);
2321 } 2321 }
2322 if (bmval1 & FATTR4_WORD1_NUMLINKS) { 2322 if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2323 if ((buflen -= 4) < 0) 2323 if ((buflen -= 4) < 0)
2324 goto out_resource; 2324 goto out_resource;
2325 WRITE32(stat.nlink); 2325 WRITE32(stat.nlink);
2326 } 2326 }
2327 if (bmval1 & FATTR4_WORD1_OWNER) { 2327 if (bmval1 & FATTR4_WORD1_OWNER) {
2328 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); 2328 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
2329 if (status == nfserr_resource) 2329 if (status == nfserr_resource)
2330 goto out_resource; 2330 goto out_resource;
2331 if (status) 2331 if (status)
2332 goto out; 2332 goto out;
2333 } 2333 }
2334 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { 2334 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2335 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); 2335 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
2336 if (status == nfserr_resource) 2336 if (status == nfserr_resource)
2337 goto out_resource; 2337 goto out_resource;
2338 if (status) 2338 if (status)
2339 goto out; 2339 goto out;
2340 } 2340 }
2341 if (bmval1 & FATTR4_WORD1_RAWDEV) { 2341 if (bmval1 & FATTR4_WORD1_RAWDEV) {
2342 if ((buflen -= 8) < 0) 2342 if ((buflen -= 8) < 0)
2343 goto out_resource; 2343 goto out_resource;
2344 WRITE32((u32) MAJOR(stat.rdev)); 2344 WRITE32((u32) MAJOR(stat.rdev));
2345 WRITE32((u32) MINOR(stat.rdev)); 2345 WRITE32((u32) MINOR(stat.rdev));
2346 } 2346 }
2347 if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) { 2347 if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2348 if ((buflen -= 8) < 0) 2348 if ((buflen -= 8) < 0)
2349 goto out_resource; 2349 goto out_resource;
2350 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize; 2350 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2351 WRITE64(dummy64); 2351 WRITE64(dummy64);
2352 } 2352 }
2353 if (bmval1 & FATTR4_WORD1_SPACE_FREE) { 2353 if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2354 if ((buflen -= 8) < 0) 2354 if ((buflen -= 8) < 0)
2355 goto out_resource; 2355 goto out_resource;
2356 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize; 2356 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2357 WRITE64(dummy64); 2357 WRITE64(dummy64);
2358 } 2358 }
2359 if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) { 2359 if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2360 if ((buflen -= 8) < 0) 2360 if ((buflen -= 8) < 0)
2361 goto out_resource; 2361 goto out_resource;
2362 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize; 2362 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2363 WRITE64(dummy64); 2363 WRITE64(dummy64);
2364 } 2364 }
2365 if (bmval1 & FATTR4_WORD1_SPACE_USED) { 2365 if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2366 if ((buflen -= 8) < 0) 2366 if ((buflen -= 8) < 0)
2367 goto out_resource; 2367 goto out_resource;
2368 dummy64 = (u64)stat.blocks << 9; 2368 dummy64 = (u64)stat.blocks << 9;
2369 WRITE64(dummy64); 2369 WRITE64(dummy64);
2370 } 2370 }
2371 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) { 2371 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2372 if ((buflen -= 12) < 0) 2372 if ((buflen -= 12) < 0)
2373 goto out_resource; 2373 goto out_resource;
2374 WRITE32(0); 2374 WRITE32(0);
2375 WRITE32(stat.atime.tv_sec); 2375 WRITE32(stat.atime.tv_sec);
2376 WRITE32(stat.atime.tv_nsec); 2376 WRITE32(stat.atime.tv_nsec);
2377 } 2377 }
2378 if (bmval1 & FATTR4_WORD1_TIME_DELTA) { 2378 if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2379 if ((buflen -= 12) < 0) 2379 if ((buflen -= 12) < 0)
2380 goto out_resource; 2380 goto out_resource;
2381 WRITE32(0); 2381 WRITE32(0);
2382 WRITE32(1); 2382 WRITE32(1);
2383 WRITE32(0); 2383 WRITE32(0);
2384 } 2384 }
2385 if (bmval1 & FATTR4_WORD1_TIME_METADATA) { 2385 if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2386 if ((buflen -= 12) < 0) 2386 if ((buflen -= 12) < 0)
2387 goto out_resource; 2387 goto out_resource;
2388 WRITE32(0); 2388 WRITE32(0);
2389 WRITE32(stat.ctime.tv_sec); 2389 WRITE32(stat.ctime.tv_sec);
2390 WRITE32(stat.ctime.tv_nsec); 2390 WRITE32(stat.ctime.tv_nsec);
2391 } 2391 }
2392 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) { 2392 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2393 if ((buflen -= 12) < 0) 2393 if ((buflen -= 12) < 0)
2394 goto out_resource; 2394 goto out_resource;
2395 WRITE32(0); 2395 WRITE32(0);
2396 WRITE32(stat.mtime.tv_sec); 2396 WRITE32(stat.mtime.tv_sec);
2397 WRITE32(stat.mtime.tv_nsec); 2397 WRITE32(stat.mtime.tv_nsec);
2398 } 2398 }
2399 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { 2399 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2400 if ((buflen -= 8) < 0) 2400 if ((buflen -= 8) < 0)
2401 goto out_resource; 2401 goto out_resource;
2402 /* 2402 /*
2403 * Get parent's attributes if not ignoring crossmount 2403 * Get parent's attributes if not ignoring crossmount
2404 * and this is the root of a cross-mounted filesystem. 2404 * and this is the root of a cross-mounted filesystem.
2405 */ 2405 */
2406 if (ignore_crossmnt == 0 && 2406 if (ignore_crossmnt == 0 &&
2407 dentry == exp->ex_path.mnt->mnt_root) { 2407 dentry == exp->ex_path.mnt->mnt_root) {
2408 struct path path = exp->ex_path; 2408 struct path path = exp->ex_path;
2409 path_get(&path); 2409 path_get(&path);
2410 while (follow_up(&path)) { 2410 while (follow_up(&path)) {
2411 if (path.dentry != path.mnt->mnt_root) 2411 if (path.dentry != path.mnt->mnt_root)
2412 break; 2412 break;
2413 } 2413 }
2414 err = vfs_getattr(path.mnt, path.dentry, &stat); 2414 err = vfs_getattr(path.mnt, path.dentry, &stat);
2415 path_put(&path); 2415 path_put(&path);
2416 if (err) 2416 if (err)
2417 goto out_nfserr; 2417 goto out_nfserr;
2418 } 2418 }
2419 WRITE64(stat.ino); 2419 WRITE64(stat.ino);
2420 } 2420 }
2421 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { 2421 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2422 WRITE32(3); 2422 WRITE32(3);
2423 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0); 2423 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2424 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1); 2424 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2425 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2); 2425 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
2426 } 2426 }
2427 2427
2428 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2428 *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2429 *countp = p - buffer; 2429 *countp = p - buffer;
2430 status = nfs_ok; 2430 status = nfs_ok;
2431 2431
2432 out: 2432 out:
2433 kfree(acl); 2433 kfree(acl);
2434 if (fhp == &tempfh) 2434 if (fhp == &tempfh)
2435 fh_put(&tempfh); 2435 fh_put(&tempfh);
2436 return status; 2436 return status;
2437 out_nfserr: 2437 out_nfserr:
2438 status = nfserrno(err); 2438 status = nfserrno(err);
2439 goto out; 2439 goto out;
2440 out_resource: 2440 out_resource:
2441 *countp = 0; 2441 *countp = 0;
2442 status = nfserr_resource; 2442 status = nfserr_resource;
2443 goto out; 2443 goto out;
2444 out_serverfault: 2444 out_serverfault:
2445 status = nfserr_serverfault; 2445 status = nfserr_serverfault;
2446 goto out; 2446 goto out;
2447 } 2447 }
2448 2448
2449 static inline int attributes_need_mount(u32 *bmval) 2449 static inline int attributes_need_mount(u32 *bmval)
2450 { 2450 {
2451 if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME)) 2451 if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
2452 return 1; 2452 return 1;
2453 if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID) 2453 if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
2454 return 1; 2454 return 1;
2455 return 0; 2455 return 0;
2456 } 2456 }
2457 2457
2458 static __be32 2458 static __be32
2459 nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, 2459 nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2460 const char *name, int namlen, __be32 *p, int *buflen) 2460 const char *name, int namlen, __be32 *p, int *buflen)
2461 { 2461 {
2462 struct svc_export *exp = cd->rd_fhp->fh_export; 2462 struct svc_export *exp = cd->rd_fhp->fh_export;
2463 struct dentry *dentry; 2463 struct dentry *dentry;
2464 __be32 nfserr; 2464 __be32 nfserr;
2465 int ignore_crossmnt = 0; 2465 int ignore_crossmnt = 0;
2466 2466
2467 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); 2467 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
2468 if (IS_ERR(dentry)) 2468 if (IS_ERR(dentry))
2469 return nfserrno(PTR_ERR(dentry)); 2469 return nfserrno(PTR_ERR(dentry));
2470 if (!dentry->d_inode) { 2470 if (!dentry->d_inode) {
2471 /* 2471 /*
2472 * nfsd_buffered_readdir drops the i_mutex between 2472 * nfsd_buffered_readdir drops the i_mutex between
2473 * readdir and calling this callback, leaving a window 2473 * readdir and calling this callback, leaving a window
2474 * where this directory entry could have gone away. 2474 * where this directory entry could have gone away.
2475 */ 2475 */
2476 dput(dentry); 2476 dput(dentry);
2477 return nfserr_noent; 2477 return nfserr_noent;
2478 } 2478 }
2479 2479
2480 exp_get(exp); 2480 exp_get(exp);
2481 /* 2481 /*
2482 * In the case of a mountpoint, the client may be asking for 2482 * In the case of a mountpoint, the client may be asking for
2483 * attributes that are only properties of the underlying filesystem 2483 * attributes that are only properties of the underlying filesystem
2484 * as opposed to the cross-mounted file system. In such a case, 2484 * as opposed to the cross-mounted file system. In such a case,
2485 * we will not follow the cross mount and will fill the attribtutes 2485 * we will not follow the cross mount and will fill the attribtutes
2486 * directly from the mountpoint dentry. 2486 * directly from the mountpoint dentry.
2487 */ 2487 */
2488 if (nfsd_mountpoint(dentry, exp)) { 2488 if (nfsd_mountpoint(dentry, exp)) {
2489 int err; 2489 int err;
2490 2490
2491 if (!(exp->ex_flags & NFSEXP_V4ROOT) 2491 if (!(exp->ex_flags & NFSEXP_V4ROOT)
2492 && !attributes_need_mount(cd->rd_bmval)) { 2492 && !attributes_need_mount(cd->rd_bmval)) {
2493 ignore_crossmnt = 1; 2493 ignore_crossmnt = 1;
2494 goto out_encode; 2494 goto out_encode;
2495 } 2495 }
2496 /* 2496 /*
2497 * Why the heck aren't we just using nfsd_lookup?? 2497 * Why the heck aren't we just using nfsd_lookup??
2498 * Different "."/".." handling? Something else? 2498 * Different "."/".." handling? Something else?
2499 * At least, add a comment here to explain.... 2499 * At least, add a comment here to explain....
2500 */ 2500 */
2501 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp); 2501 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
2502 if (err) { 2502 if (err) {
2503 nfserr = nfserrno(err); 2503 nfserr = nfserrno(err);
2504 goto out_put; 2504 goto out_put;
2505 } 2505 }
2506 nfserr = check_nfsd_access(exp, cd->rd_rqstp); 2506 nfserr = check_nfsd_access(exp, cd->rd_rqstp);
2507 if (nfserr) 2507 if (nfserr)
2508 goto out_put; 2508 goto out_put;
2509 2509
2510 } 2510 }
2511 out_encode: 2511 out_encode:
2512 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, 2512 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
2513 cd->rd_rqstp, ignore_crossmnt); 2513 cd->rd_rqstp, ignore_crossmnt);
2514 out_put: 2514 out_put:
2515 dput(dentry); 2515 dput(dentry);
2516 exp_put(exp); 2516 exp_put(exp);
2517 return nfserr; 2517 return nfserr;
2518 } 2518 }
2519 2519
2520 static __be32 * 2520 static __be32 *
2521 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) 2521 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
2522 { 2522 {
2523 __be32 *attrlenp; 2523 __be32 *attrlenp;
2524 2524
2525 if (buflen < 6) 2525 if (buflen < 6)
2526 return NULL; 2526 return NULL;
2527 *p++ = htonl(2); 2527 *p++ = htonl(2);
2528 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */ 2528 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2529 *p++ = htonl(0); /* bmval1 */ 2529 *p++ = htonl(0); /* bmval1 */
2530 2530
2531 attrlenp = p++; 2531 attrlenp = p++;
2532 *p++ = nfserr; /* no htonl */ 2532 *p++ = nfserr; /* no htonl */
2533 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2533 *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2534 return p; 2534 return p;
2535 } 2535 }
2536 2536
2537 static int 2537 static int
2538 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, 2538 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2539 loff_t offset, u64 ino, unsigned int d_type) 2539 loff_t offset, u64 ino, unsigned int d_type)
2540 { 2540 {
2541 struct readdir_cd *ccd = ccdv; 2541 struct readdir_cd *ccd = ccdv;
2542 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); 2542 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2543 int buflen; 2543 int buflen;
2544 __be32 *p = cd->buffer; 2544 __be32 *p = cd->buffer;
2545 __be32 *cookiep; 2545 __be32 *cookiep;
2546 __be32 nfserr = nfserr_toosmall; 2546 __be32 nfserr = nfserr_toosmall;
2547 2547
2548 /* In nfsv4, "." and ".." never make it onto the wire.. */ 2548 /* In nfsv4, "." and ".." never make it onto the wire.. */
2549 if (name && isdotent(name, namlen)) { 2549 if (name && isdotent(name, namlen)) {
2550 cd->common.err = nfs_ok; 2550 cd->common.err = nfs_ok;
2551 return 0; 2551 return 0;
2552 } 2552 }
2553 2553
2554 if (cd->offset) 2554 if (cd->offset)
2555 xdr_encode_hyper(cd->offset, (u64) offset); 2555 xdr_encode_hyper(cd->offset, (u64) offset);
2556 2556
2557 buflen = cd->buflen - 4 - XDR_QUADLEN(namlen); 2557 buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
2558 if (buflen < 0) 2558 if (buflen < 0)
2559 goto fail; 2559 goto fail;
2560 2560
2561 *p++ = xdr_one; /* mark entry present */ 2561 *p++ = xdr_one; /* mark entry present */
2562 cookiep = p; 2562 cookiep = p;
2563 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ 2563 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
2564 p = xdr_encode_array(p, name, namlen); /* name length & name */ 2564 p = xdr_encode_array(p, name, namlen); /* name length & name */
2565 2565
2566 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen); 2566 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);
2567 switch (nfserr) { 2567 switch (nfserr) {
2568 case nfs_ok: 2568 case nfs_ok:
2569 p += buflen; 2569 p += buflen;
2570 break; 2570 break;
2571 case nfserr_resource: 2571 case nfserr_resource:
2572 nfserr = nfserr_toosmall; 2572 nfserr = nfserr_toosmall;
2573 goto fail; 2573 goto fail;
2574 case nfserr_noent: 2574 case nfserr_noent:
2575 goto skip_entry; 2575 goto skip_entry;
2576 default: 2576 default:
2577 /* 2577 /*
2578 * If the client requested the RDATTR_ERROR attribute, 2578 * If the client requested the RDATTR_ERROR attribute,
2579 * we stuff the error code into this attribute 2579 * we stuff the error code into this attribute
2580 * and continue. If this attribute was not requested, 2580 * and continue. If this attribute was not requested,
2581 * then in accordance with the spec, we fail the 2581 * then in accordance with the spec, we fail the
2582 * entire READDIR operation(!) 2582 * entire READDIR operation(!)
2583 */ 2583 */
2584 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)) 2584 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2585 goto fail; 2585 goto fail;
2586 p = nfsd4_encode_rdattr_error(p, buflen, nfserr); 2586 p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
2587 if (p == NULL) { 2587 if (p == NULL) {
2588 nfserr = nfserr_toosmall; 2588 nfserr = nfserr_toosmall;
2589 goto fail; 2589 goto fail;
2590 } 2590 }
2591 } 2591 }
2592 cd->buflen -= (p - cd->buffer); 2592 cd->buflen -= (p - cd->buffer);
2593 cd->buffer = p; 2593 cd->buffer = p;
2594 cd->offset = cookiep; 2594 cd->offset = cookiep;
2595 skip_entry: 2595 skip_entry:
2596 cd->common.err = nfs_ok; 2596 cd->common.err = nfs_ok;
2597 return 0; 2597 return 0;
2598 fail: 2598 fail:
2599 cd->common.err = nfserr; 2599 cd->common.err = nfserr;
2600 return -EINVAL; 2600 return -EINVAL;
2601 } 2601 }
2602 2602
2603 static void 2603 static void
2604 nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid) 2604 nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
2605 { 2605 {
2606 __be32 *p; 2606 __be32 *p;
2607 2607
2608 RESERVE_SPACE(sizeof(stateid_t)); 2608 RESERVE_SPACE(sizeof(stateid_t));
2609 WRITE32(sid->si_generation); 2609 WRITE32(sid->si_generation);
2610 WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); 2610 WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
2611 ADJUST_ARGS(); 2611 ADJUST_ARGS();
2612 } 2612 }
2613 2613
2614 static __be32 2614 static __be32
2615 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) 2615 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
2616 { 2616 {
2617 __be32 *p; 2617 __be32 *p;
2618 2618
2619 if (!nfserr) { 2619 if (!nfserr) {
2620 RESERVE_SPACE(8); 2620 RESERVE_SPACE(8);
2621 WRITE32(access->ac_supported); 2621 WRITE32(access->ac_supported);
2622 WRITE32(access->ac_resp_access); 2622 WRITE32(access->ac_resp_access);
2623 ADJUST_ARGS(); 2623 ADJUST_ARGS();
2624 } 2624 }
2625 return nfserr; 2625 return nfserr;
2626 } 2626 }
2627 2627
2628 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) 2628 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2629 { 2629 {
2630 __be32 *p; 2630 __be32 *p;
2631 2631
2632 if (!nfserr) { 2632 if (!nfserr) {
2633 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8); 2633 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
2634 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); 2634 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
2635 WRITE32(bcts->dir); 2635 WRITE32(bcts->dir);
2636 /* XXX: ? */ 2636 /* XXX: ? */
2637 WRITE32(0); 2637 WRITE32(0);
2638 ADJUST_ARGS(); 2638 ADJUST_ARGS();
2639 } 2639 }
2640 return nfserr; 2640 return nfserr;
2641 } 2641 }
2642 2642
2643 static __be32 2643 static __be32
2644 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) 2644 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2645 { 2645 {
2646 ENCODE_SEQID_OP_HEAD; 2646 ENCODE_SEQID_OP_HEAD;
2647 2647
2648 if (!nfserr) 2648 if (!nfserr)
2649 nfsd4_encode_stateid(resp, &close->cl_stateid); 2649 nfsd4_encode_stateid(resp, &close->cl_stateid);
2650 2650
2651 encode_seqid_op_tail(resp, save, nfserr); 2651 encode_seqid_op_tail(resp, save, nfserr);
2652 return nfserr; 2652 return nfserr;
2653 } 2653 }
2654 2654
2655 2655
2656 static __be32 2656 static __be32
2657 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) 2657 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2658 { 2658 {
2659 __be32 *p; 2659 __be32 *p;
2660 2660
2661 if (!nfserr) { 2661 if (!nfserr) {
2662 RESERVE_SPACE(NFS4_VERIFIER_SIZE); 2662 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
2663 WRITEMEM(commit->co_verf.data, NFS4_VERIFIER_SIZE); 2663 WRITEMEM(commit->co_verf.data, NFS4_VERIFIER_SIZE);
2664 ADJUST_ARGS(); 2664 ADJUST_ARGS();
2665 } 2665 }
2666 return nfserr; 2666 return nfserr;
2667 } 2667 }
2668 2668
2669 static __be32 2669 static __be32
2670 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) 2670 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2671 { 2671 {
2672 __be32 *p; 2672 __be32 *p;
2673 2673
2674 if (!nfserr) { 2674 if (!nfserr) {
2675 RESERVE_SPACE(32); 2675 RESERVE_SPACE(32);
2676 write_cinfo(&p, &create->cr_cinfo); 2676 write_cinfo(&p, &create->cr_cinfo);
2677 WRITE32(2); 2677 WRITE32(2);
2678 WRITE32(create->cr_bmval[0]); 2678 WRITE32(create->cr_bmval[0]);
2679 WRITE32(create->cr_bmval[1]); 2679 WRITE32(create->cr_bmval[1]);
2680 ADJUST_ARGS(); 2680 ADJUST_ARGS();
2681 } 2681 }
2682 return nfserr; 2682 return nfserr;
2683 } 2683 }
2684 2684
2685 static __be32 2685 static __be32
2686 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) 2686 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
2687 { 2687 {
2688 struct svc_fh *fhp = getattr->ga_fhp; 2688 struct svc_fh *fhp = getattr->ga_fhp;
2689 int buflen; 2689 int buflen;
2690 2690
2691 if (nfserr) 2691 if (nfserr)
2692 return nfserr; 2692 return nfserr;
2693 2693
2694 buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); 2694 buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2695 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, 2695 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
2696 resp->p, &buflen, getattr->ga_bmval, 2696 resp->p, &buflen, getattr->ga_bmval,
2697 resp->rqstp, 0); 2697 resp->rqstp, 0);
2698 if (!nfserr) 2698 if (!nfserr)
2699 resp->p += buflen; 2699 resp->p += buflen;
2700 return nfserr; 2700 return nfserr;
2701 } 2701 }
2702 2702
2703 static __be32 2703 static __be32
2704 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp) 2704 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2705 { 2705 {
2706 struct svc_fh *fhp = *fhpp; 2706 struct svc_fh *fhp = *fhpp;
2707 unsigned int len; 2707 unsigned int len;
2708 __be32 *p; 2708 __be32 *p;
2709 2709
2710 if (!nfserr) { 2710 if (!nfserr) {
2711 len = fhp->fh_handle.fh_size; 2711 len = fhp->fh_handle.fh_size;
2712 RESERVE_SPACE(len + 4); 2712 RESERVE_SPACE(len + 4);
2713 WRITE32(len); 2713 WRITE32(len);
2714 WRITEMEM(&fhp->fh_handle.fh_base, len); 2714 WRITEMEM(&fhp->fh_handle.fh_base, len);
2715 ADJUST_ARGS(); 2715 ADJUST_ARGS();
2716 } 2716 }
2717 return nfserr; 2717 return nfserr;
2718 } 2718 }
2719 2719
2720 /* 2720 /*
2721 * Including all fields other than the name, a LOCK4denied structure requires 2721 * Including all fields other than the name, a LOCK4denied structure requires
2722 * 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes. 2722 * 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
2723 */ 2723 */
2724 static void 2724 static void
2725 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld) 2725 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2726 { 2726 {
2727 struct xdr_netobj *conf = &ld->ld_owner; 2727 struct xdr_netobj *conf = &ld->ld_owner;
2728 __be32 *p; 2728 __be32 *p;
2729 2729
2730 RESERVE_SPACE(32 + XDR_LEN(conf->len)); 2730 RESERVE_SPACE(32 + XDR_LEN(conf->len));
2731 WRITE64(ld->ld_start); 2731 WRITE64(ld->ld_start);
2732 WRITE64(ld->ld_length); 2732 WRITE64(ld->ld_length);
2733 WRITE32(ld->ld_type); 2733 WRITE32(ld->ld_type);
2734 if (conf->len) { 2734 if (conf->len) {
2735 WRITEMEM(&ld->ld_clientid, 8); 2735 WRITEMEM(&ld->ld_clientid, 8);
2736 WRITE32(conf->len); 2736 WRITE32(conf->len);
2737 WRITEMEM(conf->data, conf->len); 2737 WRITEMEM(conf->data, conf->len);
2738 kfree(conf->data); 2738 kfree(conf->data);
2739 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */ 2739 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */
2740 WRITE64((u64)0); /* clientid */ 2740 WRITE64((u64)0); /* clientid */
2741 WRITE32(0); /* length of owner name */ 2741 WRITE32(0); /* length of owner name */
2742 } 2742 }
2743 ADJUST_ARGS(); 2743 ADJUST_ARGS();
2744 } 2744 }
2745 2745
2746 static __be32 2746 static __be32
2747 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) 2747 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2748 { 2748 {
2749 ENCODE_SEQID_OP_HEAD; 2749 ENCODE_SEQID_OP_HEAD;
2750 2750
2751 if (!nfserr) 2751 if (!nfserr)
2752 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid); 2752 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2753 else if (nfserr == nfserr_denied) 2753 else if (nfserr == nfserr_denied)
2754 nfsd4_encode_lock_denied(resp, &lock->lk_denied); 2754 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2755 2755
2756 encode_seqid_op_tail(resp, save, nfserr); 2756 encode_seqid_op_tail(resp, save, nfserr);
2757 return nfserr; 2757 return nfserr;
2758 } 2758 }
2759 2759
2760 static __be32 2760 static __be32
2761 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) 2761 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2762 { 2762 {
2763 if (nfserr == nfserr_denied) 2763 if (nfserr == nfserr_denied)
2764 nfsd4_encode_lock_denied(resp, &lockt->lt_denied); 2764 nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
2765 return nfserr; 2765 return nfserr;
2766 } 2766 }
2767 2767
2768 static __be32 2768 static __be32
2769 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) 2769 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2770 { 2770 {
2771 ENCODE_SEQID_OP_HEAD; 2771 ENCODE_SEQID_OP_HEAD;
2772 2772
2773 if (!nfserr) 2773 if (!nfserr)
2774 nfsd4_encode_stateid(resp, &locku->lu_stateid); 2774 nfsd4_encode_stateid(resp, &locku->lu_stateid);
2775 2775
2776 encode_seqid_op_tail(resp, save, nfserr); 2776 encode_seqid_op_tail(resp, save, nfserr);
2777 return nfserr; 2777 return nfserr;
2778 } 2778 }
2779 2779
2780 2780
2781 static __be32 2781 static __be32
2782 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) 2782 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2783 { 2783 {
2784 __be32 *p; 2784 __be32 *p;
2785 2785
2786 if (!nfserr) { 2786 if (!nfserr) {
2787 RESERVE_SPACE(20); 2787 RESERVE_SPACE(20);
2788 write_cinfo(&p, &link->li_cinfo); 2788 write_cinfo(&p, &link->li_cinfo);
2789 ADJUST_ARGS(); 2789 ADJUST_ARGS();
2790 } 2790 }
2791 return nfserr; 2791 return nfserr;
2792 } 2792 }
2793 2793
2794 2794
2795 static __be32 2795 static __be32
2796 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) 2796 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2797 { 2797 {
2798 __be32 *p; 2798 __be32 *p;
2799 ENCODE_SEQID_OP_HEAD; 2799 ENCODE_SEQID_OP_HEAD;
2800 2800
2801 if (nfserr) 2801 if (nfserr)
2802 goto out; 2802 goto out;
2803 2803
2804 nfsd4_encode_stateid(resp, &open->op_stateid); 2804 nfsd4_encode_stateid(resp, &open->op_stateid);
2805 RESERVE_SPACE(40); 2805 RESERVE_SPACE(40);
2806 write_cinfo(&p, &open->op_cinfo); 2806 write_cinfo(&p, &open->op_cinfo);
2807 WRITE32(open->op_rflags); 2807 WRITE32(open->op_rflags);
2808 WRITE32(2); 2808 WRITE32(2);
2809 WRITE32(open->op_bmval[0]); 2809 WRITE32(open->op_bmval[0]);
2810 WRITE32(open->op_bmval[1]); 2810 WRITE32(open->op_bmval[1]);
2811 WRITE32(open->op_delegate_type); 2811 WRITE32(open->op_delegate_type);
2812 ADJUST_ARGS(); 2812 ADJUST_ARGS();
2813 2813
2814 switch (open->op_delegate_type) { 2814 switch (open->op_delegate_type) {
2815 case NFS4_OPEN_DELEGATE_NONE: 2815 case NFS4_OPEN_DELEGATE_NONE:
2816 break; 2816 break;
2817 case NFS4_OPEN_DELEGATE_READ: 2817 case NFS4_OPEN_DELEGATE_READ:
2818 nfsd4_encode_stateid(resp, &open->op_delegate_stateid); 2818 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2819 RESERVE_SPACE(20); 2819 RESERVE_SPACE(20);
2820 WRITE32(open->op_recall); 2820 WRITE32(open->op_recall);
2821 2821
2822 /* 2822 /*
2823 * TODO: ACE's in delegations 2823 * TODO: ACE's in delegations
2824 */ 2824 */
2825 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE); 2825 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2826 WRITE32(0); 2826 WRITE32(0);
2827 WRITE32(0); 2827 WRITE32(0);
2828 WRITE32(0); /* XXX: is NULL principal ok? */ 2828 WRITE32(0); /* XXX: is NULL principal ok? */
2829 ADJUST_ARGS(); 2829 ADJUST_ARGS();
2830 break; 2830 break;
2831 case NFS4_OPEN_DELEGATE_WRITE: 2831 case NFS4_OPEN_DELEGATE_WRITE:
2832 nfsd4_encode_stateid(resp, &open->op_delegate_stateid); 2832 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2833 RESERVE_SPACE(32); 2833 RESERVE_SPACE(32);
2834 WRITE32(0); 2834 WRITE32(0);
2835 2835
2836 /* 2836 /*
2837 * TODO: space_limit's in delegations 2837 * TODO: space_limit's in delegations
2838 */ 2838 */
2839 WRITE32(NFS4_LIMIT_SIZE); 2839 WRITE32(NFS4_LIMIT_SIZE);
2840 WRITE32(~(u32)0); 2840 WRITE32(~(u32)0);
2841 WRITE32(~(u32)0); 2841 WRITE32(~(u32)0);
2842 2842
2843 /* 2843 /*
2844 * TODO: ACE's in delegations 2844 * TODO: ACE's in delegations
2845 */ 2845 */
2846 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE); 2846 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2847 WRITE32(0); 2847 WRITE32(0);
2848 WRITE32(0); 2848 WRITE32(0);
2849 WRITE32(0); /* XXX: is NULL principal ok? */ 2849 WRITE32(0); /* XXX: is NULL principal ok? */
2850 ADJUST_ARGS(); 2850 ADJUST_ARGS();
2851 break; 2851 break;
2852 case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */ 2852 case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
2853 switch (open->op_why_no_deleg) { 2853 switch (open->op_why_no_deleg) {
2854 case WND4_CONTENTION: 2854 case WND4_CONTENTION:
2855 case WND4_RESOURCE: 2855 case WND4_RESOURCE:
2856 RESERVE_SPACE(8); 2856 RESERVE_SPACE(8);
2857 WRITE32(open->op_why_no_deleg); 2857 WRITE32(open->op_why_no_deleg);
2858 WRITE32(0); /* deleg signaling not supported yet */ 2858 WRITE32(0); /* deleg signaling not supported yet */
2859 break; 2859 break;
2860 default: 2860 default:
2861 RESERVE_SPACE(4); 2861 RESERVE_SPACE(4);
2862 WRITE32(open->op_why_no_deleg); 2862 WRITE32(open->op_why_no_deleg);
2863 } 2863 }
2864 ADJUST_ARGS(); 2864 ADJUST_ARGS();
2865 break; 2865 break;
2866 default: 2866 default:
2867 BUG(); 2867 BUG();
2868 } 2868 }
2869 /* XXX save filehandle here */ 2869 /* XXX save filehandle here */
2870 out: 2870 out:
2871 encode_seqid_op_tail(resp, save, nfserr); 2871 encode_seqid_op_tail(resp, save, nfserr);
2872 return nfserr; 2872 return nfserr;
2873 } 2873 }
2874 2874
2875 static __be32 2875 static __be32
2876 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) 2876 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2877 { 2877 {
2878 ENCODE_SEQID_OP_HEAD; 2878 ENCODE_SEQID_OP_HEAD;
2879 2879
2880 if (!nfserr) 2880 if (!nfserr)
2881 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid); 2881 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2882 2882
2883 encode_seqid_op_tail(resp, save, nfserr); 2883 encode_seqid_op_tail(resp, save, nfserr);
2884 return nfserr; 2884 return nfserr;
2885 } 2885 }
2886 2886
2887 static __be32 2887 static __be32
2888 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) 2888 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2889 { 2889 {
2890 ENCODE_SEQID_OP_HEAD; 2890 ENCODE_SEQID_OP_HEAD;
2891 2891
2892 if (!nfserr) 2892 if (!nfserr)
2893 nfsd4_encode_stateid(resp, &od->od_stateid); 2893 nfsd4_encode_stateid(resp, &od->od_stateid);
2894 2894
2895 encode_seqid_op_tail(resp, save, nfserr); 2895 encode_seqid_op_tail(resp, save, nfserr);
2896 return nfserr; 2896 return nfserr;
2897 } 2897 }
2898 2898
2899 static __be32 2899 static __be32
2900 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, 2900 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2901 struct nfsd4_read *read) 2901 struct nfsd4_read *read)
2902 { 2902 {
2903 u32 eof; 2903 u32 eof;
2904 int v, pn; 2904 int v, pn;
2905 unsigned long maxcount; 2905 unsigned long maxcount;
2906 long len; 2906 long len;
2907 __be32 *p; 2907 __be32 *p;
2908 2908
2909 if (nfserr) 2909 if (nfserr)
2910 return nfserr; 2910 return nfserr;
2911 if (resp->xbuf->page_len) 2911 if (resp->xbuf->page_len)
2912 return nfserr_resource; 2912 return nfserr_resource;
2913 2913
2914 RESERVE_SPACE(8); /* eof flag and byte count */ 2914 RESERVE_SPACE(8); /* eof flag and byte count */
2915 2915
2916 maxcount = svc_max_payload(resp->rqstp); 2916 maxcount = svc_max_payload(resp->rqstp);
2917 if (maxcount > read->rd_length) 2917 if (maxcount > read->rd_length)
2918 maxcount = read->rd_length; 2918 maxcount = read->rd_length;
2919 2919
2920 len = maxcount; 2920 len = maxcount;
2921 v = 0; 2921 v = 0;
2922 while (len > 0) { 2922 while (len > 0) {
2923 pn = resp->rqstp->rq_resused++; 2923 pn = resp->rqstp->rq_resused++;
2924 resp->rqstp->rq_vec[v].iov_base = 2924 resp->rqstp->rq_vec[v].iov_base =
2925 page_address(resp->rqstp->rq_respages[pn]); 2925 page_address(resp->rqstp->rq_respages[pn]);
2926 resp->rqstp->rq_vec[v].iov_len = 2926 resp->rqstp->rq_vec[v].iov_len =
2927 len < PAGE_SIZE ? len : PAGE_SIZE; 2927 len < PAGE_SIZE ? len : PAGE_SIZE;
2928 v++; 2928 v++;
2929 len -= PAGE_SIZE; 2929 len -= PAGE_SIZE;
2930 } 2930 }
2931 read->rd_vlen = v; 2931 read->rd_vlen = v;
2932 2932
2933 nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp, 2933 nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2934 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, 2934 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2935 &maxcount); 2935 &maxcount);
2936 2936
2937 if (nfserr) 2937 if (nfserr)
2938 return nfserr; 2938 return nfserr;
2939 eof = (read->rd_offset + maxcount >= 2939 eof = (read->rd_offset + maxcount >=
2940 read->rd_fhp->fh_dentry->d_inode->i_size); 2940 read->rd_fhp->fh_dentry->d_inode->i_size);
2941 2941
2942 WRITE32(eof); 2942 WRITE32(eof);
2943 WRITE32(maxcount); 2943 WRITE32(maxcount);
2944 ADJUST_ARGS(); 2944 ADJUST_ARGS();
2945 resp->xbuf->head[0].iov_len = (char*)p 2945 resp->xbuf->head[0].iov_len = (char*)p
2946 - (char*)resp->xbuf->head[0].iov_base; 2946 - (char*)resp->xbuf->head[0].iov_base;
2947 resp->xbuf->page_len = maxcount; 2947 resp->xbuf->page_len = maxcount;
2948 2948
2949 /* Use rest of head for padding and remaining ops: */ 2949 /* Use rest of head for padding and remaining ops: */
2950 resp->xbuf->tail[0].iov_base = p; 2950 resp->xbuf->tail[0].iov_base = p;
2951 resp->xbuf->tail[0].iov_len = 0; 2951 resp->xbuf->tail[0].iov_len = 0;
2952 if (maxcount&3) { 2952 if (maxcount&3) {
2953 RESERVE_SPACE(4); 2953 RESERVE_SPACE(4);
2954 WRITE32(0); 2954 WRITE32(0);
2955 resp->xbuf->tail[0].iov_base += maxcount&3; 2955 resp->xbuf->tail[0].iov_base += maxcount&3;
2956 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); 2956 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2957 ADJUST_ARGS(); 2957 ADJUST_ARGS();
2958 } 2958 }
2959 return 0; 2959 return 0;
2960 } 2960 }
2961 2961
2962 static __be32 2962 static __be32
2963 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) 2963 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
2964 { 2964 {
2965 int maxcount; 2965 int maxcount;
2966 char *page; 2966 char *page;
2967 __be32 *p; 2967 __be32 *p;
2968 2968
2969 if (nfserr) 2969 if (nfserr)
2970 return nfserr; 2970 return nfserr;
2971 if (resp->xbuf->page_len) 2971 if (resp->xbuf->page_len)
2972 return nfserr_resource; 2972 return nfserr_resource;
2973 2973
2974 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 2974 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2975 2975
2976 maxcount = PAGE_SIZE; 2976 maxcount = PAGE_SIZE;
2977 RESERVE_SPACE(4); 2977 RESERVE_SPACE(4);
2978 2978
2979 /* 2979 /*
2980 * XXX: By default, the ->readlink() VFS op will truncate symlinks 2980 * XXX: By default, the ->readlink() VFS op will truncate symlinks
2981 * if they would overflow the buffer. Is this kosher in NFSv4? If 2981 * if they would overflow the buffer. Is this kosher in NFSv4? If
2982 * not, one easy fix is: if ->readlink() precisely fills the buffer, 2982 * not, one easy fix is: if ->readlink() precisely fills the buffer,
2983 * assume that truncation occurred, and return NFS4ERR_RESOURCE. 2983 * assume that truncation occurred, and return NFS4ERR_RESOURCE.
2984 */ 2984 */
2985 nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount); 2985 nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
2986 if (nfserr == nfserr_isdir) 2986 if (nfserr == nfserr_isdir)
2987 return nfserr_inval; 2987 return nfserr_inval;
2988 if (nfserr) 2988 if (nfserr)
2989 return nfserr; 2989 return nfserr;
2990 2990
2991 WRITE32(maxcount); 2991 WRITE32(maxcount);
2992 ADJUST_ARGS(); 2992 ADJUST_ARGS();
2993 resp->xbuf->head[0].iov_len = (char*)p 2993 resp->xbuf->head[0].iov_len = (char*)p
2994 - (char*)resp->xbuf->head[0].iov_base; 2994 - (char*)resp->xbuf->head[0].iov_base;
2995 resp->xbuf->page_len = maxcount; 2995 resp->xbuf->page_len = maxcount;
2996 2996
2997 /* Use rest of head for padding and remaining ops: */ 2997 /* Use rest of head for padding and remaining ops: */
2998 resp->xbuf->tail[0].iov_base = p; 2998 resp->xbuf->tail[0].iov_base = p;
2999 resp->xbuf->tail[0].iov_len = 0; 2999 resp->xbuf->tail[0].iov_len = 0;
3000 if (maxcount&3) { 3000 if (maxcount&3) {
3001 RESERVE_SPACE(4); 3001 RESERVE_SPACE(4);
3002 WRITE32(0); 3002 WRITE32(0);
3003 resp->xbuf->tail[0].iov_base += maxcount&3; 3003 resp->xbuf->tail[0].iov_base += maxcount&3;
3004 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); 3004 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
3005 ADJUST_ARGS(); 3005 ADJUST_ARGS();
3006 } 3006 }
3007 return 0; 3007 return 0;
3008 } 3008 }
3009 3009
3010 static __be32 3010 static __be32
3011 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) 3011 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
3012 { 3012 {
3013 int maxcount; 3013 int maxcount;
3014 loff_t offset; 3014 loff_t offset;
3015 __be32 *page, *savep, *tailbase; 3015 __be32 *page, *savep, *tailbase;
3016 __be32 *p; 3016 __be32 *p;
3017 3017
3018 if (nfserr) 3018 if (nfserr)
3019 return nfserr; 3019 return nfserr;
3020 if (resp->xbuf->page_len) 3020 if (resp->xbuf->page_len)
3021 return nfserr_resource; 3021 return nfserr_resource;
3022 3022
3023 RESERVE_SPACE(NFS4_VERIFIER_SIZE); 3023 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
3024 savep = p; 3024 savep = p;
3025 3025
3026 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */ 3026 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
3027 WRITE32(0); 3027 WRITE32(0);
3028 WRITE32(0); 3028 WRITE32(0);
3029 ADJUST_ARGS(); 3029 ADJUST_ARGS();
3030 resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; 3030 resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
3031 tailbase = p; 3031 tailbase = p;
3032 3032
3033 maxcount = PAGE_SIZE; 3033 maxcount = PAGE_SIZE;
3034 if (maxcount > readdir->rd_maxcount) 3034 if (maxcount > readdir->rd_maxcount)
3035 maxcount = readdir->rd_maxcount; 3035 maxcount = readdir->rd_maxcount;
3036 3036
3037 /* 3037 /*
3038 * Convert from bytes to words, account for the two words already 3038 * Convert from bytes to words, account for the two words already
3039 * written, make sure to leave two words at the end for the next 3039 * written, make sure to leave two words at the end for the next
3040 * pointer and eof field. 3040 * pointer and eof field.
3041 */ 3041 */
3042 maxcount = (maxcount >> 2) - 4; 3042 maxcount = (maxcount >> 2) - 4;
3043 if (maxcount < 0) { 3043 if (maxcount < 0) {
3044 nfserr = nfserr_toosmall; 3044 nfserr = nfserr_toosmall;
3045 goto err_no_verf; 3045 goto err_no_verf;
3046 } 3046 }
3047 3047
3048 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 3048 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
3049 readdir->common.err = 0; 3049 readdir->common.err = 0;
3050 readdir->buflen = maxcount; 3050 readdir->buflen = maxcount;
3051 readdir->buffer = page; 3051 readdir->buffer = page;
3052 readdir->offset = NULL; 3052 readdir->offset = NULL;
3053 3053
3054 offset = readdir->rd_cookie; 3054 offset = readdir->rd_cookie;
3055 nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp, 3055 nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
3056 &offset, 3056 &offset,
3057 &readdir->common, nfsd4_encode_dirent); 3057 &readdir->common, nfsd4_encode_dirent);
3058 if (nfserr == nfs_ok && 3058 if (nfserr == nfs_ok &&
3059 readdir->common.err == nfserr_toosmall && 3059 readdir->common.err == nfserr_toosmall &&
3060 readdir->buffer == page) 3060 readdir->buffer == page)
3061 nfserr = nfserr_toosmall; 3061 nfserr = nfserr_toosmall;
3062 if (nfserr) 3062 if (nfserr)
3063 goto err_no_verf; 3063 goto err_no_verf;
3064 3064
3065 if (readdir->offset) 3065 if (readdir->offset)
3066 xdr_encode_hyper(readdir->offset, offset); 3066 xdr_encode_hyper(readdir->offset, offset);
3067 3067
3068 p = readdir->buffer; 3068 p = readdir->buffer;
3069 *p++ = 0; /* no more entries */ 3069 *p++ = 0; /* no more entries */
3070 *p++ = htonl(readdir->common.err == nfserr_eof); 3070 *p++ = htonl(readdir->common.err == nfserr_eof);
3071 resp->xbuf->page_len = ((char*)p) - (char*)page_address( 3071 resp->xbuf->page_len = ((char*)p) - (char*)page_address(
3072 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); 3072 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
3073 3073
3074 /* Use rest of head for padding and remaining ops: */ 3074 /* Use rest of head for padding and remaining ops: */
3075 resp->xbuf->tail[0].iov_base = tailbase; 3075 resp->xbuf->tail[0].iov_base = tailbase;
3076 resp->xbuf->tail[0].iov_len = 0; 3076 resp->xbuf->tail[0].iov_len = 0;
3077 resp->p = resp->xbuf->tail[0].iov_base; 3077 resp->p = resp->xbuf->tail[0].iov_base;
3078 resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4; 3078 resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;
3079 3079
3080 return 0; 3080 return 0;
3081 err_no_verf: 3081 err_no_verf:
3082 p = savep; 3082 p = savep;
3083 ADJUST_ARGS(); 3083 ADJUST_ARGS();
3084 return nfserr; 3084 return nfserr;
3085 } 3085 }
3086 3086
3087 static __be32 3087 static __be32
3088 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) 3088 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
3089 { 3089 {
3090 __be32 *p; 3090 __be32 *p;
3091 3091
3092 if (!nfserr) { 3092 if (!nfserr) {
3093 RESERVE_SPACE(20); 3093 RESERVE_SPACE(20);
3094 write_cinfo(&p, &remove->rm_cinfo); 3094 write_cinfo(&p, &remove->rm_cinfo);
3095 ADJUST_ARGS(); 3095 ADJUST_ARGS();
3096 } 3096 }
3097 return nfserr; 3097 return nfserr;
3098 } 3098 }
3099 3099
3100 static __be32 3100 static __be32
3101 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) 3101 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
3102 { 3102 {
3103 __be32 *p; 3103 __be32 *p;
3104 3104
3105 if (!nfserr) { 3105 if (!nfserr) {
3106 RESERVE_SPACE(40); 3106 RESERVE_SPACE(40);
3107 write_cinfo(&p, &rename->rn_sinfo); 3107 write_cinfo(&p, &rename->rn_sinfo);
3108 write_cinfo(&p, &rename->rn_tinfo); 3108 write_cinfo(&p, &rename->rn_tinfo);
3109 ADJUST_ARGS(); 3109 ADJUST_ARGS();
3110 } 3110 }
3111 return nfserr; 3111 return nfserr;
3112 } 3112 }
3113 3113
3114 static __be32 3114 static __be32
3115 nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, 3115 nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3116 __be32 nfserr,struct svc_export *exp) 3116 __be32 nfserr,struct svc_export *exp)
3117 { 3117 {
3118 int i = 0; 3118 int i = 0;
3119 u32 nflavs; 3119 u32 nflavs;
3120 struct exp_flavor_info *flavs; 3120 struct exp_flavor_info *flavs;
3121 struct exp_flavor_info def_flavs[2]; 3121 struct exp_flavor_info def_flavs[2];
3122 __be32 *p; 3122 __be32 *p;
3123 3123
3124 if (nfserr) 3124 if (nfserr)
3125 goto out; 3125 goto out;
3126 if (exp->ex_nflavors) { 3126 if (exp->ex_nflavors) {
3127 flavs = exp->ex_flavors; 3127 flavs = exp->ex_flavors;
3128 nflavs = exp->ex_nflavors; 3128 nflavs = exp->ex_nflavors;
3129 } else { /* Handling of some defaults in absence of real secinfo: */ 3129 } else { /* Handling of some defaults in absence of real secinfo: */
3130 flavs = def_flavs; 3130 flavs = def_flavs;
3131 if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) { 3131 if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
3132 nflavs = 2; 3132 nflavs = 2;
3133 flavs[0].pseudoflavor = RPC_AUTH_UNIX; 3133 flavs[0].pseudoflavor = RPC_AUTH_UNIX;
3134 flavs[1].pseudoflavor = RPC_AUTH_NULL; 3134 flavs[1].pseudoflavor = RPC_AUTH_NULL;
3135 } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) { 3135 } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
3136 nflavs = 1; 3136 nflavs = 1;
3137 flavs[0].pseudoflavor 3137 flavs[0].pseudoflavor
3138 = svcauth_gss_flavor(exp->ex_client); 3138 = svcauth_gss_flavor(exp->ex_client);
3139 } else { 3139 } else {
3140 nflavs = 1; 3140 nflavs = 1;
3141 flavs[0].pseudoflavor 3141 flavs[0].pseudoflavor
3142 = exp->ex_client->flavour->flavour; 3142 = exp->ex_client->flavour->flavour;
3143 } 3143 }
3144 } 3144 }
3145 3145
3146 RESERVE_SPACE(4); 3146 RESERVE_SPACE(4);
3147 WRITE32(nflavs); 3147 WRITE32(nflavs);
3148 ADJUST_ARGS(); 3148 ADJUST_ARGS();
3149 for (i = 0; i < nflavs; i++) { 3149 for (i = 0; i < nflavs; i++) {
3150 u32 flav = flavs[i].pseudoflavor; 3150 u32 flav = flavs[i].pseudoflavor;
3151 struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav); 3151 struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
3152 3152
3153 if (gm) { 3153 if (gm) {
3154 RESERVE_SPACE(4); 3154 RESERVE_SPACE(4);
3155 WRITE32(RPC_AUTH_GSS); 3155 WRITE32(RPC_AUTH_GSS);
3156 ADJUST_ARGS(); 3156 ADJUST_ARGS();
3157 RESERVE_SPACE(4 + gm->gm_oid.len); 3157 RESERVE_SPACE(4 + gm->gm_oid.len);
3158 WRITE32(gm->gm_oid.len); 3158 WRITE32(gm->gm_oid.len);
3159 WRITEMEM(gm->gm_oid.data, gm->gm_oid.len); 3159 WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
3160 ADJUST_ARGS(); 3160 ADJUST_ARGS();
3161 RESERVE_SPACE(4); 3161 RESERVE_SPACE(4);
3162 WRITE32(0); /* qop */ 3162 WRITE32(0); /* qop */
3163 ADJUST_ARGS(); 3163 ADJUST_ARGS();
3164 RESERVE_SPACE(4); 3164 RESERVE_SPACE(4);
3165 WRITE32(gss_pseudoflavor_to_service(gm, flav)); 3165 WRITE32(gss_pseudoflavor_to_service(gm, flav));
3166 ADJUST_ARGS(); 3166 ADJUST_ARGS();
3167 gss_mech_put(gm); 3167 gss_mech_put(gm);
3168 } else { 3168 } else {
3169 RESERVE_SPACE(4); 3169 RESERVE_SPACE(4);
3170 WRITE32(flav); 3170 WRITE32(flav);
3171 ADJUST_ARGS(); 3171 ADJUST_ARGS();
3172 } 3172 }
3173 } 3173 }
3174 out: 3174 out:
3175 if (exp) 3175 if (exp)
3176 exp_put(exp); 3176 exp_put(exp);
3177 return nfserr; 3177 return nfserr;
3178 } 3178 }
3179 3179
3180 static __be32 3180 static __be32
3181 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, 3181 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3182 struct nfsd4_secinfo *secinfo) 3182 struct nfsd4_secinfo *secinfo)
3183 { 3183 {
3184 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp); 3184 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
3185 } 3185 }
3186 3186
3187 static __be32 3187 static __be32
3188 nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, 3188 nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3189 struct nfsd4_secinfo_no_name *secinfo) 3189 struct nfsd4_secinfo_no_name *secinfo)
3190 { 3190 {
3191 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp); 3191 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
3192 } 3192 }
3193 3193
3194 /* 3194 /*
3195 * The SETATTR encode routine is special -- it always encodes a bitmap, 3195 * The SETATTR encode routine is special -- it always encodes a bitmap,
3196 * regardless of the error status. 3196 * regardless of the error status.
3197 */ 3197 */
3198 static __be32 3198 static __be32
3199 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) 3199 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3200 { 3200 {
3201 __be32 *p; 3201 __be32 *p;
3202 3202
3203 RESERVE_SPACE(12); 3203 RESERVE_SPACE(12);
3204 if (nfserr) { 3204 if (nfserr) {
3205 WRITE32(2); 3205 WRITE32(2);
3206 WRITE32(0); 3206 WRITE32(0);
3207 WRITE32(0); 3207 WRITE32(0);
3208 } 3208 }
3209 else { 3209 else {
3210 WRITE32(2); 3210 WRITE32(2);
3211 WRITE32(setattr->sa_bmval[0]); 3211 WRITE32(setattr->sa_bmval[0]);
3212 WRITE32(setattr->sa_bmval[1]); 3212 WRITE32(setattr->sa_bmval[1]);
3213 } 3213 }
3214 ADJUST_ARGS(); 3214 ADJUST_ARGS();
3215 return nfserr; 3215 return nfserr;
3216 } 3216 }
3217 3217
3218 static __be32 3218 static __be32
3219 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) 3219 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3220 { 3220 {
3221 __be32 *p; 3221 __be32 *p;
3222 3222
3223 if (!nfserr) { 3223 if (!nfserr) {
3224 RESERVE_SPACE(8 + NFS4_VERIFIER_SIZE); 3224 RESERVE_SPACE(8 + NFS4_VERIFIER_SIZE);
3225 WRITEMEM(&scd->se_clientid, 8); 3225 WRITEMEM(&scd->se_clientid, 8);
3226 WRITEMEM(&scd->se_confirm, NFS4_VERIFIER_SIZE); 3226 WRITEMEM(&scd->se_confirm, NFS4_VERIFIER_SIZE);
3227 ADJUST_ARGS(); 3227 ADJUST_ARGS();
3228 } 3228 }
3229 else if (nfserr == nfserr_clid_inuse) { 3229 else if (nfserr == nfserr_clid_inuse) {
3230 RESERVE_SPACE(8); 3230 RESERVE_SPACE(8);
3231 WRITE32(0); 3231 WRITE32(0);
3232 WRITE32(0); 3232 WRITE32(0);
3233 ADJUST_ARGS(); 3233 ADJUST_ARGS();
3234 } 3234 }
3235 return nfserr; 3235 return nfserr;
3236 } 3236 }
3237 3237
3238 static __be32 3238 static __be32
3239 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) 3239 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3240 { 3240 {
3241 __be32 *p; 3241 __be32 *p;
3242 3242
3243 if (!nfserr) { 3243 if (!nfserr) {
3244 RESERVE_SPACE(16); 3244 RESERVE_SPACE(16);
3245 WRITE32(write->wr_bytes_written); 3245 WRITE32(write->wr_bytes_written);
3246 WRITE32(write->wr_how_written); 3246 WRITE32(write->wr_how_written);
3247 WRITEMEM(write->wr_verifier.data, NFS4_VERIFIER_SIZE); 3247 WRITEMEM(write->wr_verifier.data, NFS4_VERIFIER_SIZE);
3248 ADJUST_ARGS(); 3248 ADJUST_ARGS();
3249 } 3249 }
3250 return nfserr; 3250 return nfserr;
3251 } 3251 }
3252 3252
3253 static __be32 3253 static __be32
3254 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, 3254 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3255 struct nfsd4_exchange_id *exid) 3255 struct nfsd4_exchange_id *exid)
3256 { 3256 {
3257 __be32 *p; 3257 __be32 *p;
3258 char *major_id; 3258 char *major_id;
3259 char *server_scope; 3259 char *server_scope;
3260 int major_id_sz; 3260 int major_id_sz;
3261 int server_scope_sz; 3261 int server_scope_sz;
3262 uint64_t minor_id = 0; 3262 uint64_t minor_id = 0;
3263 3263
3264 if (nfserr) 3264 if (nfserr)
3265 return nfserr; 3265 return nfserr;
3266 3266
3267 major_id = utsname()->nodename; 3267 major_id = utsname()->nodename;
3268 major_id_sz = strlen(major_id); 3268 major_id_sz = strlen(major_id);
3269 server_scope = utsname()->nodename; 3269 server_scope = utsname()->nodename;
3270 server_scope_sz = strlen(server_scope); 3270 server_scope_sz = strlen(server_scope);
3271 3271
3272 RESERVE_SPACE( 3272 RESERVE_SPACE(
3273 8 /* eir_clientid */ + 3273 8 /* eir_clientid */ +
3274 4 /* eir_sequenceid */ + 3274 4 /* eir_sequenceid */ +
3275 4 /* eir_flags */ + 3275 4 /* eir_flags */ +
3276 4 /* spr_how (SP4_NONE) */ + 3276 4 /* spr_how (SP4_NONE) */ +
3277 8 /* so_minor_id */ + 3277 8 /* so_minor_id */ +
3278 4 /* so_major_id.len */ + 3278 4 /* so_major_id.len */ +
3279 (XDR_QUADLEN(major_id_sz) * 4) + 3279 (XDR_QUADLEN(major_id_sz) * 4) +
3280 4 /* eir_server_scope.len */ + 3280 4 /* eir_server_scope.len */ +
3281 (XDR_QUADLEN(server_scope_sz) * 4) + 3281 (XDR_QUADLEN(server_scope_sz) * 4) +
3282 4 /* eir_server_impl_id.count (0) */); 3282 4 /* eir_server_impl_id.count (0) */);
3283 3283
3284 WRITEMEM(&exid->clientid, 8); 3284 WRITEMEM(&exid->clientid, 8);
3285 WRITE32(exid->seqid); 3285 WRITE32(exid->seqid);
3286 WRITE32(exid->flags); 3286 WRITE32(exid->flags);
3287 3287
3288 /* state_protect4_r. Currently only support SP4_NONE */ 3288 /* state_protect4_r. Currently only support SP4_NONE */
3289 BUG_ON(exid->spa_how != SP4_NONE); 3289 BUG_ON(exid->spa_how != SP4_NONE);
3290 WRITE32(exid->spa_how); 3290 WRITE32(exid->spa_how);
3291 3291
3292 /* The server_owner struct */ 3292 /* The server_owner struct */
3293 WRITE64(minor_id); /* Minor id */ 3293 WRITE64(minor_id); /* Minor id */
3294 /* major id */ 3294 /* major id */
3295 WRITE32(major_id_sz); 3295 WRITE32(major_id_sz);
3296 WRITEMEM(major_id, major_id_sz); 3296 WRITEMEM(major_id, major_id_sz);
3297 3297
3298 /* Server scope */ 3298 /* Server scope */
3299 WRITE32(server_scope_sz); 3299 WRITE32(server_scope_sz);
3300 WRITEMEM(server_scope, server_scope_sz); 3300 WRITEMEM(server_scope, server_scope_sz);
3301 3301
3302 /* Implementation id */ 3302 /* Implementation id */
3303 WRITE32(0); /* zero length nfs_impl_id4 array */ 3303 WRITE32(0); /* zero length nfs_impl_id4 array */
3304 ADJUST_ARGS(); 3304 ADJUST_ARGS();
3305 return 0; 3305 return 0;
3306 } 3306 }
3307 3307
3308 static __be32 3308 static __be32
3309 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, 3309 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3310 struct nfsd4_create_session *sess) 3310 struct nfsd4_create_session *sess)
3311 { 3311 {
3312 __be32 *p; 3312 __be32 *p;
3313 3313
3314 if (nfserr) 3314 if (nfserr)
3315 return nfserr; 3315 return nfserr;
3316 3316
3317 RESERVE_SPACE(24); 3317 RESERVE_SPACE(24);
3318 WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3318 WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3319 WRITE32(sess->seqid); 3319 WRITE32(sess->seqid);
3320 WRITE32(sess->flags); 3320 WRITE32(sess->flags);
3321 ADJUST_ARGS(); 3321 ADJUST_ARGS();
3322 3322
3323 RESERVE_SPACE(28); 3323 RESERVE_SPACE(28);
3324 WRITE32(0); /* headerpadsz */ 3324 WRITE32(0); /* headerpadsz */
3325 WRITE32(sess->fore_channel.maxreq_sz); 3325 WRITE32(sess->fore_channel.maxreq_sz);
3326 WRITE32(sess->fore_channel.maxresp_sz); 3326 WRITE32(sess->fore_channel.maxresp_sz);
3327 WRITE32(sess->fore_channel.maxresp_cached); 3327 WRITE32(sess->fore_channel.maxresp_cached);
3328 WRITE32(sess->fore_channel.maxops); 3328 WRITE32(sess->fore_channel.maxops);
3329 WRITE32(sess->fore_channel.maxreqs); 3329 WRITE32(sess->fore_channel.maxreqs);
3330 WRITE32(sess->fore_channel.nr_rdma_attrs); 3330 WRITE32(sess->fore_channel.nr_rdma_attrs);
3331 ADJUST_ARGS(); 3331 ADJUST_ARGS();
3332 3332
3333 if (sess->fore_channel.nr_rdma_attrs) { 3333 if (sess->fore_channel.nr_rdma_attrs) {
3334 RESERVE_SPACE(4); 3334 RESERVE_SPACE(4);
3335 WRITE32(sess->fore_channel.rdma_attrs); 3335 WRITE32(sess->fore_channel.rdma_attrs);
3336 ADJUST_ARGS(); 3336 ADJUST_ARGS();
3337 } 3337 }
3338 3338
3339 RESERVE_SPACE(28); 3339 RESERVE_SPACE(28);
3340 WRITE32(0); /* headerpadsz */ 3340 WRITE32(0); /* headerpadsz */
3341 WRITE32(sess->back_channel.maxreq_sz); 3341 WRITE32(sess->back_channel.maxreq_sz);
3342 WRITE32(sess->back_channel.maxresp_sz); 3342 WRITE32(sess->back_channel.maxresp_sz);
3343 WRITE32(sess->back_channel.maxresp_cached); 3343 WRITE32(sess->back_channel.maxresp_cached);
3344 WRITE32(sess->back_channel.maxops); 3344 WRITE32(sess->back_channel.maxops);
3345 WRITE32(sess->back_channel.maxreqs); 3345 WRITE32(sess->back_channel.maxreqs);
3346 WRITE32(sess->back_channel.nr_rdma_attrs); 3346 WRITE32(sess->back_channel.nr_rdma_attrs);
3347 ADJUST_ARGS(); 3347 ADJUST_ARGS();
3348 3348
3349 if (sess->back_channel.nr_rdma_attrs) { 3349 if (sess->back_channel.nr_rdma_attrs) {
3350 RESERVE_SPACE(4); 3350 RESERVE_SPACE(4);
3351 WRITE32(sess->back_channel.rdma_attrs); 3351 WRITE32(sess->back_channel.rdma_attrs);
3352 ADJUST_ARGS(); 3352 ADJUST_ARGS();
3353 } 3353 }
3354 return 0; 3354 return 0;
3355 } 3355 }
3356 3356
3357 static __be32 3357 static __be32
3358 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, 3358 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3359 struct nfsd4_destroy_session *destroy_session) 3359 struct nfsd4_destroy_session *destroy_session)
3360 { 3360 {
3361 return nfserr; 3361 return nfserr;
3362 } 3362 }
3363 3363
3364 static __be32 3364 static __be32
3365 nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, 3365 nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr,
3366 struct nfsd4_free_stateid *free_stateid) 3366 struct nfsd4_free_stateid *free_stateid)
3367 { 3367 {
3368 __be32 *p; 3368 __be32 *p;
3369 3369
3370 if (nfserr) 3370 if (nfserr)
3371 return nfserr; 3371 return nfserr;
3372 3372
3373 RESERVE_SPACE(4); 3373 RESERVE_SPACE(4);
3374 WRITE32(nfserr); 3374 WRITE32(nfserr);
3375 ADJUST_ARGS(); 3375 ADJUST_ARGS();
3376 return nfserr; 3376 return nfserr;
3377 } 3377 }
3378 3378
3379 static __be32 3379 static __be32
3380 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3380 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3381 struct nfsd4_sequence *seq) 3381 struct nfsd4_sequence *seq)
3382 { 3382 {
3383 __be32 *p; 3383 __be32 *p;
3384 3384
3385 if (nfserr) 3385 if (nfserr)
3386 return nfserr; 3386 return nfserr;
3387 3387
3388 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20); 3388 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
3389 WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3389 WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3390 WRITE32(seq->seqid); 3390 WRITE32(seq->seqid);
3391 WRITE32(seq->slotid); 3391 WRITE32(seq->slotid);
3392 /* Note slotid's are numbered from zero: */ 3392 /* Note slotid's are numbered from zero: */
3393 WRITE32(seq->maxslots - 1); /* sr_highest_slotid */ 3393 WRITE32(seq->maxslots - 1); /* sr_highest_slotid */
3394 WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */ 3394 WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
3395 WRITE32(seq->status_flags); 3395 WRITE32(seq->status_flags);
3396 3396
3397 ADJUST_ARGS(); 3397 ADJUST_ARGS();
3398 resp->cstate.datap = p; /* DRC cache data pointer */ 3398 resp->cstate.datap = p; /* DRC cache data pointer */
3399 return 0; 3399 return 0;
3400 } 3400 }
3401 3401
3402 static __be32 3402 static __be32
3403 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, 3403 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3404 struct nfsd4_test_stateid *test_stateid) 3404 struct nfsd4_test_stateid *test_stateid)
3405 { 3405 {
3406 struct nfsd4_test_stateid_id *stateid, *next; 3406 struct nfsd4_test_stateid_id *stateid, *next;
3407 __be32 *p; 3407 __be32 *p;
3408 3408
3409 RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids)); 3409 RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
3410 *p++ = htonl(test_stateid->ts_num_ids); 3410 *p++ = htonl(test_stateid->ts_num_ids);
3411 3411
3412 list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) { 3412 list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
3413 *p++ = htonl(stateid->ts_id_status); 3413 *p++ = htonl(stateid->ts_id_status);
3414 } 3414 }
3415 3415
3416 ADJUST_ARGS(); 3416 ADJUST_ARGS();
3417 return nfserr; 3417 return nfserr;
3418 } 3418 }
3419 3419
3420 static __be32 3420 static __be32
3421 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p) 3421 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
3422 { 3422 {
3423 return nfserr; 3423 return nfserr;
3424 } 3424 }
3425 3425
3426 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); 3426 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
3427 3427
3428 /* 3428 /*
3429 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1 3429 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
3430 * since we don't need to filter out obsolete ops as this is 3430 * since we don't need to filter out obsolete ops as this is
3431 * done in the decoding phase. 3431 * done in the decoding phase.
3432 */ 3432 */
3433 static nfsd4_enc nfsd4_enc_ops[] = { 3433 static nfsd4_enc nfsd4_enc_ops[] = {
3434 [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access, 3434 [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access,
3435 [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close, 3435 [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close,
3436 [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit, 3436 [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit,
3437 [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create, 3437 [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create,
3438 [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop, 3438 [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop,
3439 [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop, 3439 [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop,
3440 [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr, 3440 [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr,
3441 [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh, 3441 [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh,
3442 [OP_LINK] = (nfsd4_enc)nfsd4_encode_link, 3442 [OP_LINK] = (nfsd4_enc)nfsd4_encode_link,
3443 [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock, 3443 [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock,
3444 [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt, 3444 [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt,
3445 [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku, 3445 [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku,
3446 [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop, 3446 [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop,
3447 [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, 3447 [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop,
3448 [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, 3448 [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop,
3449 [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, 3449 [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open,
3450 [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, 3450 [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop,
3451 [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, 3451 [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm,
3452 [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, 3452 [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade,
3453 [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, 3453 [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop,
3454 [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop, 3454 [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop,
3455 [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop, 3455 [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop,
3456 [OP_READ] = (nfsd4_enc)nfsd4_encode_read, 3456 [OP_READ] = (nfsd4_enc)nfsd4_encode_read,
3457 [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir, 3457 [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir,
3458 [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink, 3458 [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink,
3459 [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove, 3459 [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove,
3460 [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename, 3460 [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename,
3461 [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop, 3461 [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop,
3462 [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop, 3462 [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop,
3463 [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop, 3463 [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop,
3464 [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo, 3464 [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo,
3465 [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr, 3465 [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr,
3466 [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid, 3466 [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid,
3467 [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop, 3467 [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
3468 [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop, 3468 [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop,
3469 [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write, 3469 [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write,
3470 [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop, 3470 [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop,
3471 3471
3472 /* NFSv4.1 operations */ 3472 /* NFSv4.1 operations */
3473 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, 3473 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop,
3474 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session, 3474 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3475 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3475 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
3476 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3476 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
3477 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3477 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session,
3478 [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_free_stateid, 3478 [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_free_stateid,
3479 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3479 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
3480 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, 3480 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop,
3481 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, 3481 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
3482 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, 3482 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
3483 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, 3483 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
3484 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, 3484 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
3485 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name, 3485 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
3486 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, 3486 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
3487 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, 3487 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
3488 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid, 3488 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid,
3489 [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3489 [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
3490 [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop, 3490 [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop,
3491 [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop, 3491 [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop,
3492 }; 3492 };
3493 3493
3494 /* 3494 /*
3495 * Calculate the total amount of memory that the compound response has taken 3495 * Calculate the total amount of memory that the compound response has taken
3496 * after encoding the current operation with pad. 3496 * after encoding the current operation with pad.
3497 * 3497 *
3498 * pad: if operation is non-idempotent, pad was calculate by op_rsize_bop() 3498 * pad: if operation is non-idempotent, pad was calculate by op_rsize_bop()
3499 * which was specified at nfsd4_operation, else pad is zero. 3499 * which was specified at nfsd4_operation, else pad is zero.
3500 * 3500 *
3501 * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached. 3501 * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached.
3502 * 3502 *
3503 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3503 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3504 * will be at least a page and will therefore hold the xdr_buf head. 3504 * will be at least a page and will therefore hold the xdr_buf head.
3505 */ 3505 */
3506 int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) 3506 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3507 { 3507 {
3508 struct xdr_buf *xb = &resp->rqstp->rq_res; 3508 struct xdr_buf *xb = &resp->rqstp->rq_res;
3509 struct nfsd4_session *session = NULL; 3509 struct nfsd4_session *session = NULL;
3510 struct nfsd4_slot *slot = resp->cstate.slot; 3510 struct nfsd4_slot *slot = resp->cstate.slot;
3511 u32 length, tlen = 0; 3511 u32 length, tlen = 0;
3512 3512
3513 if (!nfsd4_has_session(&resp->cstate)) 3513 if (!nfsd4_has_session(&resp->cstate))
3514 return 0; 3514 return 0;
3515 3515
3516 session = resp->cstate.session; 3516 session = resp->cstate.session;
3517 if (session == NULL) 3517 if (session == NULL)
3518 return 0; 3518 return 0;
3519 3519
3520 if (xb->page_len == 0) { 3520 if (xb->page_len == 0) {
3521 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad; 3521 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
3522 } else { 3522 } else {
3523 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0) 3523 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3524 tlen = (char *)resp->p - (char *)xb->tail[0].iov_base; 3524 tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
3525 3525
3526 length = xb->head[0].iov_len + xb->page_len + tlen + pad; 3526 length = xb->head[0].iov_len + xb->page_len + tlen + pad;
3527 } 3527 }
3528 dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__, 3528 dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3529 length, xb->page_len, tlen, pad); 3529 length, xb->page_len, tlen, pad);
3530 3530
3531 if (length > session->se_fchannel.maxresp_sz) 3531 if (length > session->se_fchannel.maxresp_sz)
3532 return nfserr_rep_too_big; 3532 return nfserr_rep_too_big;
3533 3533
3534 if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) && 3534 if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
3535 length > session->se_fchannel.maxresp_cached) 3535 length > session->se_fchannel.maxresp_cached)
3536 return nfserr_rep_too_big_to_cache; 3536 return nfserr_rep_too_big_to_cache;
3537 3537
3538 return 0; 3538 return 0;
3539 } 3539 }
3540 3540
3541 void 3541 void
3542 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 3542 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3543 { 3543 {
3544 __be32 *statp; 3544 __be32 *statp;
3545 __be32 *p; 3545 __be32 *p;
3546 3546
3547 RESERVE_SPACE(8); 3547 RESERVE_SPACE(8);
3548 WRITE32(op->opnum); 3548 WRITE32(op->opnum);
3549 statp = p++; /* to be backfilled at the end */ 3549 statp = p++; /* to be backfilled at the end */
3550 ADJUST_ARGS(); 3550 ADJUST_ARGS();
3551 3551
3552 if (op->opnum == OP_ILLEGAL) 3552 if (op->opnum == OP_ILLEGAL)
3553 goto status; 3553 goto status;
3554 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) || 3554 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
3555 !nfsd4_enc_ops[op->opnum]); 3555 !nfsd4_enc_ops[op->opnum]);
3556 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u); 3556 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3557 /* nfsd4_check_drc_limit guarantees enough room for error status */ 3557 /* nfsd4_check_drc_limit guarantees enough room for error status */
3558 if (!op->status) 3558 if (!op->status)
3559 op->status = nfsd4_check_resp_size(resp, 0); 3559 op->status = nfsd4_check_resp_size(resp, 0);
3560 status: 3560 status:
3561 /* 3561 /*
3562 * Note: We write the status directly, instead of using WRITE32(), 3562 * Note: We write the status directly, instead of using WRITE32(),
3563 * since it is already in network byte order. 3563 * since it is already in network byte order.
3564 */ 3564 */
3565 *statp = op->status; 3565 *statp = op->status;
3566 } 3566 }
3567 3567
3568 /* 3568 /*
3569 * Encode the reply stored in the stateowner reply cache 3569 * Encode the reply stored in the stateowner reply cache
3570 * 3570 *
3571 * XDR note: do not encode rp->rp_buflen: the buffer contains the 3571 * XDR note: do not encode rp->rp_buflen: the buffer contains the
3572 * previously sent already encoded operation. 3572 * previously sent already encoded operation.
3573 * 3573 *
3574 * called with nfs4_lock_state() held 3574 * called with nfs4_lock_state() held
3575 */ 3575 */
3576 void 3576 void
3577 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 3577 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3578 { 3578 {
3579 __be32 *p; 3579 __be32 *p;
3580 struct nfs4_replay *rp = op->replay; 3580 struct nfs4_replay *rp = op->replay;
3581 3581
3582 BUG_ON(!rp); 3582 BUG_ON(!rp);
3583 3583
3584 RESERVE_SPACE(8); 3584 RESERVE_SPACE(8);
3585 WRITE32(op->opnum); 3585 WRITE32(op->opnum);
3586 *p++ = rp->rp_status; /* already xdr'ed */ 3586 *p++ = rp->rp_status; /* already xdr'ed */
3587 ADJUST_ARGS(); 3587 ADJUST_ARGS();
3588 3588
3589 RESERVE_SPACE(rp->rp_buflen); 3589 RESERVE_SPACE(rp->rp_buflen);
3590 WRITEMEM(rp->rp_buf, rp->rp_buflen); 3590 WRITEMEM(rp->rp_buf, rp->rp_buflen);
3591 ADJUST_ARGS(); 3591 ADJUST_ARGS();
3592 } 3592 }
3593 3593
3594 int 3594 int
3595 nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) 3595 nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
3596 { 3596 {
3597 return xdr_ressize_check(rqstp, p); 3597 return xdr_ressize_check(rqstp, p);
3598 } 3598 }
3599 3599
3600 int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) 3600 int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
3601 { 3601 {
3602 struct svc_rqst *rqstp = rq; 3602 struct svc_rqst *rqstp = rq;
3603 struct nfsd4_compoundargs *args = rqstp->rq_argp; 3603 struct nfsd4_compoundargs *args = rqstp->rq_argp;
3604 3604
3605 if (args->ops != args->iops) { 3605 if (args->ops != args->iops) {
3606 kfree(args->ops); 3606 kfree(args->ops);
3607 args->ops = args->iops; 3607 args->ops = args->iops;
3608 } 3608 }
3609 kfree(args->tmpp); 3609 kfree(args->tmpp);
3610 args->tmpp = NULL; 3610 args->tmpp = NULL;
3611 while (args->to_free) { 3611 while (args->to_free) {
3612 struct tmpbuf *tb = args->to_free; 3612 struct tmpbuf *tb = args->to_free;
3613 args->to_free = tb->next; 3613 args->to_free = tb->next;
3614 tb->release(tb->buf); 3614 tb->release(tb->buf);
3615 kfree(tb); 3615 kfree(tb);
3616 } 3616 }
3617 return 1; 3617 return 1;
3618 } 3618 }
3619 3619
3620 int 3620 int
3621 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) 3621 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
3622 { 3622 {
3623 args->p = p; 3623 args->p = p;
3624 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; 3624 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
3625 args->pagelist = rqstp->rq_arg.pages; 3625 args->pagelist = rqstp->rq_arg.pages;
3626 args->pagelen = rqstp->rq_arg.page_len; 3626 args->pagelen = rqstp->rq_arg.page_len;
3627 args->tmpp = NULL; 3627 args->tmpp = NULL;
3628 args->to_free = NULL; 3628 args->to_free = NULL;
3629 args->ops = args->iops; 3629 args->ops = args->iops;
3630 args->rqstp = rqstp; 3630 args->rqstp = rqstp;
3631 3631
3632 return !nfsd4_decode_compound(args); 3632 return !nfsd4_decode_compound(args);
3633 } 3633 }
3634 3634
3635 int 3635 int
3636 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp) 3636 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
3637 { 3637 {
3638 /* 3638 /*
3639 * All that remains is to write the tag and operation count... 3639 * All that remains is to write the tag and operation count...
3640 */ 3640 */
3641 struct nfsd4_compound_state *cs = &resp->cstate; 3641 struct nfsd4_compound_state *cs = &resp->cstate;
3642 struct kvec *iov; 3642 struct kvec *iov;
3643 p = resp->tagp; 3643 p = resp->tagp;
3644 *p++ = htonl(resp->taglen); 3644 *p++ = htonl(resp->taglen);
3645 memcpy(p, resp->tag, resp->taglen); 3645 memcpy(p, resp->tag, resp->taglen);
3646 p += XDR_QUADLEN(resp->taglen); 3646 p += XDR_QUADLEN(resp->taglen);
3647 *p++ = htonl(resp->opcnt); 3647 *p++ = htonl(resp->opcnt);
3648 3648
3649 if (rqstp->rq_res.page_len) 3649 if (rqstp->rq_res.page_len)
3650 iov = &rqstp->rq_res.tail[0]; 3650 iov = &rqstp->rq_res.tail[0];
3651 else 3651 else
3652 iov = &rqstp->rq_res.head[0]; 3652 iov = &rqstp->rq_res.head[0];
3653 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; 3653 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3654 BUG_ON(iov->iov_len > PAGE_SIZE); 3654 BUG_ON(iov->iov_len > PAGE_SIZE);
3655 if (nfsd4_has_session(cs)) { 3655 if (nfsd4_has_session(cs)) {
3656 if (cs->status != nfserr_replay_cache) { 3656 if (cs->status != nfserr_replay_cache) {
3657 nfsd4_store_cache_entry(resp); 3657 nfsd4_store_cache_entry(resp);
3658 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE; 3658 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
3659 } 3659 }
3660 /* Renew the clientid on success and on replay */ 3660 /* Renew the clientid on success and on replay */
3661 release_session_client(cs->session); 3661 release_session_client(cs->session);
3662 nfsd4_put_session(cs->session); 3662 nfsd4_put_session(cs->session);
3663 } 3663 }
3664 return 1; 3664 return 1;
3665 } 3665 }
3666 3666
3667 /* 3667 /*
3668 * Local variables: 3668 * Local variables:
3669 * c-basic-offset: 8 3669 * c-basic-offset: 8
3670 * End: 3670 * End:
3671 */ 3671 */
3672 3672
1 /* 1 /*
2 * Server-side types for NFSv4. 2 * Server-side types 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 */ 35 */
36 36
37 #ifndef _LINUX_NFSD_XDR4_H 37 #ifndef _LINUX_NFSD_XDR4_H
38 #define _LINUX_NFSD_XDR4_H 38 #define _LINUX_NFSD_XDR4_H
39 39
40 #include "state.h" 40 #include "state.h"
41 #include "nfsd.h" 41 #include "nfsd.h"
42 42
43 #define NFSD4_MAX_TAGLEN 128 43 #define NFSD4_MAX_TAGLEN 128
44 #define XDR_LEN(n) (((n) + 3) & ~3) 44 #define XDR_LEN(n) (((n) + 3) & ~3)
45 45
46 #define CURRENT_STATE_ID_FLAG (1<<0) 46 #define CURRENT_STATE_ID_FLAG (1<<0)
47 #define SAVED_STATE_ID_FLAG (1<<1) 47 #define SAVED_STATE_ID_FLAG (1<<1)
48 48
49 #define SET_STATE_ID(c, f) ((c)->sid_flags |= (f)) 49 #define SET_STATE_ID(c, f) ((c)->sid_flags |= (f))
50 #define HAS_STATE_ID(c, f) ((c)->sid_flags & (f)) 50 #define HAS_STATE_ID(c, f) ((c)->sid_flags & (f))
51 #define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f)) 51 #define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f))
52 52
53 struct nfsd4_compound_state { 53 struct nfsd4_compound_state {
54 struct svc_fh current_fh; 54 struct svc_fh current_fh;
55 struct svc_fh save_fh; 55 struct svc_fh save_fh;
56 struct nfs4_stateowner *replay_owner; 56 struct nfs4_stateowner *replay_owner;
57 /* For sessions DRC */ 57 /* For sessions DRC */
58 struct nfsd4_session *session; 58 struct nfsd4_session *session;
59 struct nfsd4_slot *slot; 59 struct nfsd4_slot *slot;
60 __be32 *datap; 60 __be32 *datap;
61 size_t iovlen; 61 size_t iovlen;
62 u32 minorversion; 62 u32 minorversion;
63 u32 status; 63 __be32 status;
64 stateid_t current_stateid; 64 stateid_t current_stateid;
65 stateid_t save_stateid; 65 stateid_t save_stateid;
66 /* to indicate current and saved state id presents */ 66 /* to indicate current and saved state id presents */
67 u32 sid_flags; 67 u32 sid_flags;
68 }; 68 };
69 69
70 static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs) 70 static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
71 { 71 {
72 return cs->slot != NULL; 72 return cs->slot != NULL;
73 } 73 }
74 74
75 struct nfsd4_change_info { 75 struct nfsd4_change_info {
76 u32 atomic; 76 u32 atomic;
77 bool change_supported; 77 bool change_supported;
78 u32 before_ctime_sec; 78 u32 before_ctime_sec;
79 u32 before_ctime_nsec; 79 u32 before_ctime_nsec;
80 u64 before_change; 80 u64 before_change;
81 u32 after_ctime_sec; 81 u32 after_ctime_sec;
82 u32 after_ctime_nsec; 82 u32 after_ctime_nsec;
83 u64 after_change; 83 u64 after_change;
84 }; 84 };
85 85
86 struct nfsd4_access { 86 struct nfsd4_access {
87 u32 ac_req_access; /* request */ 87 u32 ac_req_access; /* request */
88 u32 ac_supported; /* response */ 88 u32 ac_supported; /* response */
89 u32 ac_resp_access; /* response */ 89 u32 ac_resp_access; /* response */
90 }; 90 };
91 91
92 struct nfsd4_close { 92 struct nfsd4_close {
93 u32 cl_seqid; /* request */ 93 u32 cl_seqid; /* request */
94 stateid_t cl_stateid; /* request+response */ 94 stateid_t cl_stateid; /* request+response */
95 }; 95 };
96 96
97 struct nfsd4_commit { 97 struct nfsd4_commit {
98 u64 co_offset; /* request */ 98 u64 co_offset; /* request */
99 u32 co_count; /* request */ 99 u32 co_count; /* request */
100 nfs4_verifier co_verf; /* response */ 100 nfs4_verifier co_verf; /* response */
101 }; 101 };
102 102
103 struct nfsd4_create { 103 struct nfsd4_create {
104 u32 cr_namelen; /* request */ 104 u32 cr_namelen; /* request */
105 char * cr_name; /* request */ 105 char * cr_name; /* request */
106 u32 cr_type; /* request */ 106 u32 cr_type; /* request */
107 union { /* request */ 107 union { /* request */
108 struct { 108 struct {
109 u32 namelen; 109 u32 namelen;
110 char *name; 110 char *name;
111 } link; /* NF4LNK */ 111 } link; /* NF4LNK */
112 struct { 112 struct {
113 u32 specdata1; 113 u32 specdata1;
114 u32 specdata2; 114 u32 specdata2;
115 } dev; /* NF4BLK, NF4CHR */ 115 } dev; /* NF4BLK, NF4CHR */
116 } u; 116 } u;
117 u32 cr_bmval[3]; /* request */ 117 u32 cr_bmval[3]; /* request */
118 struct iattr cr_iattr; /* request */ 118 struct iattr cr_iattr; /* request */
119 struct nfsd4_change_info cr_cinfo; /* response */ 119 struct nfsd4_change_info cr_cinfo; /* response */
120 struct nfs4_acl *cr_acl; 120 struct nfs4_acl *cr_acl;
121 }; 121 };
122 #define cr_linklen u.link.namelen 122 #define cr_linklen u.link.namelen
123 #define cr_linkname u.link.name 123 #define cr_linkname u.link.name
124 #define cr_specdata1 u.dev.specdata1 124 #define cr_specdata1 u.dev.specdata1
125 #define cr_specdata2 u.dev.specdata2 125 #define cr_specdata2 u.dev.specdata2
126 126
127 struct nfsd4_delegreturn { 127 struct nfsd4_delegreturn {
128 stateid_t dr_stateid; 128 stateid_t dr_stateid;
129 }; 129 };
130 130
131 struct nfsd4_getattr { 131 struct nfsd4_getattr {
132 u32 ga_bmval[3]; /* request */ 132 u32 ga_bmval[3]; /* request */
133 struct svc_fh *ga_fhp; /* response */ 133 struct svc_fh *ga_fhp; /* response */
134 }; 134 };
135 135
136 struct nfsd4_link { 136 struct nfsd4_link {
137 u32 li_namelen; /* request */ 137 u32 li_namelen; /* request */
138 char * li_name; /* request */ 138 char * li_name; /* request */
139 struct nfsd4_change_info li_cinfo; /* response */ 139 struct nfsd4_change_info li_cinfo; /* response */
140 }; 140 };
141 141
142 struct nfsd4_lock_denied { 142 struct nfsd4_lock_denied {
143 clientid_t ld_clientid; 143 clientid_t ld_clientid;
144 struct xdr_netobj ld_owner; 144 struct xdr_netobj ld_owner;
145 u64 ld_start; 145 u64 ld_start;
146 u64 ld_length; 146 u64 ld_length;
147 u32 ld_type; 147 u32 ld_type;
148 }; 148 };
149 149
150 struct nfsd4_lock { 150 struct nfsd4_lock {
151 /* request */ 151 /* request */
152 u32 lk_type; 152 u32 lk_type;
153 u32 lk_reclaim; /* boolean */ 153 u32 lk_reclaim; /* boolean */
154 u64 lk_offset; 154 u64 lk_offset;
155 u64 lk_length; 155 u64 lk_length;
156 u32 lk_is_new; 156 u32 lk_is_new;
157 union { 157 union {
158 struct { 158 struct {
159 u32 open_seqid; 159 u32 open_seqid;
160 stateid_t open_stateid; 160 stateid_t open_stateid;
161 u32 lock_seqid; 161 u32 lock_seqid;
162 clientid_t clientid; 162 clientid_t clientid;
163 struct xdr_netobj owner; 163 struct xdr_netobj owner;
164 } new; 164 } new;
165 struct { 165 struct {
166 stateid_t lock_stateid; 166 stateid_t lock_stateid;
167 u32 lock_seqid; 167 u32 lock_seqid;
168 } old; 168 } old;
169 } v; 169 } v;
170 170
171 /* response */ 171 /* response */
172 union { 172 union {
173 struct { 173 struct {
174 stateid_t stateid; 174 stateid_t stateid;
175 } ok; 175 } ok;
176 struct nfsd4_lock_denied denied; 176 struct nfsd4_lock_denied denied;
177 } u; 177 } u;
178 }; 178 };
179 #define lk_new_open_seqid v.new.open_seqid 179 #define lk_new_open_seqid v.new.open_seqid
180 #define lk_new_open_stateid v.new.open_stateid 180 #define lk_new_open_stateid v.new.open_stateid
181 #define lk_new_lock_seqid v.new.lock_seqid 181 #define lk_new_lock_seqid v.new.lock_seqid
182 #define lk_new_clientid v.new.clientid 182 #define lk_new_clientid v.new.clientid
183 #define lk_new_owner v.new.owner 183 #define lk_new_owner v.new.owner
184 #define lk_old_lock_stateid v.old.lock_stateid 184 #define lk_old_lock_stateid v.old.lock_stateid
185 #define lk_old_lock_seqid v.old.lock_seqid 185 #define lk_old_lock_seqid v.old.lock_seqid
186 186
187 #define lk_rflags u.ok.rflags 187 #define lk_rflags u.ok.rflags
188 #define lk_resp_stateid u.ok.stateid 188 #define lk_resp_stateid u.ok.stateid
189 #define lk_denied u.denied 189 #define lk_denied u.denied
190 190
191 191
192 struct nfsd4_lockt { 192 struct nfsd4_lockt {
193 u32 lt_type; 193 u32 lt_type;
194 clientid_t lt_clientid; 194 clientid_t lt_clientid;
195 struct xdr_netobj lt_owner; 195 struct xdr_netobj lt_owner;
196 u64 lt_offset; 196 u64 lt_offset;
197 u64 lt_length; 197 u64 lt_length;
198 struct nfsd4_lock_denied lt_denied; 198 struct nfsd4_lock_denied lt_denied;
199 }; 199 };
200 200
201 201
202 struct nfsd4_locku { 202 struct nfsd4_locku {
203 u32 lu_type; 203 u32 lu_type;
204 u32 lu_seqid; 204 u32 lu_seqid;
205 stateid_t lu_stateid; 205 stateid_t lu_stateid;
206 u64 lu_offset; 206 u64 lu_offset;
207 u64 lu_length; 207 u64 lu_length;
208 }; 208 };
209 209
210 210
211 struct nfsd4_lookup { 211 struct nfsd4_lookup {
212 u32 lo_len; /* request */ 212 u32 lo_len; /* request */
213 char * lo_name; /* request */ 213 char * lo_name; /* request */
214 }; 214 };
215 215
216 struct nfsd4_putfh { 216 struct nfsd4_putfh {
217 u32 pf_fhlen; /* request */ 217 u32 pf_fhlen; /* request */
218 char *pf_fhval; /* request */ 218 char *pf_fhval; /* request */
219 }; 219 };
220 220
221 struct nfsd4_open { 221 struct nfsd4_open {
222 u32 op_claim_type; /* request */ 222 u32 op_claim_type; /* request */
223 struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */ 223 struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */
224 u32 op_delegate_type; /* request - CLAIM_PREV only */ 224 u32 op_delegate_type; /* request - CLAIM_PREV only */
225 stateid_t op_delegate_stateid; /* request - response */ 225 stateid_t op_delegate_stateid; /* request - response */
226 u32 op_why_no_deleg; /* response - DELEG_NONE_EXT only */ 226 u32 op_why_no_deleg; /* response - DELEG_NONE_EXT only */
227 u32 op_create; /* request */ 227 u32 op_create; /* request */
228 u32 op_createmode; /* request */ 228 u32 op_createmode; /* request */
229 u32 op_bmval[3]; /* request */ 229 u32 op_bmval[3]; /* request */
230 struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ 230 struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
231 nfs4_verifier op_verf __attribute__((aligned(32))); 231 nfs4_verifier op_verf __attribute__((aligned(32)));
232 /* EXCLUSIVE4 */ 232 /* EXCLUSIVE4 */
233 clientid_t op_clientid; /* request */ 233 clientid_t op_clientid; /* request */
234 struct xdr_netobj op_owner; /* request */ 234 struct xdr_netobj op_owner; /* request */
235 u32 op_seqid; /* request */ 235 u32 op_seqid; /* request */
236 u32 op_share_access; /* request */ 236 u32 op_share_access; /* request */
237 u32 op_share_deny; /* request */ 237 u32 op_share_deny; /* request */
238 u32 op_deleg_want; /* request */ 238 u32 op_deleg_want; /* request */
239 stateid_t op_stateid; /* response */ 239 stateid_t op_stateid; /* response */
240 u32 op_recall; /* recall */ 240 u32 op_recall; /* recall */
241 struct nfsd4_change_info op_cinfo; /* response */ 241 struct nfsd4_change_info op_cinfo; /* response */
242 u32 op_rflags; /* response */ 242 u32 op_rflags; /* response */
243 bool op_truncate; /* used during processing */ 243 bool op_truncate; /* used during processing */
244 bool op_created; /* used during processing */ 244 bool op_created; /* used during processing */
245 struct nfs4_openowner *op_openowner; /* used during processing */ 245 struct nfs4_openowner *op_openowner; /* used during processing */
246 struct nfs4_file *op_file; /* used during processing */ 246 struct nfs4_file *op_file; /* used during processing */
247 struct nfs4_ol_stateid *op_stp; /* used during processing */ 247 struct nfs4_ol_stateid *op_stp; /* used during processing */
248 struct nfs4_acl *op_acl; 248 struct nfs4_acl *op_acl;
249 }; 249 };
250 #define op_iattr iattr 250 #define op_iattr iattr
251 251
252 struct nfsd4_open_confirm { 252 struct nfsd4_open_confirm {
253 stateid_t oc_req_stateid /* request */; 253 stateid_t oc_req_stateid /* request */;
254 u32 oc_seqid /* request */; 254 u32 oc_seqid /* request */;
255 stateid_t oc_resp_stateid /* response */; 255 stateid_t oc_resp_stateid /* response */;
256 }; 256 };
257 257
258 struct nfsd4_open_downgrade { 258 struct nfsd4_open_downgrade {
259 stateid_t od_stateid; 259 stateid_t od_stateid;
260 u32 od_seqid; 260 u32 od_seqid;
261 u32 od_share_access; /* request */ 261 u32 od_share_access; /* request */
262 u32 od_deleg_want; /* request */ 262 u32 od_deleg_want; /* request */
263 u32 od_share_deny; /* request */ 263 u32 od_share_deny; /* request */
264 }; 264 };
265 265
266 266
267 struct nfsd4_read { 267 struct nfsd4_read {
268 stateid_t rd_stateid; /* request */ 268 stateid_t rd_stateid; /* request */
269 u64 rd_offset; /* request */ 269 u64 rd_offset; /* request */
270 u32 rd_length; /* request */ 270 u32 rd_length; /* request */
271 int rd_vlen; 271 int rd_vlen;
272 struct file *rd_filp; 272 struct file *rd_filp;
273 273
274 struct svc_rqst *rd_rqstp; /* response */ 274 struct svc_rqst *rd_rqstp; /* response */
275 struct svc_fh * rd_fhp; /* response */ 275 struct svc_fh * rd_fhp; /* response */
276 }; 276 };
277 277
278 struct nfsd4_readdir { 278 struct nfsd4_readdir {
279 u64 rd_cookie; /* request */ 279 u64 rd_cookie; /* request */
280 nfs4_verifier rd_verf; /* request */ 280 nfs4_verifier rd_verf; /* request */
281 u32 rd_dircount; /* request */ 281 u32 rd_dircount; /* request */
282 u32 rd_maxcount; /* request */ 282 u32 rd_maxcount; /* request */
283 u32 rd_bmval[3]; /* request */ 283 u32 rd_bmval[3]; /* request */
284 struct svc_rqst *rd_rqstp; /* response */ 284 struct svc_rqst *rd_rqstp; /* response */
285 struct svc_fh * rd_fhp; /* response */ 285 struct svc_fh * rd_fhp; /* response */
286 286
287 struct readdir_cd common; 287 struct readdir_cd common;
288 __be32 * buffer; 288 __be32 * buffer;
289 int buflen; 289 int buflen;
290 __be32 * offset; 290 __be32 * offset;
291 }; 291 };
292 292
293 struct nfsd4_release_lockowner { 293 struct nfsd4_release_lockowner {
294 clientid_t rl_clientid; 294 clientid_t rl_clientid;
295 struct xdr_netobj rl_owner; 295 struct xdr_netobj rl_owner;
296 }; 296 };
297 struct nfsd4_readlink { 297 struct nfsd4_readlink {
298 struct svc_rqst *rl_rqstp; /* request */ 298 struct svc_rqst *rl_rqstp; /* request */
299 struct svc_fh * rl_fhp; /* request */ 299 struct svc_fh * rl_fhp; /* request */
300 }; 300 };
301 301
302 struct nfsd4_remove { 302 struct nfsd4_remove {
303 u32 rm_namelen; /* request */ 303 u32 rm_namelen; /* request */
304 char * rm_name; /* request */ 304 char * rm_name; /* request */
305 struct nfsd4_change_info rm_cinfo; /* response */ 305 struct nfsd4_change_info rm_cinfo; /* response */
306 }; 306 };
307 307
308 struct nfsd4_rename { 308 struct nfsd4_rename {
309 u32 rn_snamelen; /* request */ 309 u32 rn_snamelen; /* request */
310 char * rn_sname; /* request */ 310 char * rn_sname; /* request */
311 u32 rn_tnamelen; /* request */ 311 u32 rn_tnamelen; /* request */
312 char * rn_tname; /* request */ 312 char * rn_tname; /* request */
313 struct nfsd4_change_info rn_sinfo; /* response */ 313 struct nfsd4_change_info rn_sinfo; /* response */
314 struct nfsd4_change_info rn_tinfo; /* response */ 314 struct nfsd4_change_info rn_tinfo; /* response */
315 }; 315 };
316 316
317 struct nfsd4_secinfo { 317 struct nfsd4_secinfo {
318 u32 si_namelen; /* request */ 318 u32 si_namelen; /* request */
319 char *si_name; /* request */ 319 char *si_name; /* request */
320 struct svc_export *si_exp; /* response */ 320 struct svc_export *si_exp; /* response */
321 }; 321 };
322 322
323 struct nfsd4_secinfo_no_name { 323 struct nfsd4_secinfo_no_name {
324 u32 sin_style; /* request */ 324 u32 sin_style; /* request */
325 struct svc_export *sin_exp; /* response */ 325 struct svc_export *sin_exp; /* response */
326 }; 326 };
327 327
328 struct nfsd4_setattr { 328 struct nfsd4_setattr {
329 stateid_t sa_stateid; /* request */ 329 stateid_t sa_stateid; /* request */
330 u32 sa_bmval[3]; /* request */ 330 u32 sa_bmval[3]; /* request */
331 struct iattr sa_iattr; /* request */ 331 struct iattr sa_iattr; /* request */
332 struct nfs4_acl *sa_acl; 332 struct nfs4_acl *sa_acl;
333 }; 333 };
334 334
335 struct nfsd4_setclientid { 335 struct nfsd4_setclientid {
336 nfs4_verifier se_verf; /* request */ 336 nfs4_verifier se_verf; /* request */
337 struct xdr_netobj se_name; 337 struct xdr_netobj se_name;
338 u32 se_callback_prog; /* request */ 338 u32 se_callback_prog; /* request */
339 u32 se_callback_netid_len; /* request */ 339 u32 se_callback_netid_len; /* request */
340 char * se_callback_netid_val; /* request */ 340 char * se_callback_netid_val; /* request */
341 u32 se_callback_addr_len; /* request */ 341 u32 se_callback_addr_len; /* request */
342 char * se_callback_addr_val; /* request */ 342 char * se_callback_addr_val; /* request */
343 u32 se_callback_ident; /* request */ 343 u32 se_callback_ident; /* request */
344 clientid_t se_clientid; /* response */ 344 clientid_t se_clientid; /* response */
345 nfs4_verifier se_confirm; /* response */ 345 nfs4_verifier se_confirm; /* response */
346 }; 346 };
347 347
348 struct nfsd4_setclientid_confirm { 348 struct nfsd4_setclientid_confirm {
349 clientid_t sc_clientid; 349 clientid_t sc_clientid;
350 nfs4_verifier sc_confirm; 350 nfs4_verifier sc_confirm;
351 }; 351 };
352 352
353 struct nfsd4_saved_compoundargs { 353 struct nfsd4_saved_compoundargs {
354 __be32 *p; 354 __be32 *p;
355 __be32 *end; 355 __be32 *end;
356 int pagelen; 356 int pagelen;
357 struct page **pagelist; 357 struct page **pagelist;
358 }; 358 };
359 359
360 struct nfsd4_test_stateid_id { 360 struct nfsd4_test_stateid_id {
361 __be32 ts_id_status; 361 __be32 ts_id_status;
362 stateid_t ts_id_stateid; 362 stateid_t ts_id_stateid;
363 struct list_head ts_id_list; 363 struct list_head ts_id_list;
364 }; 364 };
365 365
366 struct nfsd4_test_stateid { 366 struct nfsd4_test_stateid {
367 __be32 ts_num_ids; 367 u32 ts_num_ids;
368 struct list_head ts_stateid_list; 368 struct list_head ts_stateid_list;
369 }; 369 };
370 370
371 struct nfsd4_free_stateid { 371 struct nfsd4_free_stateid {
372 stateid_t fr_stateid; /* request */ 372 stateid_t fr_stateid; /* request */
373 __be32 fr_status; /* response */ 373 __be32 fr_status; /* response */
374 }; 374 };
375 375
376 /* also used for NVERIFY */ 376 /* also used for NVERIFY */
377 struct nfsd4_verify { 377 struct nfsd4_verify {
378 u32 ve_bmval[3]; /* request */ 378 u32 ve_bmval[3]; /* request */
379 u32 ve_attrlen; /* request */ 379 u32 ve_attrlen; /* request */
380 char * ve_attrval; /* request */ 380 char * ve_attrval; /* request */
381 }; 381 };
382 382
383 struct nfsd4_write { 383 struct nfsd4_write {
384 stateid_t wr_stateid; /* request */ 384 stateid_t wr_stateid; /* request */
385 u64 wr_offset; /* request */ 385 u64 wr_offset; /* request */
386 u32 wr_stable_how; /* request */ 386 u32 wr_stable_how; /* request */
387 u32 wr_buflen; /* request */ 387 u32 wr_buflen; /* request */
388 int wr_vlen; 388 int wr_vlen;
389 389
390 u32 wr_bytes_written; /* response */ 390 u32 wr_bytes_written; /* response */
391 u32 wr_how_written; /* response */ 391 u32 wr_how_written; /* response */
392 nfs4_verifier wr_verifier; /* response */ 392 nfs4_verifier wr_verifier; /* response */
393 }; 393 };
394 394
395 struct nfsd4_exchange_id { 395 struct nfsd4_exchange_id {
396 nfs4_verifier verifier; 396 nfs4_verifier verifier;
397 struct xdr_netobj clname; 397 struct xdr_netobj clname;
398 u32 flags; 398 u32 flags;
399 clientid_t clientid; 399 clientid_t clientid;
400 u32 seqid; 400 u32 seqid;
401 int spa_how; 401 int spa_how;
402 }; 402 };
403 403
404 struct nfsd4_sequence { 404 struct nfsd4_sequence {
405 struct nfs4_sessionid sessionid; /* request/response */ 405 struct nfs4_sessionid sessionid; /* request/response */
406 u32 seqid; /* request/response */ 406 u32 seqid; /* request/response */
407 u32 slotid; /* request/response */ 407 u32 slotid; /* request/response */
408 u32 maxslots; /* request/response */ 408 u32 maxslots; /* request/response */
409 u32 cachethis; /* request */ 409 u32 cachethis; /* request */
410 #if 0 410 #if 0
411 u32 target_maxslots; /* response */ 411 u32 target_maxslots; /* response */
412 #endif /* not yet */ 412 #endif /* not yet */
413 u32 status_flags; /* response */ 413 u32 status_flags; /* response */
414 }; 414 };
415 415
416 struct nfsd4_destroy_session { 416 struct nfsd4_destroy_session {
417 struct nfs4_sessionid sessionid; 417 struct nfs4_sessionid sessionid;
418 }; 418 };
419 419
420 struct nfsd4_destroy_clientid { 420 struct nfsd4_destroy_clientid {
421 clientid_t clientid; 421 clientid_t clientid;
422 }; 422 };
423 423
424 struct nfsd4_reclaim_complete { 424 struct nfsd4_reclaim_complete {
425 u32 rca_one_fs; 425 u32 rca_one_fs;
426 }; 426 };
427 427
428 struct nfsd4_op { 428 struct nfsd4_op {
429 int opnum; 429 int opnum;
430 __be32 status; 430 __be32 status;
431 union { 431 union {
432 struct nfsd4_access access; 432 struct nfsd4_access access;
433 struct nfsd4_close close; 433 struct nfsd4_close close;
434 struct nfsd4_commit commit; 434 struct nfsd4_commit commit;
435 struct nfsd4_create create; 435 struct nfsd4_create create;
436 struct nfsd4_delegreturn delegreturn; 436 struct nfsd4_delegreturn delegreturn;
437 struct nfsd4_getattr getattr; 437 struct nfsd4_getattr getattr;
438 struct svc_fh * getfh; 438 struct svc_fh * getfh;
439 struct nfsd4_link link; 439 struct nfsd4_link link;
440 struct nfsd4_lock lock; 440 struct nfsd4_lock lock;
441 struct nfsd4_lockt lockt; 441 struct nfsd4_lockt lockt;
442 struct nfsd4_locku locku; 442 struct nfsd4_locku locku;
443 struct nfsd4_lookup lookup; 443 struct nfsd4_lookup lookup;
444 struct nfsd4_verify nverify; 444 struct nfsd4_verify nverify;
445 struct nfsd4_open open; 445 struct nfsd4_open open;
446 struct nfsd4_open_confirm open_confirm; 446 struct nfsd4_open_confirm open_confirm;
447 struct nfsd4_open_downgrade open_downgrade; 447 struct nfsd4_open_downgrade open_downgrade;
448 struct nfsd4_putfh putfh; 448 struct nfsd4_putfh putfh;
449 struct nfsd4_read read; 449 struct nfsd4_read read;
450 struct nfsd4_readdir readdir; 450 struct nfsd4_readdir readdir;
451 struct nfsd4_readlink readlink; 451 struct nfsd4_readlink readlink;
452 struct nfsd4_remove remove; 452 struct nfsd4_remove remove;
453 struct nfsd4_rename rename; 453 struct nfsd4_rename rename;
454 clientid_t renew; 454 clientid_t renew;
455 struct nfsd4_secinfo secinfo; 455 struct nfsd4_secinfo secinfo;
456 struct nfsd4_setattr setattr; 456 struct nfsd4_setattr setattr;
457 struct nfsd4_setclientid setclientid; 457 struct nfsd4_setclientid setclientid;
458 struct nfsd4_setclientid_confirm setclientid_confirm; 458 struct nfsd4_setclientid_confirm setclientid_confirm;
459 struct nfsd4_verify verify; 459 struct nfsd4_verify verify;
460 struct nfsd4_write write; 460 struct nfsd4_write write;
461 struct nfsd4_release_lockowner release_lockowner; 461 struct nfsd4_release_lockowner release_lockowner;
462 462
463 /* NFSv4.1 */ 463 /* NFSv4.1 */
464 struct nfsd4_exchange_id exchange_id; 464 struct nfsd4_exchange_id exchange_id;
465 struct nfsd4_bind_conn_to_session bind_conn_to_session; 465 struct nfsd4_bind_conn_to_session bind_conn_to_session;
466 struct nfsd4_create_session create_session; 466 struct nfsd4_create_session create_session;
467 struct nfsd4_destroy_session destroy_session; 467 struct nfsd4_destroy_session destroy_session;
468 struct nfsd4_sequence sequence; 468 struct nfsd4_sequence sequence;
469 struct nfsd4_reclaim_complete reclaim_complete; 469 struct nfsd4_reclaim_complete reclaim_complete;
470 struct nfsd4_test_stateid test_stateid; 470 struct nfsd4_test_stateid test_stateid;
471 struct nfsd4_free_stateid free_stateid; 471 struct nfsd4_free_stateid free_stateid;
472 } u; 472 } u;
473 struct nfs4_replay * replay; 473 struct nfs4_replay * replay;
474 }; 474 };
475 475
476 bool nfsd4_cache_this_op(struct nfsd4_op *); 476 bool nfsd4_cache_this_op(struct nfsd4_op *);
477 477
478 struct nfsd4_compoundargs { 478 struct nfsd4_compoundargs {
479 /* scratch variables for XDR decode */ 479 /* scratch variables for XDR decode */
480 __be32 * p; 480 __be32 * p;
481 __be32 * end; 481 __be32 * end;
482 struct page ** pagelist; 482 struct page ** pagelist;
483 int pagelen; 483 int pagelen;
484 __be32 tmp[8]; 484 __be32 tmp[8];
485 __be32 * tmpp; 485 __be32 * tmpp;
486 struct tmpbuf { 486 struct tmpbuf {
487 struct tmpbuf *next; 487 struct tmpbuf *next;
488 void (*release)(const void *); 488 void (*release)(const void *);
489 void *buf; 489 void *buf;
490 } *to_free; 490 } *to_free;
491 491
492 struct svc_rqst *rqstp; 492 struct svc_rqst *rqstp;
493 493
494 u32 taglen; 494 u32 taglen;
495 char * tag; 495 char * tag;
496 u32 minorversion; 496 u32 minorversion;
497 u32 opcnt; 497 u32 opcnt;
498 struct nfsd4_op *ops; 498 struct nfsd4_op *ops;
499 struct nfsd4_op iops[8]; 499 struct nfsd4_op iops[8];
500 int cachetype; 500 int cachetype;
501 }; 501 };
502 502
503 struct nfsd4_compoundres { 503 struct nfsd4_compoundres {
504 /* scratch variables for XDR encode */ 504 /* scratch variables for XDR encode */
505 __be32 * p; 505 __be32 * p;
506 __be32 * end; 506 __be32 * end;
507 struct xdr_buf * xbuf; 507 struct xdr_buf * xbuf;
508 struct svc_rqst * rqstp; 508 struct svc_rqst * rqstp;
509 509
510 u32 taglen; 510 u32 taglen;
511 char * tag; 511 char * tag;
512 u32 opcnt; 512 u32 opcnt;
513 __be32 * tagp; /* tag, opcount encode location */ 513 __be32 * tagp; /* tag, opcount encode location */
514 struct nfsd4_compound_state cstate; 514 struct nfsd4_compound_state cstate;
515 }; 515 };
516 516
517 static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp) 517 static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
518 { 518 {
519 struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; 519 struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
520 return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE; 520 return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE;
521 } 521 }
522 522
523 static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) 523 static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
524 { 524 {
525 return !(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS) 525 return !(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
526 || nfsd4_is_solo_sequence(resp); 526 || nfsd4_is_solo_sequence(resp);
527 } 527 }
528 528
529 #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) 529 #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)
530 530
531 static inline void 531 static inline void
532 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) 532 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
533 { 533 {
534 BUG_ON(!fhp->fh_pre_saved); 534 BUG_ON(!fhp->fh_pre_saved);
535 cinfo->atomic = fhp->fh_post_saved; 535 cinfo->atomic = fhp->fh_post_saved;
536 cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); 536 cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
537 537
538 cinfo->before_change = fhp->fh_pre_change; 538 cinfo->before_change = fhp->fh_pre_change;
539 cinfo->after_change = fhp->fh_post_change; 539 cinfo->after_change = fhp->fh_post_change;
540 cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; 540 cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
541 cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; 541 cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
542 cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; 542 cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
543 cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; 543 cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
544 544
545 } 545 }
546 546
547 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); 547 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
548 int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *, 548 int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *,
549 struct nfsd4_compoundargs *); 549 struct nfsd4_compoundargs *);
550 int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, 550 int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
551 struct nfsd4_compoundres *); 551 struct nfsd4_compoundres *);
552 int nfsd4_check_resp_size(struct nfsd4_compoundres *, u32); 552 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
553 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); 553 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
554 void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); 554 void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
555 __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 555 __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
556 struct dentry *dentry, __be32 *buffer, int *countp, 556 struct dentry *dentry, __be32 *buffer, int *countp,
557 u32 *bmval, struct svc_rqst *, int ignore_crossmnt); 557 u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
558 extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, 558 extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
559 struct nfsd4_compound_state *, 559 struct nfsd4_compound_state *,
560 struct nfsd4_setclientid *setclid); 560 struct nfsd4_setclientid *setclid);
561 extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 561 extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
562 struct nfsd4_compound_state *, 562 struct nfsd4_compound_state *,
563 struct nfsd4_setclientid_confirm *setclientid_confirm); 563 struct nfsd4_setclientid_confirm *setclientid_confirm);
564 extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp); 564 extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
565 extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, 565 extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
566 struct nfsd4_sequence *seq); 566 struct nfsd4_sequence *seq);
567 extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, 567 extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
568 struct nfsd4_compound_state *, struct nfsd4_exchange_id *); 568 struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
569 extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *); 569 extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *);
570 extern __be32 nfsd4_create_session(struct svc_rqst *, 570 extern __be32 nfsd4_create_session(struct svc_rqst *,
571 struct nfsd4_compound_state *, 571 struct nfsd4_compound_state *,
572 struct nfsd4_create_session *); 572 struct nfsd4_create_session *);
573 extern __be32 nfsd4_sequence(struct svc_rqst *, 573 extern __be32 nfsd4_sequence(struct svc_rqst *,
574 struct nfsd4_compound_state *, 574 struct nfsd4_compound_state *,
575 struct nfsd4_sequence *); 575 struct nfsd4_sequence *);
576 extern __be32 nfsd4_destroy_session(struct svc_rqst *, 576 extern __be32 nfsd4_destroy_session(struct svc_rqst *,
577 struct nfsd4_compound_state *, 577 struct nfsd4_compound_state *,
578 struct nfsd4_destroy_session *); 578 struct nfsd4_destroy_session *);
579 extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *); 579 extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *);
580 __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); 580 __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *);
581 extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, 581 extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
582 struct nfsd4_open *open); 582 struct nfsd4_open *open);
583 extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, 583 extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
584 struct svc_fh *current_fh, struct nfsd4_open *open); 584 struct svc_fh *current_fh, struct nfsd4_open *open);
585 extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status); 585 extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status);
586 extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, 586 extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
587 struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); 587 struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
588 extern __be32 nfsd4_close(struct svc_rqst *rqstp, 588 extern __be32 nfsd4_close(struct svc_rqst *rqstp,
589 struct nfsd4_compound_state *, 589 struct nfsd4_compound_state *,
590 struct nfsd4_close *close); 590 struct nfsd4_close *close);
591 extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, 591 extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
592 struct nfsd4_compound_state *, 592 struct nfsd4_compound_state *,
593 struct nfsd4_open_downgrade *od); 593 struct nfsd4_open_downgrade *od);
594 extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, 594 extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
595 struct nfsd4_lock *lock); 595 struct nfsd4_lock *lock);
596 extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, 596 extern __be32 nfsd4_lockt(struct svc_rqst *rqstp,
597 struct nfsd4_compound_state *, 597 struct nfsd4_compound_state *,
598 struct nfsd4_lockt *lockt); 598 struct nfsd4_lockt *lockt);
599 extern __be32 nfsd4_locku(struct svc_rqst *rqstp, 599 extern __be32 nfsd4_locku(struct svc_rqst *rqstp,
600 struct nfsd4_compound_state *, 600 struct nfsd4_compound_state *,
601 struct nfsd4_locku *locku); 601 struct nfsd4_locku *locku);
602 extern __be32 602 extern __be32
603 nfsd4_release_lockowner(struct svc_rqst *rqstp, 603 nfsd4_release_lockowner(struct svc_rqst *rqstp,
604 struct nfsd4_compound_state *, 604 struct nfsd4_compound_state *,
605 struct nfsd4_release_lockowner *rlockowner); 605 struct nfsd4_release_lockowner *rlockowner);
606 extern int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp); 606 extern int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp);
607 extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, 607 extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
608 struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); 608 struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr);
609 extern __be32 nfsd4_renew(struct svc_rqst *rqstp, 609 extern __be32 nfsd4_renew(struct svc_rqst *rqstp,
610 struct nfsd4_compound_state *, clientid_t *clid); 610 struct nfsd4_compound_state *, clientid_t *clid);
611 extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp, 611 extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp,
612 struct nfsd4_compound_state *, struct nfsd4_test_stateid *test_stateid); 612 struct nfsd4_compound_state *, struct nfsd4_test_stateid *test_stateid);
613 extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp, 613 extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
614 struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid); 614 struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid);
615 #endif 615 #endif
616 616
617 /* 617 /*
618 * Local variables: 618 * Local variables:
619 * c-basic-offset: 8 619 * c-basic-offset: 8
620 * End: 620 * End:
621 */ 621 */
622 622