NFSv4: Add post-op attributes to nfs4_proc_remove()
[deliverable/linux.git] / fs / nfs / nfs4xdr.c
CommitLineData
1da177e4
LT
1/*
2 * fs/nfs/nfs4xdr.c
3 *
4 * Client-side XDR for NFSv4.
5 *
6 * Copyright (c) 2002 The Regents of the University of Michigan.
7 * All rights reserved.
8 *
9 * Kendrick Smith <kmsmith@umich.edu>
10 * Andy Adamson <andros@umich.edu>
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <linux/param.h>
39#include <linux/time.h>
40#include <linux/mm.h>
41#include <linux/slab.h>
42#include <linux/utsname.h>
43#include <linux/errno.h>
44#include <linux/string.h>
45#include <linux/in.h>
46#include <linux/pagemap.h>
47#include <linux/proc_fs.h>
48#include <linux/kdev_t.h>
49#include <linux/sunrpc/clnt.h>
50#include <linux/nfs.h>
51#include <linux/nfs4.h>
52#include <linux/nfs_fs.h>
53#include <linux/nfs_idmap.h>
4ce79717 54#include "nfs4_fs.h"
1da177e4
LT
55
56#define NFSDBG_FACILITY NFSDBG_XDR
57
58/* Mapping from NFS error code to "errno" error code. */
59#define errno_NFSERR_IO EIO
60
61static int nfs_stat_to_errno(int);
62
63/* NFSv4 COMPOUND tags are only wanted for debugging purposes */
64#ifdef DEBUG
65#define NFS4_MAXTAGLEN 20
66#else
67#define NFS4_MAXTAGLEN 0
68#endif
69
70/* lock,open owner id:
71 * we currently use size 1 (u32) out of (NFS4_OPAQUE_LIMIT >> 2)
72 */
73#define owner_id_maxsz (1 + 1)
74#define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))
75#define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))
76#define op_encode_hdr_maxsz (1)
77#define op_decode_hdr_maxsz (2)
78#define encode_putfh_maxsz (op_encode_hdr_maxsz + 1 + \
79 (NFS4_FHSIZE >> 2))
80#define decode_putfh_maxsz (op_decode_hdr_maxsz)
81#define encode_putrootfh_maxsz (op_encode_hdr_maxsz)
82#define decode_putrootfh_maxsz (op_decode_hdr_maxsz)
83#define encode_getfh_maxsz (op_encode_hdr_maxsz)
84#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \
85 ((3+NFS4_FHSIZE) >> 2))
96928206
BF
86#define nfs4_fattr_bitmap_maxsz 3
87#define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
1da177e4
LT
88#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
89#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
96928206
BF
90/* This is based on getfattr, which uses the most attributes: */
91#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
92 3 + 3 + 3 + 2 * nfs4_name_maxsz))
93#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
94 nfs4_fattr_value_maxsz)
95#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
1da177e4
LT
96#define encode_savefh_maxsz (op_encode_hdr_maxsz)
97#define decode_savefh_maxsz (op_decode_hdr_maxsz)
56ae19f3
TM
98#define encode_restorefh_maxsz (op_encode_hdr_maxsz)
99#define decode_restorefh_maxsz (op_decode_hdr_maxsz)
1da177e4
LT
100#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2)
101#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11)
102#define encode_renew_maxsz (op_encode_hdr_maxsz + 3)
103#define decode_renew_maxsz (op_decode_hdr_maxsz)
104#define encode_setclientid_maxsz \
105 (op_encode_hdr_maxsz + \
106 4 /*server->ip_addr*/ + \
107 1 /*Netid*/ + \
108 6 /*uaddr*/ + \
109 6 + (NFS4_VERIFIER_SIZE >> 2))
110#define decode_setclientid_maxsz \
111 (op_decode_hdr_maxsz + \
112 2 + \
113 1024) /* large value for CLID_INUSE */
114#define encode_setclientid_confirm_maxsz \
115 (op_encode_hdr_maxsz + \
116 3 + (NFS4_VERIFIER_SIZE >> 2))
117#define decode_setclientid_confirm_maxsz \
118 (op_decode_hdr_maxsz)
119#define encode_lookup_maxsz (op_encode_hdr_maxsz + \
120 1 + ((3 + NFS4_FHSIZE) >> 2))
121#define encode_remove_maxsz (op_encode_hdr_maxsz + \
122 nfs4_name_maxsz)
123#define encode_rename_maxsz (op_encode_hdr_maxsz + \
124 2 * nfs4_name_maxsz)
125#define decode_rename_maxsz (op_decode_hdr_maxsz + 5 + 5)
126#define encode_link_maxsz (op_encode_hdr_maxsz + \
127 nfs4_name_maxsz)
128#define decode_link_maxsz (op_decode_hdr_maxsz + 5)
129#define encode_symlink_maxsz (op_encode_hdr_maxsz + \
130 1 + nfs4_name_maxsz + \
131 nfs4_path_maxsz + \
96928206 132 nfs4_fattr_maxsz)
1da177e4
LT
133#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8)
134#define encode_create_maxsz (op_encode_hdr_maxsz + \
135 2 + nfs4_name_maxsz + \
96928206 136 nfs4_fattr_maxsz)
1da177e4
LT
137#define decode_create_maxsz (op_decode_hdr_maxsz + 8)
138#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
139#define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
140#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
141#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
142#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
143 encode_putfh_maxsz + \
144 op_encode_hdr_maxsz + 7)
145#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \
146 decode_putfh_maxsz + \
147 op_decode_hdr_maxsz + 2)
148#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \
149 encode_putfh_maxsz + \
150 op_encode_hdr_maxsz)
151#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \
152 decode_putfh_maxsz + \
153 op_decode_hdr_maxsz)
154#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \
155 encode_putfh_maxsz + \
156 op_encode_hdr_maxsz + 9)
157#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \
158 decode_putfh_maxsz + \
159 op_decode_hdr_maxsz + 2)
160#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
161 encode_putfh_maxsz + \
162 op_encode_hdr_maxsz + 8)
163#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \
164 decode_putfh_maxsz + \
165 op_decode_hdr_maxsz + 4)
166#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
167 encode_putfh_maxsz + \
168 op_encode_hdr_maxsz + 3)
169#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
170 decode_putfh_maxsz + \
171 op_decode_hdr_maxsz + 2)
172#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
173 encode_putfh_maxsz + \
174 op_encode_hdr_maxsz + \
175 13 + 3 + 2 + 64 + \
176 encode_getattr_maxsz + \
177 encode_getfh_maxsz)
178#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
179 decode_putfh_maxsz + \
180 op_decode_hdr_maxsz + 4 + 5 + 2 + 3 + \
181 decode_getattr_maxsz + \
182 decode_getfh_maxsz)
183#define NFS4_enc_open_confirm_sz \
184 (compound_encode_hdr_maxsz + \
185 encode_putfh_maxsz + \
186 op_encode_hdr_maxsz + 5)
187#define NFS4_dec_open_confirm_sz (compound_decode_hdr_maxsz + \
188 decode_putfh_maxsz + \
189 op_decode_hdr_maxsz + 4)
190#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \
191 encode_putfh_maxsz + \
192 op_encode_hdr_maxsz + \
193 11)
194#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
195 decode_putfh_maxsz + \
196 op_decode_hdr_maxsz + \
197 4 + 5 + 2 + 3)
198#define NFS4_enc_open_downgrade_sz \
199 (compound_encode_hdr_maxsz + \
200 encode_putfh_maxsz + \
516a6af6
TM
201 op_encode_hdr_maxsz + 7 + \
202 encode_getattr_maxsz)
1da177e4
LT
203#define NFS4_dec_open_downgrade_sz \
204 (compound_decode_hdr_maxsz + \
205 decode_putfh_maxsz + \
516a6af6
TM
206 op_decode_hdr_maxsz + 4 + \
207 decode_getattr_maxsz)
1da177e4
LT
208#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
209 encode_putfh_maxsz + \
516a6af6
TM
210 op_encode_hdr_maxsz + 5 + \
211 encode_getattr_maxsz)
1da177e4
LT
212#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
213 decode_putfh_maxsz + \
516a6af6
TM
214 op_decode_hdr_maxsz + 4 + \
215 decode_getattr_maxsz)
1da177e4
LT
216#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
217 encode_putfh_maxsz + \
218 op_encode_hdr_maxsz + 4 + \
96928206 219 nfs4_fattr_maxsz + \
1da177e4
LT
220 encode_getattr_maxsz)
221#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
222 decode_putfh_maxsz + \
223 op_decode_hdr_maxsz + 3)
224#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \
225 encode_putfh_maxsz + \
226 encode_fsinfo_maxsz)
227#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \
228 decode_putfh_maxsz + \
229 decode_fsinfo_maxsz)
230#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \
231 encode_renew_maxsz)
232#define NFS4_dec_renew_sz (compound_decode_hdr_maxsz + \
233 decode_renew_maxsz)
234#define NFS4_enc_setclientid_sz (compound_encode_hdr_maxsz + \
235 encode_setclientid_maxsz)
236#define NFS4_dec_setclientid_sz (compound_decode_hdr_maxsz + \
237 decode_setclientid_maxsz)
238#define NFS4_enc_setclientid_confirm_sz \
239 (compound_encode_hdr_maxsz + \
240 encode_setclientid_confirm_maxsz + \
241 encode_putrootfh_maxsz + \
242 encode_fsinfo_maxsz)
243#define NFS4_dec_setclientid_confirm_sz \
244 (compound_decode_hdr_maxsz + \
245 decode_setclientid_confirm_maxsz + \
246 decode_putrootfh_maxsz + \
247 decode_fsinfo_maxsz)
248#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \
249 encode_putfh_maxsz + \
250 encode_getattr_maxsz + \
251 op_encode_hdr_maxsz + \
252 1 + 1 + 2 + 2 + \
253 1 + 4 + 1 + 2 + \
254 owner_id_maxsz)
255#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \
256 decode_putfh_maxsz + \
257 decode_getattr_maxsz + \
258 op_decode_hdr_maxsz + \
259 2 + 2 + 1 + 2 + \
260 owner_id_maxsz)
261#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \
262 encode_putfh_maxsz + \
263 encode_getattr_maxsz + \
264 op_encode_hdr_maxsz + \
265 1 + 2 + 2 + 2 + \
266 owner_id_maxsz)
267#define NFS4_dec_lockt_sz (NFS4_dec_lock_sz)
268#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \
269 encode_putfh_maxsz + \
270 encode_getattr_maxsz + \
271 op_encode_hdr_maxsz + \
272 1 + 1 + 4 + 2 + 2)
273#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \
274 decode_putfh_maxsz + \
275 decode_getattr_maxsz + \
276 op_decode_hdr_maxsz + 4)
277#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \
278 encode_putfh_maxsz + \
279 op_encode_hdr_maxsz + 1)
280#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \
281 decode_putfh_maxsz + \
282 op_decode_hdr_maxsz + 2)
283#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
284 encode_putfh_maxsz + \
285 encode_getattr_maxsz)
286#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \
287 decode_putfh_maxsz + \
288 decode_getattr_maxsz)
289#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \
290 encode_putfh_maxsz + \
291 encode_lookup_maxsz + \
292 encode_getattr_maxsz + \
293 encode_getfh_maxsz)
294#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \
295 decode_putfh_maxsz + \
296 op_decode_hdr_maxsz + \
297 decode_getattr_maxsz + \
298 decode_getfh_maxsz)
299#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
300 encode_putrootfh_maxsz + \
301 encode_getattr_maxsz + \
302 encode_getfh_maxsz)
303#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
304 decode_putrootfh_maxsz + \
305 decode_getattr_maxsz + \
306 decode_getfh_maxsz)
307#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
308 encode_putfh_maxsz + \
16e42959
TM
309 encode_remove_maxsz + \
310 encode_getattr_maxsz)
1da177e4
LT
311#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
312 decode_putfh_maxsz + \
16e42959
TM
313 op_decode_hdr_maxsz + 5 + \
314 decode_getattr_maxsz)
1da177e4
LT
315#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
316 encode_putfh_maxsz + \
317 encode_savefh_maxsz + \
318 encode_putfh_maxsz + \
6caf2c82
TM
319 encode_rename_maxsz + \
320 encode_getattr_maxsz + \
321 encode_restorefh_maxsz + \
322 encode_getattr_maxsz)
1da177e4
LT
323#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
324 decode_putfh_maxsz + \
325 decode_savefh_maxsz + \
326 decode_putfh_maxsz + \
6caf2c82
TM
327 decode_rename_maxsz + \
328 decode_getattr_maxsz + \
329 decode_restorefh_maxsz + \
330 decode_getattr_maxsz)
1da177e4
LT
331#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
332 encode_putfh_maxsz + \
333 encode_savefh_maxsz + \
334 encode_putfh_maxsz + \
91ba2eee
TM
335 encode_link_maxsz + \
336 decode_getattr_maxsz + \
337 encode_restorefh_maxsz + \
338 decode_getattr_maxsz)
1da177e4
LT
339#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
340 decode_putfh_maxsz + \
341 decode_savefh_maxsz + \
342 decode_putfh_maxsz + \
91ba2eee
TM
343 decode_link_maxsz + \
344 decode_getattr_maxsz + \
345 decode_restorefh_maxsz + \
346 decode_getattr_maxsz)
1da177e4
LT
347#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
348 encode_putfh_maxsz + \
349 encode_symlink_maxsz + \
350 encode_getattr_maxsz + \
351 encode_getfh_maxsz)
352#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \
353 decode_putfh_maxsz + \
354 decode_symlink_maxsz + \
355 decode_getattr_maxsz + \
356 decode_getfh_maxsz)
357#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
358 encode_putfh_maxsz + \
56ae19f3 359 encode_savefh_maxsz + \
1da177e4 360 encode_create_maxsz + \
56ae19f3 361 encode_getfh_maxsz + \
1da177e4 362 encode_getattr_maxsz + \
56ae19f3
TM
363 encode_restorefh_maxsz + \
364 encode_getattr_maxsz)
1da177e4
LT
365#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
366 decode_putfh_maxsz + \
56ae19f3 367 decode_savefh_maxsz + \
1da177e4 368 decode_create_maxsz + \
56ae19f3 369 decode_getfh_maxsz + \
1da177e4 370 decode_getattr_maxsz + \
56ae19f3
TM
371 decode_restorefh_maxsz + \
372 decode_getattr_maxsz)
1da177e4
LT
373#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
374 encode_putfh_maxsz + \
375 encode_getattr_maxsz)
376#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \
377 decode_putfh_maxsz + \
378 decode_getattr_maxsz)
379#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \
380 encode_putfh_maxsz + \
381 encode_getattr_maxsz)
382#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \
383 decode_putfh_maxsz + \
384 op_decode_hdr_maxsz + 12)
385#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
386 encode_getattr_maxsz)
387#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
388 decode_getattr_maxsz)
389#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
390 encode_putfh_maxsz + \
391 encode_delegreturn_maxsz)
392#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
393 decode_delegreturn_maxsz)
029d105e
BF
394#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
395 encode_putfh_maxsz + \
396 encode_getattr_maxsz)
397#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \
398 decode_putfh_maxsz + \
399 op_decode_hdr_maxsz + \
400 nfs4_fattr_bitmap_maxsz + 1)
23ec6965
BF
401#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \
402 encode_putfh_maxsz + \
403 op_encode_hdr_maxsz + 4 + \
404 nfs4_fattr_bitmap_maxsz + 1)
405#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \
406 decode_putfh_maxsz + \
407 op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
1da177e4
LT
408
409static struct {
410 unsigned int mode;
411 unsigned int nfs2type;
412} nfs_type2fmt[] = {
413 { 0, NFNON },
414 { S_IFREG, NFREG },
415 { S_IFDIR, NFDIR },
416 { S_IFBLK, NFBLK },
417 { S_IFCHR, NFCHR },
418 { S_IFLNK, NFLNK },
419 { S_IFSOCK, NFSOCK },
420 { S_IFIFO, NFFIFO },
421 { 0, NFNON },
422 { 0, NFNON },
423};
424
425struct compound_hdr {
426 int32_t status;
427 uint32_t nops;
428 uint32_t taglen;
429 char * tag;
430};
431
432/*
433 * START OF "GENERIC" ENCODE ROUTINES.
434 * These may look a little ugly since they are imported from a "generic"
435 * set of XDR encode/decode routines which are intended to be shared by
436 * all of our NFSv4 implementations (OpenBSD, MacOS X...).
437 *
438 * If the pain of reading these is too great, it should be a straightforward
439 * task to translate them into Linux-specific versions which are more
440 * consistent with the style used in NFSv2/v3...
441 */
442#define WRITE32(n) *p++ = htonl(n)
443#define WRITE64(n) do { \
444 *p++ = htonl((uint32_t)((n) >> 32)); \
445 *p++ = htonl((uint32_t)(n)); \
446} while (0)
447#define WRITEMEM(ptr,nbytes) do { \
448 p = xdr_encode_opaque_fixed(p, ptr, nbytes); \
449} while (0)
450
451#define RESERVE_SPACE(nbytes) do { \
452 p = xdr_reserve_space(xdr, nbytes); \
453 if (!p) printk("RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \
454 BUG_ON(!p); \
455} while (0)
456
457static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
458{
459 uint32_t *p;
460
461 p = xdr_reserve_space(xdr, 4 + len);
462 BUG_ON(p == NULL);
463 xdr_encode_opaque(p, str, len);
464}
465
466static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
467{
468 uint32_t *p;
469
470 dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
471 BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
472 RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2));
473 WRITE32(hdr->taglen);
474 WRITEMEM(hdr->tag, hdr->taglen);
475 WRITE32(NFS4_MINOR_VERSION);
476 WRITE32(hdr->nops);
477 return 0;
478}
479
480static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
481{
482 uint32_t *p;
483
484 p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
485 BUG_ON(p == NULL);
486 xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE);
487}
488
489static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server)
490{
491 char owner_name[IDMAP_NAMESZ];
492 char owner_group[IDMAP_NAMESZ];
493 int owner_namelen = 0;
494 int owner_grouplen = 0;
495 uint32_t *p;
496 uint32_t *q;
497 int len;
498 uint32_t bmval0 = 0;
499 uint32_t bmval1 = 0;
500 int status;
501
502 /*
503 * We reserve enough space to write the entire attribute buffer at once.
504 * In the worst-case, this would be
505 * 12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
506 * = 36 bytes, plus any contribution from variable-length fields
23ec6965 507 * such as owner/group.
1da177e4
LT
508 */
509 len = 16;
510
511 /* Sigh */
512 if (iap->ia_valid & ATTR_SIZE)
513 len += 8;
514 if (iap->ia_valid & ATTR_MODE)
515 len += 4;
516 if (iap->ia_valid & ATTR_UID) {
517 owner_namelen = nfs_map_uid_to_name(server->nfs4_state, iap->ia_uid, owner_name);
518 if (owner_namelen < 0) {
519 printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n",
520 iap->ia_uid);
521 /* XXX */
522 strcpy(owner_name, "nobody");
523 owner_namelen = sizeof("nobody") - 1;
524 /* goto out; */
525 }
526 len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
527 }
528 if (iap->ia_valid & ATTR_GID) {
529 owner_grouplen = nfs_map_gid_to_group(server->nfs4_state, iap->ia_gid, owner_group);
530 if (owner_grouplen < 0) {
531 printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n",
532 iap->ia_gid);
533 strcpy(owner_group, "nobody");
534 owner_grouplen = sizeof("nobody") - 1;
535 /* goto out; */
536 }
537 len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
538 }
539 if (iap->ia_valid & ATTR_ATIME_SET)
540 len += 16;
541 else if (iap->ia_valid & ATTR_ATIME)
542 len += 4;
543 if (iap->ia_valid & ATTR_MTIME_SET)
544 len += 16;
545 else if (iap->ia_valid & ATTR_MTIME)
546 len += 4;
547 RESERVE_SPACE(len);
548
549 /*
550 * We write the bitmap length now, but leave the bitmap and the attribute
551 * buffer length to be backfilled at the end of this routine.
552 */
553 WRITE32(2);
554 q = p;
555 p += 3;
556
557 if (iap->ia_valid & ATTR_SIZE) {
558 bmval0 |= FATTR4_WORD0_SIZE;
559 WRITE64(iap->ia_size);
560 }
561 if (iap->ia_valid & ATTR_MODE) {
562 bmval1 |= FATTR4_WORD1_MODE;
563 WRITE32(iap->ia_mode);
564 }
565 if (iap->ia_valid & ATTR_UID) {
566 bmval1 |= FATTR4_WORD1_OWNER;
567 WRITE32(owner_namelen);
568 WRITEMEM(owner_name, owner_namelen);
569 }
570 if (iap->ia_valid & ATTR_GID) {
571 bmval1 |= FATTR4_WORD1_OWNER_GROUP;
572 WRITE32(owner_grouplen);
573 WRITEMEM(owner_group, owner_grouplen);
574 }
575 if (iap->ia_valid & ATTR_ATIME_SET) {
576 bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
577 WRITE32(NFS4_SET_TO_CLIENT_TIME);
578 WRITE32(0);
579 WRITE32(iap->ia_mtime.tv_sec);
580 WRITE32(iap->ia_mtime.tv_nsec);
581 }
582 else if (iap->ia_valid & ATTR_ATIME) {
583 bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
584 WRITE32(NFS4_SET_TO_SERVER_TIME);
585 }
586 if (iap->ia_valid & ATTR_MTIME_SET) {
587 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
588 WRITE32(NFS4_SET_TO_CLIENT_TIME);
589 WRITE32(0);
590 WRITE32(iap->ia_mtime.tv_sec);
591 WRITE32(iap->ia_mtime.tv_nsec);
592 }
593 else if (iap->ia_valid & ATTR_MTIME) {
594 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
595 WRITE32(NFS4_SET_TO_SERVER_TIME);
596 }
597
598 /*
599 * Now we backfill the bitmap and the attribute buffer length.
600 */
601 if (len != ((char *)p - (char *)q) + 4) {
602 printk ("encode_attr: Attr length calculation error! %u != %Zu\n",
603 len, ((char *)p - (char *)q) + 4);
604 BUG();
605 }
606 len = (char *)p - (char *)q - 12;
607 *q++ = htonl(bmval0);
608 *q++ = htonl(bmval1);
609 *q++ = htonl(len);
610
611 status = 0;
612/* out: */
613 return status;
614}
615
616static int encode_access(struct xdr_stream *xdr, u32 access)
617{
618 uint32_t *p;
619
620 RESERVE_SPACE(8);
621 WRITE32(OP_ACCESS);
622 WRITE32(access);
623
624 return 0;
625}
626
627static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
628{
629 uint32_t *p;
630
9512135d 631 RESERVE_SPACE(8+sizeof(arg->stateid->data));
1da177e4 632 WRITE32(OP_CLOSE);
cee54fc9 633 WRITE32(arg->seqid->sequence->counter);
9512135d 634 WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
1da177e4
LT
635
636 return 0;
637}
638
639static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args)
640{
641 uint32_t *p;
642
643 RESERVE_SPACE(16);
644 WRITE32(OP_COMMIT);
645 WRITE64(args->offset);
646 WRITE32(args->count);
647
648 return 0;
649}
650
651static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create)
652{
653 uint32_t *p;
654
655 RESERVE_SPACE(8);
656 WRITE32(OP_CREATE);
657 WRITE32(create->ftype);
658
659 switch (create->ftype) {
660 case NF4LNK:
661 RESERVE_SPACE(4 + create->u.symlink->len);
662 WRITE32(create->u.symlink->len);
663 WRITEMEM(create->u.symlink->name, create->u.symlink->len);
664 break;
665
666 case NF4BLK: case NF4CHR:
667 RESERVE_SPACE(8);
668 WRITE32(create->u.device.specdata1);
669 WRITE32(create->u.device.specdata2);
670 break;
671
672 default:
673 break;
674 }
675
676 RESERVE_SPACE(4 + create->name->len);
677 WRITE32(create->name->len);
678 WRITEMEM(create->name->name, create->name->len);
679
680 return encode_attrs(xdr, create->attrs, create->server);
681}
682
683static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)
684{
685 uint32_t *p;
686
687 RESERVE_SPACE(12);
688 WRITE32(OP_GETATTR);
689 WRITE32(1);
690 WRITE32(bitmap);
691 return 0;
692}
693
694static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1)
695{
696 uint32_t *p;
697
698 RESERVE_SPACE(16);
699 WRITE32(OP_GETATTR);
700 WRITE32(2);
701 WRITE32(bm0);
702 WRITE32(bm1);
703 return 0;
704}
705
706static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask)
707{
1da177e4
LT
708 return encode_getattr_two(xdr,
709 bitmask[0] & nfs4_fattr_bitmap[0],
710 bitmask[1] & nfs4_fattr_bitmap[1]);
711}
712
713static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask)
714{
1da177e4
LT
715 return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0],
716 bitmask[1] & nfs4_fsinfo_bitmap[1]);
717}
718
719static int encode_getfh(struct xdr_stream *xdr)
720{
721 uint32_t *p;
722
723 RESERVE_SPACE(4);
724 WRITE32(OP_GETFH);
725
726 return 0;
727}
728
729static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
730{
731 uint32_t *p;
732
733 RESERVE_SPACE(8 + name->len);
734 WRITE32(OP_LINK);
735 WRITE32(name->len);
736 WRITEMEM(name->name, name->len);
737
738 return 0;
739}
740
741/*
742 * opcode,type,reclaim,offset,length,new_lock_owner = 32
743 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
744 */
745static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
746{
747 uint32_t *p;
748 struct nfs_lock_opargs *opargs = arg->u.lock;
749
750 RESERVE_SPACE(32);
751 WRITE32(OP_LOCK);
752 WRITE32(arg->type);
753 WRITE32(opargs->reclaim);
754 WRITE64(arg->offset);
755 WRITE64(arg->length);
756 WRITE32(opargs->new_lock_owner);
757 if (opargs->new_lock_owner){
1da177e4 758 RESERVE_SPACE(40);
06735b34
TM
759 WRITE32(opargs->open_seqid->sequence->counter);
760 WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
761 WRITE32(opargs->lock_seqid->sequence->counter);
762 WRITE64(opargs->lock_owner.clientid);
1da177e4 763 WRITE32(4);
06735b34 764 WRITE32(opargs->lock_owner.id);
1da177e4
LT
765 }
766 else {
1da177e4 767 RESERVE_SPACE(20);
06735b34
TM
768 WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
769 WRITE32(opargs->lock_seqid->sequence->counter);
1da177e4
LT
770 }
771
772 return 0;
773}
774
775static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
776{
777 uint32_t *p;
778 struct nfs_lowner *opargs = arg->u.lockt;
779
780 RESERVE_SPACE(40);
781 WRITE32(OP_LOCKT);
782 WRITE32(arg->type);
783 WRITE64(arg->offset);
784 WRITE64(arg->length);
785 WRITE64(opargs->clientid);
786 WRITE32(4);
787 WRITE32(opargs->id);
788
789 return 0;
790}
791
792static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
793{
794 uint32_t *p;
795 struct nfs_locku_opargs *opargs = arg->u.locku;
796
797 RESERVE_SPACE(44);
798 WRITE32(OP_LOCKU);
799 WRITE32(arg->type);
cee54fc9 800 WRITE32(opargs->seqid->sequence->counter);
faf5f49c 801 WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data));
1da177e4
LT
802 WRITE64(arg->offset);
803 WRITE64(arg->length);
804
805 return 0;
806}
807
808static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
809{
810 int len = name->len;
811 uint32_t *p;
812
813 RESERVE_SPACE(8 + len);
814 WRITE32(OP_LOOKUP);
815 WRITE32(len);
816 WRITEMEM(name->name, len);
817
818 return 0;
819}
820
821static void encode_share_access(struct xdr_stream *xdr, int open_flags)
822{
823 uint32_t *p;
824
825 RESERVE_SPACE(8);
826 switch (open_flags & (FMODE_READ|FMODE_WRITE)) {
827 case FMODE_READ:
828 WRITE32(NFS4_SHARE_ACCESS_READ);
829 break;
830 case FMODE_WRITE:
831 WRITE32(NFS4_SHARE_ACCESS_WRITE);
832 break;
833 case FMODE_READ|FMODE_WRITE:
834 WRITE32(NFS4_SHARE_ACCESS_BOTH);
835 break;
836 default:
837 BUG();
838 }
839 WRITE32(0); /* for linux, share_deny = 0 always */
840}
841
842static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
843{
844 uint32_t *p;
845 /*
846 * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
847 * owner 4 = 32
848 */
849 RESERVE_SPACE(8);
850 WRITE32(OP_OPEN);
cee54fc9 851 WRITE32(arg->seqid->sequence->counter);
1da177e4
LT
852 encode_share_access(xdr, arg->open_flags);
853 RESERVE_SPACE(16);
854 WRITE64(arg->clientid);
855 WRITE32(4);
856 WRITE32(arg->id);
857}
858
859static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
860{
861 uint32_t *p;
862
863 RESERVE_SPACE(4);
864 switch(arg->open_flags & O_EXCL) {
865 case 0:
866 WRITE32(NFS4_CREATE_UNCHECKED);
867 encode_attrs(xdr, arg->u.attrs, arg->server);
868 break;
869 default:
870 WRITE32(NFS4_CREATE_EXCLUSIVE);
871 encode_nfs4_verifier(xdr, &arg->u.verifier);
872 }
873}
874
875static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
876{
877 uint32_t *p;
878
879 RESERVE_SPACE(4);
880 switch (arg->open_flags & O_CREAT) {
881 case 0:
882 WRITE32(NFS4_OPEN_NOCREATE);
883 break;
884 default:
885 BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
886 WRITE32(NFS4_OPEN_CREATE);
887 encode_createmode(xdr, arg);
888 }
889}
890
891static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type)
892{
893 uint32_t *p;
894
895 RESERVE_SPACE(4);
896 switch (delegation_type) {
897 case 0:
898 WRITE32(NFS4_OPEN_DELEGATE_NONE);
899 break;
900 case FMODE_READ:
901 WRITE32(NFS4_OPEN_DELEGATE_READ);
902 break;
903 case FMODE_WRITE|FMODE_READ:
904 WRITE32(NFS4_OPEN_DELEGATE_WRITE);
905 break;
906 default:
907 BUG();
908 }
909}
910
911static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
912{
913 uint32_t *p;
914
915 RESERVE_SPACE(4);
916 WRITE32(NFS4_OPEN_CLAIM_NULL);
917 encode_string(xdr, name->len, name->name);
918}
919
920static inline void encode_claim_previous(struct xdr_stream *xdr, int type)
921{
922 uint32_t *p;
923
924 RESERVE_SPACE(4);
925 WRITE32(NFS4_OPEN_CLAIM_PREVIOUS);
926 encode_delegation_type(xdr, type);
927}
928
929static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid)
930{
931 uint32_t *p;
932
933 RESERVE_SPACE(4+sizeof(stateid->data));
934 WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
935 WRITEMEM(stateid->data, sizeof(stateid->data));
936 encode_string(xdr, name->len, name->name);
937}
938
939static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)
940{
941 encode_openhdr(xdr, arg);
942 encode_opentype(xdr, arg);
943 switch (arg->claim) {
944 case NFS4_OPEN_CLAIM_NULL:
945 encode_claim_null(xdr, arg->name);
946 break;
947 case NFS4_OPEN_CLAIM_PREVIOUS:
948 encode_claim_previous(xdr, arg->u.delegation_type);
949 break;
950 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
951 encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
952 break;
953 default:
954 BUG();
955 }
956 return 0;
957}
958
959static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg)
960{
961 uint32_t *p;
962
963 RESERVE_SPACE(8+sizeof(arg->stateid.data));
964 WRITE32(OP_OPEN_CONFIRM);
965 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
cee54fc9 966 WRITE32(arg->seqid->sequence->counter);
1da177e4
LT
967
968 return 0;
969}
970
971static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
972{
973 uint32_t *p;
974
9512135d 975 RESERVE_SPACE(8+sizeof(arg->stateid->data));
1da177e4 976 WRITE32(OP_OPEN_DOWNGRADE);
9512135d 977 WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
cee54fc9 978 WRITE32(arg->seqid->sequence->counter);
1da177e4
LT
979 encode_share_access(xdr, arg->open_flags);
980 return 0;
981}
982
983static int
984encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)
985{
986 int len = fh->size;
987 uint32_t *p;
988
989 RESERVE_SPACE(8 + len);
990 WRITE32(OP_PUTFH);
991 WRITE32(len);
992 WRITEMEM(fh->data, len);
993
994 return 0;
995}
996
997static int encode_putrootfh(struct xdr_stream *xdr)
998{
999 uint32_t *p;
1000
1001 RESERVE_SPACE(4);
1002 WRITE32(OP_PUTROOTFH);
1003
1004 return 0;
1005}
1006
1007static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
1008{
1da177e4
LT
1009 nfs4_stateid stateid;
1010 uint32_t *p;
1011
1012 RESERVE_SPACE(16);
1013 if (ctx->state != NULL) {
1014 nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner);
1015 WRITEMEM(stateid.data, sizeof(stateid.data));
1016 } else
1017 WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data));
1018}
1019
1020static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
1021{
1022 uint32_t *p;
1023
1024 RESERVE_SPACE(4);
1025 WRITE32(OP_READ);
1026
1027 encode_stateid(xdr, args->context);
1028
1029 RESERVE_SPACE(12);
1030 WRITE64(args->offset);
1031 WRITE32(args->count);
1032
1033 return 0;
1034}
1035
1036static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
1037{
1038 struct rpc_auth *auth = req->rq_task->tk_auth;
97d312d0
MN
1039 uint32_t attrs[2] = {
1040 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
1041 FATTR4_WORD1_MOUNTED_ON_FILEID,
1042 };
1da177e4
LT
1043 int replen;
1044 uint32_t *p;
1045
1046 RESERVE_SPACE(32+sizeof(nfs4_verifier));
1047 WRITE32(OP_READDIR);
1048 WRITE64(readdir->cookie);
1049 WRITEMEM(readdir->verifier.data, sizeof(readdir->verifier.data));
1050 WRITE32(readdir->count >> 1); /* We're not doing readdirplus */
1051 WRITE32(readdir->count);
1052 WRITE32(2);
97d312d0
MN
1053 /* Switch to mounted_on_fileid if the server supports it */
1054 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1055 attrs[0] &= ~FATTR4_WORD0_FILEID;
1056 else
1057 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1058 WRITE32(attrs[0] & readdir->bitmask[0]);
1059 WRITE32(attrs[1] & readdir->bitmask[1]);
eadf4598
TM
1060 dprintk("%s: cookie = %Lu, verifier = 0x%x%x, bitmap = 0x%x%x\n",
1061 __FUNCTION__,
1062 (unsigned long long)readdir->cookie,
1063 ((u32 *)readdir->verifier.data)[0],
1064 ((u32 *)readdir->verifier.data)[1],
1065 attrs[0] & readdir->bitmask[0],
1066 attrs[1] & readdir->bitmask[1]);
1da177e4
LT
1067
1068 /* set up reply kvec
1069 * toplevel_status + taglen + rescount + OP_PUTFH + status
1070 * + OP_READDIR + status + verifer(2) = 9
1071 */
1072 replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
1073 xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->pages,
1074 readdir->pgbase, readdir->count);
eadf4598
TM
1075 dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
1076 __FUNCTION__, replen, readdir->pages,
1077 readdir->pgbase, readdir->count);
1da177e4
LT
1078
1079 return 0;
1080}
1081
1082static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req)
1083{
1084 struct rpc_auth *auth = req->rq_task->tk_auth;
1085 unsigned int replen;
1086 uint32_t *p;
1087
1088 RESERVE_SPACE(4);
1089 WRITE32(OP_READLINK);
1090
1091 /* set up reply kvec
1092 * toplevel_status + taglen + rescount + OP_PUTFH + status
1093 * + OP_READLINK + status + string length = 8
1094 */
1095 replen = (RPC_REPHDRSIZE + auth->au_rslack + 8) << 2;
1096 xdr_inline_pages(&req->rq_rcv_buf, replen, readlink->pages,
1097 readlink->pgbase, readlink->pglen);
1098
1099 return 0;
1100}
1101
1102static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)
1103{
1104 uint32_t *p;
1105
1106 RESERVE_SPACE(8 + name->len);
1107 WRITE32(OP_REMOVE);
1108 WRITE32(name->len);
1109 WRITEMEM(name->name, name->len);
1110
1111 return 0;
1112}
1113
1114static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname)
1115{
1116 uint32_t *p;
1117
1118 RESERVE_SPACE(8 + oldname->len);
1119 WRITE32(OP_RENAME);
1120 WRITE32(oldname->len);
1121 WRITEMEM(oldname->name, oldname->len);
1122
1123 RESERVE_SPACE(4 + newname->len);
1124 WRITE32(newname->len);
1125 WRITEMEM(newname->name, newname->len);
1126
1127 return 0;
1128}
1129
1130static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client_stateid)
1131{
1132 uint32_t *p;
1133
1134 RESERVE_SPACE(12);
1135 WRITE32(OP_RENEW);
1136 WRITE64(client_stateid->cl_clientid);
1137
1138 return 0;
1139}
1140
56ae19f3
TM
1141static int
1142encode_restorefh(struct xdr_stream *xdr)
1143{
1144 uint32_t *p;
1145
1146 RESERVE_SPACE(4);
1147 WRITE32(OP_RESTOREFH);
1148
1149 return 0;
1150}
1151
23ec6965
BF
1152static int
1153encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
1154{
1155 uint32_t *p;
1156
1157 RESERVE_SPACE(4+sizeof(zero_stateid.data));
1158 WRITE32(OP_SETATTR);
1159 WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data));
1160 RESERVE_SPACE(2*4);
1161 WRITE32(1);
1162 WRITE32(FATTR4_WORD0_ACL);
1163 if (arg->acl_len % 4)
1164 return -EINVAL;
1165 RESERVE_SPACE(4);
1166 WRITE32(arg->acl_len);
1167 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
1168 return 0;
1169}
1170
1da177e4
LT
1171static int
1172encode_savefh(struct xdr_stream *xdr)
1173{
1174 uint32_t *p;
1175
1176 RESERVE_SPACE(4);
1177 WRITE32(OP_SAVEFH);
1178
1179 return 0;
1180}
1181
1182static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server)
1183{
1184 int status;
1185 uint32_t *p;
1186
1187 RESERVE_SPACE(4+sizeof(arg->stateid.data));
1188 WRITE32(OP_SETATTR);
1189 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
1190
1191 if ((status = encode_attrs(xdr, arg->iap, server)))
1192 return status;
1193
1194 return 0;
1195}
1196
1197static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid)
1198{
1199 uint32_t *p;
1200
1201 RESERVE_SPACE(4 + sizeof(setclientid->sc_verifier->data));
1202 WRITE32(OP_SETCLIENTID);
1203 WRITEMEM(setclientid->sc_verifier->data, sizeof(setclientid->sc_verifier->data));
1204
1205 encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name);
1206 RESERVE_SPACE(4);
1207 WRITE32(setclientid->sc_prog);
1208 encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
1209 encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
1210 RESERVE_SPACE(4);
1211 WRITE32(setclientid->sc_cb_ident);
1212
1213 return 0;
1214}
1215
1216static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_client *client_state)
1217{
1218 uint32_t *p;
1219
1220 RESERVE_SPACE(12 + sizeof(client_state->cl_confirm.data));
1221 WRITE32(OP_SETCLIENTID_CONFIRM);
1222 WRITE64(client_state->cl_clientid);
1223 WRITEMEM(client_state->cl_confirm.data, sizeof(client_state->cl_confirm.data));
1224
1225 return 0;
1226}
1227
1228static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args)
1229{
1230 uint32_t *p;
1231
1232 RESERVE_SPACE(4);
1233 WRITE32(OP_WRITE);
1234
1235 encode_stateid(xdr, args->context);
1236
1237 RESERVE_SPACE(16);
1238 WRITE64(args->offset);
1239 WRITE32(args->stable);
1240 WRITE32(args->count);
1241
1242 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1243
1244 return 0;
1245}
1246
1247static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid)
1248{
1249 uint32_t *p;
1250
1251 RESERVE_SPACE(20);
1252
1253 WRITE32(OP_DELEGRETURN);
1254 WRITEMEM(stateid->data, sizeof(stateid->data));
1255 return 0;
1256
1257}
1258/*
1259 * END OF "GENERIC" ENCODE ROUTINES.
1260 */
1261
1262/*
1263 * Encode an ACCESS request
1264 */
1265static int nfs4_xdr_enc_access(struct rpc_rqst *req, uint32_t *p, const struct nfs4_accessargs *args)
1266{
1267 struct xdr_stream xdr;
1268 struct compound_hdr hdr = {
1269 .nops = 2,
1270 };
1271 int status;
1272
1273 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1274 encode_compound_hdr(&xdr, &hdr);
1275 if ((status = encode_putfh(&xdr, args->fh)) == 0)
1276 status = encode_access(&xdr, args->access);
1277 return status;
1278}
1279
1280/*
1281 * Encode LOOKUP request
1282 */
1283static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_arg *args)
1284{
1285 struct xdr_stream xdr;
1286 struct compound_hdr hdr = {
1287 .nops = 4,
1288 };
1289 int status;
1290
1291 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1292 encode_compound_hdr(&xdr, &hdr);
1293 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1294 goto out;
1295 if ((status = encode_lookup(&xdr, args->name)) != 0)
1296 goto out;
1297 if ((status = encode_getfh(&xdr)) != 0)
1298 goto out;
1299 status = encode_getfattr(&xdr, args->bitmask);
1300out:
1301 return status;
1302}
1303
1304/*
1305 * Encode LOOKUP_ROOT request
1306 */
1307static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_root_arg *args)
1308{
1309 struct xdr_stream xdr;
1310 struct compound_hdr hdr = {
1311 .nops = 3,
1312 };
1313 int status;
1314
1315 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1316 encode_compound_hdr(&xdr, &hdr);
1317 if ((status = encode_putrootfh(&xdr)) != 0)
1318 goto out;
1319 if ((status = encode_getfh(&xdr)) == 0)
1320 status = encode_getfattr(&xdr, args->bitmask);
1321out:
1322 return status;
1323}
1324
1325/*
1326 * Encode REMOVE request
1327 */
1328static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct nfs4_remove_arg *args)
1329{
1330 struct xdr_stream xdr;
1331 struct compound_hdr hdr = {
16e42959 1332 .nops = 3,
1da177e4
LT
1333 };
1334 int status;
1335
1336 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1337 encode_compound_hdr(&xdr, &hdr);
16e42959
TM
1338 if ((status = encode_putfh(&xdr, args->fh)) != 0)
1339 goto out;
1340 if ((status = encode_remove(&xdr, args->name)) != 0)
1341 goto out;
1342 status = encode_getfattr(&xdr, args->bitmask);
1343out:
1da177e4
LT
1344 return status;
1345}
1346
1347/*
1348 * Encode RENAME request
1349 */
1350static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct nfs4_rename_arg *args)
1351{
1352 struct xdr_stream xdr;
1353 struct compound_hdr hdr = {
6caf2c82 1354 .nops = 7,
1da177e4
LT
1355 };
1356 int status;
1357
1358 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1359 encode_compound_hdr(&xdr, &hdr);
1360 if ((status = encode_putfh(&xdr, args->old_dir)) != 0)
1361 goto out;
1362 if ((status = encode_savefh(&xdr)) != 0)
1363 goto out;
1364 if ((status = encode_putfh(&xdr, args->new_dir)) != 0)
1365 goto out;
6caf2c82
TM
1366 if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0)
1367 goto out;
1368 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1369 goto out;
1370 if ((status = encode_restorefh(&xdr)) != 0)
1371 goto out;
1372 status = encode_getfattr(&xdr, args->bitmask);
1da177e4
LT
1373out:
1374 return status;
1375}
1376
1377/*
1378 * Encode LINK request
1379 */
1380static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs4_link_arg *args)
1381{
1382 struct xdr_stream xdr;
1383 struct compound_hdr hdr = {
91ba2eee 1384 .nops = 7,
1da177e4
LT
1385 };
1386 int status;
1387
1388 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1389 encode_compound_hdr(&xdr, &hdr);
1390 if ((status = encode_putfh(&xdr, args->fh)) != 0)
1391 goto out;
1392 if ((status = encode_savefh(&xdr)) != 0)
1393 goto out;
1394 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1395 goto out;
91ba2eee
TM
1396 if ((status = encode_link(&xdr, args->name)) != 0)
1397 goto out;
1398 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1399 goto out;
1400 if ((status = encode_restorefh(&xdr)) != 0)
1401 goto out;
1402 status = encode_getfattr(&xdr, args->bitmask);
1da177e4
LT
1403out:
1404 return status;
1405}
1406
1407/*
1408 * Encode CREATE request
1409 */
1410static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args)
1411{
1412 struct xdr_stream xdr;
1413 struct compound_hdr hdr = {
56ae19f3 1414 .nops = 7,
1da177e4
LT
1415 };
1416 int status;
1417
1418 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1419 encode_compound_hdr(&xdr, &hdr);
1420 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1421 goto out;
56ae19f3
TM
1422 if ((status = encode_savefh(&xdr)) != 0)
1423 goto out;
1da177e4
LT
1424 if ((status = encode_create(&xdr, args)) != 0)
1425 goto out;
1426 if ((status = encode_getfh(&xdr)) != 0)
1427 goto out;
56ae19f3
TM
1428 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1429 goto out;
1430 if ((status = encode_restorefh(&xdr)) != 0)
1431 goto out;
1da177e4
LT
1432 status = encode_getfattr(&xdr, args->bitmask);
1433out:
1434 return status;
1435}
1436
1437/*
1438 * Encode SYMLINK request
1439 */
1440static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args)
1441{
1442 return nfs4_xdr_enc_create(req, p, args);
1443}
1444
1445/*
1446 * Encode GETATTR request
1447 */
1448static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct nfs4_getattr_arg *args)
1449{
1450 struct xdr_stream xdr;
1451 struct compound_hdr hdr = {
1452 .nops = 2,
1453 };
1454 int status;
1455
1456 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1457 encode_compound_hdr(&xdr, &hdr);
1458 if ((status = encode_putfh(&xdr, args->fh)) == 0)
1459 status = encode_getfattr(&xdr, args->bitmask);
1460 return status;
1461}
1462
1463/*
1464 * Encode a CLOSE request
1465 */
1466static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_closeargs *args)
1467{
1468 struct xdr_stream xdr;
1469 struct compound_hdr hdr = {
516a6af6 1470 .nops = 3,
1da177e4
LT
1471 };
1472 int status;
1473
1474 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1475 encode_compound_hdr(&xdr, &hdr);
1476 status = encode_putfh(&xdr, args->fh);
1477 if(status)
1478 goto out;
1479 status = encode_close(&xdr, args);
516a6af6
TM
1480 if (status != 0)
1481 goto out;
1482 status = encode_getfattr(&xdr, args->bitmask);
1da177e4
LT
1483out:
1484 return status;
1485}
1486
1487/*
1488 * Encode an OPEN request
1489 */
1490static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args)
1491{
1492 struct xdr_stream xdr;
1493 struct compound_hdr hdr = {
56ae19f3 1494 .nops = 7,
1da177e4
LT
1495 };
1496 int status;
1497
cee54fc9
TM
1498 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1499 if (status != 0)
1500 goto out;
1da177e4
LT
1501 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1502 encode_compound_hdr(&xdr, &hdr);
1503 status = encode_putfh(&xdr, args->fh);
56ae19f3
TM
1504 if (status)
1505 goto out;
1506 status = encode_savefh(&xdr);
1da177e4
LT
1507 if (status)
1508 goto out;
1509 status = encode_open(&xdr, args);
1510 if (status)
1511 goto out;
1512 status = encode_getfh(&xdr);
1513 if (status)
1514 goto out;
1515 status = encode_getfattr(&xdr, args->bitmask);
56ae19f3
TM
1516 if (status)
1517 goto out;
1518 status = encode_restorefh(&xdr);
1519 if (status)
1520 goto out;
1521 status = encode_getfattr(&xdr, args->bitmask);
1da177e4
LT
1522out:
1523 return status;
1524}
1525
1526/*
1527 * Encode an OPEN_CONFIRM request
1528 */
1529static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_open_confirmargs *args)
1530{
1531 struct xdr_stream xdr;
1532 struct compound_hdr hdr = {
1533 .nops = 2,
1534 };
1535 int status;
1536
cee54fc9
TM
1537 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1538 if (status != 0)
1539 goto out;
1da177e4
LT
1540 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1541 encode_compound_hdr(&xdr, &hdr);
1542 status = encode_putfh(&xdr, args->fh);
1543 if(status)
1544 goto out;
1545 status = encode_open_confirm(&xdr, args);
1546out:
1547 return status;
1548}
1549
1550/*
1551 * Encode an OPEN request with no attributes.
1552 */
1553static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args)
1554{
1555 struct xdr_stream xdr;
1556 struct compound_hdr hdr = {
1557 .nops = 2,
1558 };
1559 int status;
1560
cee54fc9
TM
1561 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1562 if (status != 0)
1563 goto out;
1da177e4
LT
1564 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1565 encode_compound_hdr(&xdr, &hdr);
1566 status = encode_putfh(&xdr, args->fh);
1567 if (status)
1568 goto out;
1569 status = encode_open(&xdr, args);
1570out:
1571 return status;
1572}
1573
1574/*
1575 * Encode an OPEN_DOWNGRADE request
1576 */
1577static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct nfs_closeargs *args)
1578{
1579 struct xdr_stream xdr;
1580 struct compound_hdr hdr = {
516a6af6 1581 .nops = 3,
1da177e4
LT
1582 };
1583 int status;
1584
1585 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1586 encode_compound_hdr(&xdr, &hdr);
1587 status = encode_putfh(&xdr, args->fh);
1588 if (status)
1589 goto out;
1590 status = encode_open_downgrade(&xdr, args);
516a6af6
TM
1591 if (status != 0)
1592 goto out;
1593 status = encode_getfattr(&xdr, args->bitmask);
1da177e4
LT
1594out:
1595 return status;
1596}
1597
1598/*
1599 * Encode a LOCK request
1600 */
1601static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
1602{
1603 struct xdr_stream xdr;
1604 struct compound_hdr hdr = {
1605 .nops = 2,
1606 };
cee54fc9 1607 struct nfs_lock_opargs *opargs = args->u.lock;
1da177e4
LT
1608 int status;
1609
06735b34 1610 status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
cee54fc9
TM
1611 if (status != 0)
1612 goto out;
06735b34
TM
1613 /* Do we need to do an open_to_lock_owner? */
1614 if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
1615 opargs->new_lock_owner = 0;
1da177e4
LT
1616 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1617 encode_compound_hdr(&xdr, &hdr);
1618 status = encode_putfh(&xdr, args->fh);
1619 if(status)
1620 goto out;
1621 status = encode_lock(&xdr, args);
1622out:
1623 return status;
1624}
1625
1626/*
1627 * Encode a LOCKT request
1628 */
1629static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
1630{
1631 struct xdr_stream xdr;
1632 struct compound_hdr hdr = {
1633 .nops = 2,
1634 };
1635 int status;
1636
1637 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1638 encode_compound_hdr(&xdr, &hdr);
1639 status = encode_putfh(&xdr, args->fh);
1640 if(status)
1641 goto out;
1642 status = encode_lockt(&xdr, args);
1643out:
1644 return status;
1645}
1646
1647/*
1648 * Encode a LOCKU request
1649 */
1650static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
1651{
1652 struct xdr_stream xdr;
1653 struct compound_hdr hdr = {
1654 .nops = 2,
1655 };
1656 int status;
1657
1658 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1659 encode_compound_hdr(&xdr, &hdr);
1660 status = encode_putfh(&xdr, args->fh);
1661 if(status)
1662 goto out;
1663 status = encode_locku(&xdr, args);
1664out:
1665 return status;
1666}
1667
1668/*
1669 * Encode a READLINK request
1670 */
1671static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readlink *args)
1672{
1673 struct xdr_stream xdr;
1674 struct compound_hdr hdr = {
1675 .nops = 2,
1676 };
1677 int status;
1678
1679 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1680 encode_compound_hdr(&xdr, &hdr);
1681 status = encode_putfh(&xdr, args->fh);
1682 if(status)
1683 goto out;
1684 status = encode_readlink(&xdr, args, req);
1685out:
1686 return status;
1687}
1688
1689/*
1690 * Encode a READDIR request
1691 */
1692static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readdir_arg *args)
1693{
1694 struct xdr_stream xdr;
1695 struct compound_hdr hdr = {
1696 .nops = 2,
1697 };
1698 int status;
1699
1700 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1701 encode_compound_hdr(&xdr, &hdr);
1702 status = encode_putfh(&xdr, args->fh);
1703 if(status)
1704 goto out;
1705 status = encode_readdir(&xdr, args, req);
1706out:
1707 return status;
1708}
1709
1710/*
1711 * Encode a READ request
1712 */
1713static int nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args)
1714{
1715 struct rpc_auth *auth = req->rq_task->tk_auth;
1716 struct xdr_stream xdr;
1717 struct compound_hdr hdr = {
1718 .nops = 2,
1719 };
1720 int replen, status;
1721
1722 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1723 encode_compound_hdr(&xdr, &hdr);
1724 status = encode_putfh(&xdr, args->fh);
1725 if (status)
1726 goto out;
1727 status = encode_read(&xdr, args);
1728 if (status)
1729 goto out;
1730
1731 /* set up reply kvec
1732 * toplevel status + taglen=0 + rescount + OP_PUTFH + status
1733 * + OP_READ + status + eof + datalen = 9
1734 */
1735 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
1736 xdr_inline_pages(&req->rq_rcv_buf, replen,
1737 args->pages, args->pgbase, args->count);
1738out:
1739 return status;
1740}
1741
1742/*
1743 * Encode an SETATTR request
1744 */
1745static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, uint32_t *p, struct nfs_setattrargs *args)
1746
1747{
1748 struct xdr_stream xdr;
1749 struct compound_hdr hdr = {
1750 .nops = 3,
1751 };
1752 int status;
1753
1754 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1755 encode_compound_hdr(&xdr, &hdr);
1756 status = encode_putfh(&xdr, args->fh);
1757 if(status)
1758 goto out;
1759 status = encode_setattr(&xdr, args, args->server);
1760 if(status)
1761 goto out;
1762 status = encode_getfattr(&xdr, args->bitmask);
1763out:
1764 return status;
1765}
1766
029d105e
BF
1767/*
1768 * Encode a GETACL request
1769 */
1770static int
1771nfs4_xdr_enc_getacl(struct rpc_rqst *req, uint32_t *p,
1772 struct nfs_getaclargs *args)
1773{
1774 struct xdr_stream xdr;
1775 struct rpc_auth *auth = req->rq_task->tk_auth;
1776 struct compound_hdr hdr = {
1777 .nops = 2,
1778 };
1779 int replen, status;
1780
1781 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1782 encode_compound_hdr(&xdr, &hdr);
1783 status = encode_putfh(&xdr, args->fh);
1784 if (status)
1785 goto out;
1786 status = encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0);
1787 /* set up reply buffer: */
1788 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
1789 xdr_inline_pages(&req->rq_rcv_buf, replen,
1790 args->acl_pages, args->acl_pgbase, args->acl_len);
1791out:
1792 return status;
1793}
1794
1da177e4
LT
1795/*
1796 * Encode a WRITE request
1797 */
1798static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
1799{
1800 struct xdr_stream xdr;
1801 struct compound_hdr hdr = {
1802 .nops = 2,
1803 };
1804 int status;
1805
1806 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1807 encode_compound_hdr(&xdr, &hdr);
1808 status = encode_putfh(&xdr, args->fh);
1809 if (status)
1810 goto out;
1811 status = encode_write(&xdr, args);
1812out:
1813 return status;
1814}
1815
1816/*
1817 * a COMMIT request
1818 */
1819static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
1820{
1821 struct xdr_stream xdr;
1822 struct compound_hdr hdr = {
1823 .nops = 2,
1824 };
1825 int status;
1826
1827 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1828 encode_compound_hdr(&xdr, &hdr);
1829 status = encode_putfh(&xdr, args->fh);
1830 if (status)
1831 goto out;
1832 status = encode_commit(&xdr, args);
1833out:
1834 return status;
1835}
1836
1837/*
1838 * FSINFO request
1839 */
1840static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fsinfo_arg *args)
1841{
1842 struct xdr_stream xdr;
1843 struct compound_hdr hdr = {
1844 .nops = 2,
1845 };
1846 int status;
1847
1848 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1849 encode_compound_hdr(&xdr, &hdr);
1850 status = encode_putfh(&xdr, args->fh);
1851 if (!status)
1852 status = encode_fsinfo(&xdr, args->bitmask);
1853 return status;
1854}
1855
1856/*
1857 * a PATHCONF request
1858 */
1859static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args)
1860{
1da177e4
LT
1861 struct xdr_stream xdr;
1862 struct compound_hdr hdr = {
1863 .nops = 2,
1864 };
1865 int status;
1866
1867 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1868 encode_compound_hdr(&xdr, &hdr);
1869 status = encode_putfh(&xdr, args->fh);
1870 if (!status)
1871 status = encode_getattr_one(&xdr,
1872 args->bitmask[0] & nfs4_pathconf_bitmap[0]);
1873 return status;
1874}
1875
1876/*
1877 * a STATFS request
1878 */
1879static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args)
1880{
1da177e4
LT
1881 struct xdr_stream xdr;
1882 struct compound_hdr hdr = {
1883 .nops = 2,
1884 };
1885 int status;
1886
1887 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1888 encode_compound_hdr(&xdr, &hdr);
1889 status = encode_putfh(&xdr, args->fh);
1890 if (status == 0)
1891 status = encode_getattr_two(&xdr,
1892 args->bitmask[0] & nfs4_statfs_bitmap[0],
1893 args->bitmask[1] & nfs4_statfs_bitmap[1]);
1894 return status;
1895}
1896
1897/*
1898 * GETATTR_BITMAP request
1899 */
1900static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const struct nfs_fh *fhandle)
1901{
1902 struct xdr_stream xdr;
1903 struct compound_hdr hdr = {
1904 .nops = 2,
1905 };
1906 int status;
1907
1908 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1909 encode_compound_hdr(&xdr, &hdr);
1910 status = encode_putfh(&xdr, fhandle);
1911 if (status == 0)
1912 status = encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
1913 FATTR4_WORD0_LINK_SUPPORT|
1914 FATTR4_WORD0_SYMLINK_SUPPORT|
1915 FATTR4_WORD0_ACLSUPPORT);
1916 return status;
1917}
1918
1919/*
1920 * a RENEW request
1921 */
1922static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp)
1923{
1924 struct xdr_stream xdr;
1925 struct compound_hdr hdr = {
1926 .nops = 1,
1927 };
1928
1929 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1930 encode_compound_hdr(&xdr, &hdr);
1931 return encode_renew(&xdr, clp);
1932}
1933
1934/*
1935 * a SETCLIENTID request
1936 */
1937static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nfs4_setclientid *sc)
1938{
1939 struct xdr_stream xdr;
1940 struct compound_hdr hdr = {
1941 .nops = 1,
1942 };
1943
1944 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1945 encode_compound_hdr(&xdr, &hdr);
1946 return encode_setclientid(&xdr, sc);
1947}
1948
1949/*
1950 * a SETCLIENTID_CONFIRM request
1951 */
1952static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp)
1953{
1954 struct xdr_stream xdr;
1955 struct compound_hdr hdr = {
1956 .nops = 3,
1957 };
1958 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
1959 int status;
1960
1961 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1962 encode_compound_hdr(&xdr, &hdr);
1963 status = encode_setclientid_confirm(&xdr, clp);
1964 if (!status)
1965 status = encode_putrootfh(&xdr);
1966 if (!status)
1967 status = encode_fsinfo(&xdr, lease_bitmap);
1968 return status;
1969}
1970
1971/*
1972 * DELEGRETURN request
1973 */
1974static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const struct nfs4_delegreturnargs *args)
1975{
1976 struct xdr_stream xdr;
1977 struct compound_hdr hdr = {
1978 .nops = 2,
1979 };
1980 int status;
1981
1982 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1983 encode_compound_hdr(&xdr, &hdr);
1984 if ((status = encode_putfh(&xdr, args->fhandle)) == 0)
1985 status = encode_delegreturn(&xdr, args->stateid);
1986 return status;
1987}
1988
1989/*
1990 * START OF "GENERIC" DECODE ROUTINES.
1991 * These may look a little ugly since they are imported from a "generic"
1992 * set of XDR encode/decode routines which are intended to be shared by
1993 * all of our NFSv4 implementations (OpenBSD, MacOS X...).
1994 *
1995 * If the pain of reading these is too great, it should be a straightforward
1996 * task to translate them into Linux-specific versions which are more
1997 * consistent with the style used in NFSv2/v3...
1998 */
1999#define READ32(x) (x) = ntohl(*p++)
2000#define READ64(x) do { \
2001 (x) = (u64)ntohl(*p++) << 32; \
2002 (x) |= ntohl(*p++); \
2003} while (0)
2004#define READTIME(x) do { \
2005 p++; \
2006 (x.tv_sec) = ntohl(*p++); \
2007 (x.tv_nsec) = ntohl(*p++); \
2008} while (0)
2009#define COPYMEM(x,nbytes) do { \
2010 memcpy((x), p, nbytes); \
2011 p += XDR_QUADLEN(nbytes); \
2012} while (0)
2013
2014#define READ_BUF(nbytes) do { \
2015 p = xdr_inline_decode(xdr, nbytes); \
2016 if (!p) { \
2017 printk(KERN_WARNING "%s: reply buffer overflowed in line %d.", \
2018 __FUNCTION__, __LINE__); \
2019 return -EIO; \
2020 } \
2021} while (0)
2022
2023static int decode_opaque_inline(struct xdr_stream *xdr, uint32_t *len, char **string)
2024{
2025 uint32_t *p;
2026
2027 READ_BUF(4);
2028 READ32(*len);
2029 READ_BUF(*len);
2030 *string = (char *)p;
2031 return 0;
2032}
2033
2034static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
2035{
2036 uint32_t *p;
2037
2038 READ_BUF(8);
2039 READ32(hdr->status);
2040 READ32(hdr->taglen);
2041
2042 READ_BUF(hdr->taglen + 4);
2043 hdr->tag = (char *)p;
2044 p += XDR_QUADLEN(hdr->taglen);
2045 READ32(hdr->nops);
2046 return 0;
2047}
2048
2049static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
2050{
2051 uint32_t *p;
2052 uint32_t opnum;
2053 int32_t nfserr;
2054
2055 READ_BUF(8);
2056 READ32(opnum);
2057 if (opnum != expected) {
2058 printk(KERN_NOTICE
2059 "nfs4_decode_op_hdr: Server returned operation"
2060 " %d but we issued a request for %d\n",
2061 opnum, expected);
2062 return -EIO;
2063 }
2064 READ32(nfserr);
2065 if (nfserr != NFS_OK)
2066 return -nfs_stat_to_errno(nfserr);
2067 return 0;
2068}
2069
2070/* Dummy routine */
2071static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs4_client *clp)
2072{
2073 uint32_t *p;
2074 uint32_t strlen;
2075 char *str;
2076
2077 READ_BUF(12);
2078 return decode_opaque_inline(xdr, &strlen, &str);
2079}
2080
2081static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
2082{
2083 uint32_t bmlen, *p;
2084
2085 READ_BUF(4);
2086 READ32(bmlen);
2087
2088 bitmap[0] = bitmap[1] = 0;
2089 READ_BUF((bmlen << 2));
2090 if (bmlen > 0) {
2091 READ32(bitmap[0]);
2092 if (bmlen > 1)
2093 READ32(bitmap[1]);
2094 }
2095 return 0;
2096}
2097
2098static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, uint32_t **savep)
2099{
2100 uint32_t *p;
2101
2102 READ_BUF(4);
2103 READ32(*attrlen);
2104 *savep = xdr->p;
2105 return 0;
2106}
2107
2108static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask)
2109{
2110 if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) {
2111 decode_attr_bitmap(xdr, bitmask);
2112 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
2113 } else
2114 bitmask[0] = bitmask[1] = 0;
2115 dprintk("%s: bitmask=0x%x%x\n", __FUNCTION__, bitmask[0], bitmask[1]);
2116 return 0;
2117}
2118
2119static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type)
2120{
2121 uint32_t *p;
2122
2123 *type = 0;
2124 if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
2125 return -EIO;
2126 if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) {
2127 READ_BUF(4);
2128 READ32(*type);
2129 if (*type < NF4REG || *type > NF4NAMEDATTR) {
2130 dprintk("%s: bad type %d\n", __FUNCTION__, *type);
2131 return -EIO;
2132 }
2133 bitmap[0] &= ~FATTR4_WORD0_TYPE;
2134 }
2135 dprintk("%s: type=0%o\n", __FUNCTION__, nfs_type2fmt[*type].nfs2type);
2136 return 0;
2137}
2138
2139static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
2140{
2141 uint32_t *p;
2142
2143 *change = 0;
2144 if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
2145 return -EIO;
2146 if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) {
2147 READ_BUF(8);
2148 READ64(*change);
2149 bitmap[0] &= ~FATTR4_WORD0_CHANGE;
2150 }
2151 dprintk("%s: change attribute=%Lu\n", __FUNCTION__,
2152 (unsigned long long)*change);
2153 return 0;
2154}
2155
2156static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
2157{
2158 uint32_t *p;
2159
2160 *size = 0;
2161 if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
2162 return -EIO;
2163 if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) {
2164 READ_BUF(8);
2165 READ64(*size);
2166 bitmap[0] &= ~FATTR4_WORD0_SIZE;
2167 }
2168 dprintk("%s: file size=%Lu\n", __FUNCTION__, (unsigned long long)*size);
2169 return 0;
2170}
2171
2172static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2173{
2174 uint32_t *p;
2175
2176 *res = 0;
2177 if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U)))
2178 return -EIO;
2179 if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) {
2180 READ_BUF(4);
2181 READ32(*res);
2182 bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT;
2183 }
2184 dprintk("%s: link support=%s\n", __FUNCTION__, *res == 0 ? "false" : "true");
2185 return 0;
2186}
2187
2188static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2189{
2190 uint32_t *p;
2191
2192 *res = 0;
2193 if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U)))
2194 return -EIO;
2195 if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) {
2196 READ_BUF(4);
2197 READ32(*res);
2198 bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT;
2199 }
2200 dprintk("%s: symlink support=%s\n", __FUNCTION__, *res == 0 ? "false" : "true");
2201 return 0;
2202}
2203
2204static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fsid *fsid)
2205{
2206 uint32_t *p;
2207
2208 fsid->major = 0;
2209 fsid->minor = 0;
2210 if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U)))
2211 return -EIO;
2212 if (likely(bitmap[0] & FATTR4_WORD0_FSID)) {
2213 READ_BUF(16);
2214 READ64(fsid->major);
2215 READ64(fsid->minor);
2216 bitmap[0] &= ~FATTR4_WORD0_FSID;
2217 }
2218 dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __FUNCTION__,
2219 (unsigned long long)fsid->major,
2220 (unsigned long long)fsid->minor);
2221 return 0;
2222}
2223
2224static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2225{
2226 uint32_t *p;
2227
2228 *res = 60;
2229 if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U)))
2230 return -EIO;
2231 if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) {
2232 READ_BUF(4);
2233 READ32(*res);
2234 bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME;
2235 }
2236 dprintk("%s: file size=%u\n", __FUNCTION__, (unsigned int)*res);
2237 return 0;
2238}
2239
2240static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2241{
2242 uint32_t *p;
2243
2244 *res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL;
2245 if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U)))
2246 return -EIO;
2247 if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) {
2248 READ_BUF(4);
2249 READ32(*res);
2250 bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT;
2251 }
2252 dprintk("%s: ACLs supported=%u\n", __FUNCTION__, (unsigned int)*res);
2253 return 0;
2254}
2255
2256static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
2257{
2258 uint32_t *p;
2259
2260 *fileid = 0;
2261 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
2262 return -EIO;
2263 if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) {
2264 READ_BUF(8);
2265 READ64(*fileid);
2266 bitmap[0] &= ~FATTR4_WORD0_FILEID;
2267 }
2268 dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid);
2269 return 0;
2270}
2271
2272static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2273{
2274 uint32_t *p;
2275 int status = 0;
2276
2277 *res = 0;
2278 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U)))
2279 return -EIO;
2280 if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) {
2281 READ_BUF(8);
2282 READ64(*res);
2283 bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL;
2284 }
2285 dprintk("%s: files avail=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2286 return status;
2287}
2288
2289static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2290{
2291 uint32_t *p;
2292 int status = 0;
2293
2294 *res = 0;
2295 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U)))
2296 return -EIO;
2297 if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) {
2298 READ_BUF(8);
2299 READ64(*res);
2300 bitmap[0] &= ~FATTR4_WORD0_FILES_FREE;
2301 }
2302 dprintk("%s: files free=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2303 return status;
2304}
2305
2306static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2307{
2308 uint32_t *p;
2309 int status = 0;
2310
2311 *res = 0;
2312 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U)))
2313 return -EIO;
2314 if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) {
2315 READ_BUF(8);
2316 READ64(*res);
2317 bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL;
2318 }
2319 dprintk("%s: files total=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2320 return status;
2321}
2322
2323static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2324{
2325 uint32_t *p;
2326 int status = 0;
2327
2328 *res = 0;
2329 if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U)))
2330 return -EIO;
2331 if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) {
2332 READ_BUF(8);
2333 READ64(*res);
2334 bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE;
2335 }
2336 dprintk("%s: maxfilesize=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2337 return status;
2338}
2339
2340static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink)
2341{
2342 uint32_t *p;
2343 int status = 0;
2344
2345 *maxlink = 1;
2346 if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U)))
2347 return -EIO;
2348 if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) {
2349 READ_BUF(4);
2350 READ32(*maxlink);
2351 bitmap[0] &= ~FATTR4_WORD0_MAXLINK;
2352 }
2353 dprintk("%s: maxlink=%u\n", __FUNCTION__, *maxlink);
2354 return status;
2355}
2356
2357static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname)
2358{
2359 uint32_t *p;
2360 int status = 0;
2361
2362 *maxname = 1024;
2363 if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U)))
2364 return -EIO;
2365 if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) {
2366 READ_BUF(4);
2367 READ32(*maxname);
2368 bitmap[0] &= ~FATTR4_WORD0_MAXNAME;
2369 }
2370 dprintk("%s: maxname=%u\n", __FUNCTION__, *maxname);
2371 return status;
2372}
2373
2374static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2375{
2376 uint32_t *p;
2377 int status = 0;
2378
2379 *res = 1024;
2380 if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXREAD - 1U)))
2381 return -EIO;
2382 if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) {
2383 uint64_t maxread;
2384 READ_BUF(8);
2385 READ64(maxread);
2386 if (maxread > 0x7FFFFFFF)
2387 maxread = 0x7FFFFFFF;
2388 *res = (uint32_t)maxread;
2389 bitmap[0] &= ~FATTR4_WORD0_MAXREAD;
2390 }
2391 dprintk("%s: maxread=%lu\n", __FUNCTION__, (unsigned long)*res);
2392 return status;
2393}
2394
2395static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2396{
2397 uint32_t *p;
2398 int status = 0;
2399
2400 *res = 1024;
2401 if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXWRITE - 1U)))
2402 return -EIO;
2403 if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) {
2404 uint64_t maxwrite;
2405 READ_BUF(8);
2406 READ64(maxwrite);
2407 if (maxwrite > 0x7FFFFFFF)
2408 maxwrite = 0x7FFFFFFF;
2409 *res = (uint32_t)maxwrite;
2410 bitmap[0] &= ~FATTR4_WORD0_MAXWRITE;
2411 }
2412 dprintk("%s: maxwrite=%lu\n", __FUNCTION__, (unsigned long)*res);
2413 return status;
2414}
2415
2416static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode)
2417{
2418 uint32_t *p;
2419
2420 *mode = 0;
2421 if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
2422 return -EIO;
2423 if (likely(bitmap[1] & FATTR4_WORD1_MODE)) {
2424 READ_BUF(4);
2425 READ32(*mode);
2426 *mode &= ~S_IFMT;
2427 bitmap[1] &= ~FATTR4_WORD1_MODE;
2428 }
2429 dprintk("%s: file mode=0%o\n", __FUNCTION__, (unsigned int)*mode);
2430 return 0;
2431}
2432
2433static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
2434{
2435 uint32_t *p;
2436
2437 *nlink = 1;
2438 if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
2439 return -EIO;
2440 if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) {
2441 READ_BUF(4);
2442 READ32(*nlink);
2443 bitmap[1] &= ~FATTR4_WORD1_NUMLINKS;
2444 }
2445 dprintk("%s: nlink=%u\n", __FUNCTION__, (unsigned int)*nlink);
2446 return 0;
2447}
2448
2449static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *uid)
2450{
2451 uint32_t len, *p;
2452
2453 *uid = -2;
2454 if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
2455 return -EIO;
2456 if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) {
2457 READ_BUF(4);
2458 READ32(len);
2459 READ_BUF(len);
2460 if (len < XDR_MAX_NETOBJ) {
2461 if (nfs_map_name_to_uid(clp, (char *)p, len, uid) != 0)
2462 dprintk("%s: nfs_map_name_to_uid failed!\n",
2463 __FUNCTION__);
2464 } else
2465 printk(KERN_WARNING "%s: name too long (%u)!\n",
2466 __FUNCTION__, len);
2467 bitmap[1] &= ~FATTR4_WORD1_OWNER;
2468 }
2469 dprintk("%s: uid=%d\n", __FUNCTION__, (int)*uid);
2470 return 0;
2471}
2472
2473static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *gid)
2474{
2475 uint32_t len, *p;
2476
2477 *gid = -2;
2478 if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
2479 return -EIO;
2480 if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) {
2481 READ_BUF(4);
2482 READ32(len);
2483 READ_BUF(len);
2484 if (len < XDR_MAX_NETOBJ) {
2485 if (nfs_map_group_to_gid(clp, (char *)p, len, gid) != 0)
2486 dprintk("%s: nfs_map_group_to_gid failed!\n",
2487 __FUNCTION__);
2488 } else
2489 printk(KERN_WARNING "%s: name too long (%u)!\n",
2490 __FUNCTION__, len);
2491 bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
2492 }
2493 dprintk("%s: gid=%d\n", __FUNCTION__, (int)*gid);
2494 return 0;
2495}
2496
2497static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
2498{
2499 uint32_t major = 0, minor = 0, *p;
2500
2501 *rdev = MKDEV(0,0);
2502 if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U)))
2503 return -EIO;
2504 if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) {
2505 dev_t tmp;
2506
2507 READ_BUF(8);
2508 READ32(major);
2509 READ32(minor);
2510 tmp = MKDEV(major, minor);
2511 if (MAJOR(tmp) == major && MINOR(tmp) == minor)
2512 *rdev = tmp;
2513 bitmap[1] &= ~ FATTR4_WORD1_RAWDEV;
2514 }
2515 dprintk("%s: rdev=(0x%x:0x%x)\n", __FUNCTION__, major, minor);
2516 return 0;
2517}
2518
2519static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2520{
2521 uint32_t *p;
2522 int status = 0;
2523
2524 *res = 0;
2525 if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U)))
2526 return -EIO;
2527 if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) {
2528 READ_BUF(8);
2529 READ64(*res);
2530 bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL;
2531 }
2532 dprintk("%s: space avail=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2533 return status;
2534}
2535
2536static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2537{
2538 uint32_t *p;
2539 int status = 0;
2540
2541 *res = 0;
2542 if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U)))
2543 return -EIO;
2544 if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) {
2545 READ_BUF(8);
2546 READ64(*res);
2547 bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE;
2548 }
2549 dprintk("%s: space free=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2550 return status;
2551}
2552
2553static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2554{
2555 uint32_t *p;
2556 int status = 0;
2557
2558 *res = 0;
2559 if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U)))
2560 return -EIO;
2561 if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) {
2562 READ_BUF(8);
2563 READ64(*res);
2564 bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL;
2565 }
2566 dprintk("%s: space total=%Lu\n", __FUNCTION__, (unsigned long long)*res);
2567 return status;
2568}
2569
2570static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
2571{
2572 uint32_t *p;
2573
2574 *used = 0;
2575 if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
2576 return -EIO;
2577 if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) {
2578 READ_BUF(8);
2579 READ64(*used);
2580 bitmap[1] &= ~FATTR4_WORD1_SPACE_USED;
2581 }
2582 dprintk("%s: space used=%Lu\n", __FUNCTION__,
2583 (unsigned long long)*used);
2584 return 0;
2585}
2586
2587static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
2588{
2589 uint32_t *p;
2590 uint64_t sec;
2591 uint32_t nsec;
2592
2593 READ_BUF(12);
2594 READ64(sec);
2595 READ32(nsec);
2596 time->tv_sec = (time_t)sec;
2597 time->tv_nsec = (long)nsec;
2598 return 0;
2599}
2600
2601static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
2602{
2603 int status = 0;
2604
2605 time->tv_sec = 0;
2606 time->tv_nsec = 0;
2607 if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_ACCESS - 1U)))
2608 return -EIO;
2609 if (likely(bitmap[1] & FATTR4_WORD1_TIME_ACCESS)) {
2610 status = decode_attr_time(xdr, time);
2611 bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS;
2612 }
2613 dprintk("%s: atime=%ld\n", __FUNCTION__, (long)time->tv_sec);
2614 return status;
2615}
2616
2617static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
2618{
2619 int status = 0;
2620
2621 time->tv_sec = 0;
2622 time->tv_nsec = 0;
2623 if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_METADATA - 1U)))
2624 return -EIO;
2625 if (likely(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) {
2626 status = decode_attr_time(xdr, time);
2627 bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA;
2628 }
2629 dprintk("%s: ctime=%ld\n", __FUNCTION__, (long)time->tv_sec);
2630 return status;
2631}
2632
2633static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
2634{
2635 int status = 0;
2636
2637 time->tv_sec = 0;
2638 time->tv_nsec = 0;
2639 if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_MODIFY - 1U)))
2640 return -EIO;
2641 if (likely(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) {
2642 status = decode_attr_time(xdr, time);
2643 bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY;
2644 }
2645 dprintk("%s: mtime=%ld\n", __FUNCTION__, (long)time->tv_sec);
2646 return status;
2647}
2648
2649static int verify_attr_len(struct xdr_stream *xdr, uint32_t *savep, uint32_t attrlen)
2650{
2651 unsigned int attrwords = XDR_QUADLEN(attrlen);
2652 unsigned int nwords = xdr->p - savep;
2653
2654 if (unlikely(attrwords != nwords)) {
2655 printk(KERN_WARNING "%s: server returned incorrect attribute length: %u %c %u\n",
2656 __FUNCTION__,
2657 attrwords << 2,
2658 (attrwords < nwords) ? '<' : '>',
2659 nwords << 2);
2660 return -EIO;
2661 }
2662 return 0;
2663}
2664
2665static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
2666{
2667 uint32_t *p;
2668
2669 READ_BUF(20);
2670 READ32(cinfo->atomic);
2671 READ64(cinfo->before);
2672 READ64(cinfo->after);
2673 return 0;
2674}
2675
2676static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
2677{
2678 uint32_t *p;
2679 uint32_t supp, acc;
2680 int status;
2681
2682 status = decode_op_hdr(xdr, OP_ACCESS);
2683 if (status)
2684 return status;
2685 READ_BUF(8);
2686 READ32(supp);
2687 READ32(acc);
2688 access->supported = supp;
2689 access->access = acc;
2690 return 0;
2691}
2692
2693static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
2694{
2695 uint32_t *p;
2696 int status;
2697
2698 status = decode_op_hdr(xdr, OP_CLOSE);
2699 if (status)
2700 return status;
2701 READ_BUF(sizeof(res->stateid.data));
2702 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
2703 return 0;
2704}
2705
2706static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res)
2707{
2708 uint32_t *p;
2709 int status;
2710
2711 status = decode_op_hdr(xdr, OP_COMMIT);
2712 if (status)
2713 return status;
2714 READ_BUF(8);
2715 COPYMEM(res->verf->verifier, 8);
2716 return 0;
2717}
2718
2719static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
2720{
2721 uint32_t *p;
2722 uint32_t bmlen;
2723 int status;
2724
2725 status = decode_op_hdr(xdr, OP_CREATE);
2726 if (status)
2727 return status;
2728 if ((status = decode_change_info(xdr, cinfo)))
2729 return status;
2730 READ_BUF(4);
2731 READ32(bmlen);
2732 READ_BUF(bmlen << 2);
2733 return 0;
2734}
2735
2736static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
2737{
2738 uint32_t *savep;
2739 uint32_t attrlen,
2740 bitmap[2] = {0};
2741 int status;
2742
2743 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
2744 goto xdr_error;
2745 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
2746 goto xdr_error;
2747 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
2748 goto xdr_error;
2749 if ((status = decode_attr_supported(xdr, bitmap, res->attr_bitmask)) != 0)
2750 goto xdr_error;
2751 if ((status = decode_attr_link_support(xdr, bitmap, &res->has_links)) != 0)
2752 goto xdr_error;
2753 if ((status = decode_attr_symlink_support(xdr, bitmap, &res->has_symlinks)) != 0)
2754 goto xdr_error;
2755 if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
2756 goto xdr_error;
2757 status = verify_attr_len(xdr, savep, attrlen);
2758xdr_error:
2759 if (status != 0)
2760 printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
2761 return status;
2762}
2763
2764static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
2765{
2766 uint32_t *savep;
2767 uint32_t attrlen,
2768 bitmap[2] = {0};
2769 int status;
2770
2771 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
2772 goto xdr_error;
2773 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
2774 goto xdr_error;
2775 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
2776 goto xdr_error;
2777
2778 if ((status = decode_attr_files_avail(xdr, bitmap, &fsstat->afiles)) != 0)
2779 goto xdr_error;
2780 if ((status = decode_attr_files_free(xdr, bitmap, &fsstat->ffiles)) != 0)
2781 goto xdr_error;
2782 if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0)
2783 goto xdr_error;
2784 if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0)
2785 goto xdr_error;
2786 if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0)
2787 goto xdr_error;
2788 if ((status = decode_attr_space_total(xdr, bitmap, &fsstat->tbytes)) != 0)
2789 goto xdr_error;
2790
2791 status = verify_attr_len(xdr, savep, attrlen);
2792xdr_error:
2793 if (status != 0)
2794 printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
2795 return status;
2796}
2797
2798static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
2799{
2800 uint32_t *savep;
2801 uint32_t attrlen,
2802 bitmap[2] = {0};
2803 int status;
2804
2805 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
2806 goto xdr_error;
2807 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
2808 goto xdr_error;
2809 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
2810 goto xdr_error;
2811
2812 if ((status = decode_attr_maxlink(xdr, bitmap, &pathconf->max_link)) != 0)
2813 goto xdr_error;
2814 if ((status = decode_attr_maxname(xdr, bitmap, &pathconf->max_namelen)) != 0)
2815 goto xdr_error;
2816
2817 status = verify_attr_len(xdr, savep, attrlen);
2818xdr_error:
2819 if (status != 0)
2820 printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
2821 return status;
2822}
2823
2824static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server)
2825{
2826 uint32_t *savep;
2827 uint32_t attrlen,
2828 bitmap[2] = {0},
2829 type;
2830 int status, fmode = 0;
2831
2832 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
2833 goto xdr_error;
2834 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
2835 goto xdr_error;
2836
2837 fattr->bitmap[0] = bitmap[0];
2838 fattr->bitmap[1] = bitmap[1];
2839
2840 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
2841 goto xdr_error;
2842
2843
2844 if ((status = decode_attr_type(xdr, bitmap, &type)) != 0)
2845 goto xdr_error;
2846 fattr->type = nfs_type2fmt[type].nfs2type;
2847 fmode = nfs_type2fmt[type].mode;
2848
2849 if ((status = decode_attr_change(xdr, bitmap, &fattr->change_attr)) != 0)
2850 goto xdr_error;
2851 if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0)
2852 goto xdr_error;
2853 if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid_u.nfs4)) != 0)
2854 goto xdr_error;
2855 if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0)
2856 goto xdr_error;
2857 if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0)
2858 goto xdr_error;
2859 fattr->mode |= fmode;
2860 if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0)
2861 goto xdr_error;
2862 if ((status = decode_attr_owner(xdr, bitmap, server->nfs4_state, &fattr->uid)) != 0)
2863 goto xdr_error;
2864 if ((status = decode_attr_group(xdr, bitmap, server->nfs4_state, &fattr->gid)) != 0)
2865 goto xdr_error;
2866 if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0)
2867 goto xdr_error;
2868 if ((status = decode_attr_space_used(xdr, bitmap, &fattr->du.nfs3.used)) != 0)
2869 goto xdr_error;
2870 if ((status = decode_attr_time_access(xdr, bitmap, &fattr->atime)) != 0)
2871 goto xdr_error;
2872 if ((status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime)) != 0)
2873 goto xdr_error;
2874 if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0)
2875 goto xdr_error;
33801147 2876 if ((status = verify_attr_len(xdr, savep, attrlen)) == 0)
1da177e4 2877 fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4;
1da177e4
LT
2878xdr_error:
2879 if (status != 0)
2880 printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
2881 return status;
2882}
2883
2884
2885static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
2886{
2887 uint32_t *savep;
2888 uint32_t attrlen, bitmap[2];
2889 int status;
2890
2891 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
2892 goto xdr_error;
2893 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
2894 goto xdr_error;
2895 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
2896 goto xdr_error;
2897
2898 fsinfo->rtmult = fsinfo->wtmult = 512; /* ??? */
2899
2900 if ((status = decode_attr_lease_time(xdr, bitmap, &fsinfo->lease_time)) != 0)
2901 goto xdr_error;
2902 if ((status = decode_attr_maxfilesize(xdr, bitmap, &fsinfo->maxfilesize)) != 0)
2903 goto xdr_error;
2904 if ((status = decode_attr_maxread(xdr, bitmap, &fsinfo->rtmax)) != 0)
2905 goto xdr_error;
2906 fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax;
2907 if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0)
2908 goto xdr_error;
2909 fsinfo->wtpref = fsinfo->wtmax;
2910
2911 status = verify_attr_len(xdr, savep, attrlen);
2912xdr_error:
2913 if (status != 0)
2914 printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
2915 return status;
2916}
2917
2918static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
2919{
2920 uint32_t *p;
2921 uint32_t len;
2922 int status;
2923
2924 status = decode_op_hdr(xdr, OP_GETFH);
2925 if (status)
2926 return status;
2927 /* Zero handle first to allow comparisons */
2928 memset(fh, 0, sizeof(*fh));
2929
2930 READ_BUF(4);
2931 READ32(len);
2932 if (len > NFS4_FHSIZE)
2933 return -EIO;
2934 fh->size = len;
2935 READ_BUF(len);
2936 COPYMEM(fh->data, len);
2937 return 0;
2938}
2939
2940static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
2941{
2942 int status;
2943
2944 status = decode_op_hdr(xdr, OP_LINK);
2945 if (status)
2946 return status;
2947 return decode_change_info(xdr, cinfo);
2948}
2949
2950/*
2951 * We create the owner, so we know a proper owner.id length is 4.
2952 */
2953static int decode_lock_denied (struct xdr_stream *xdr, struct nfs_lock_denied *denied)
2954{
2955 uint32_t *p;
2956 uint32_t namelen;
2957
2958 READ_BUF(32);
2959 READ64(denied->offset);
2960 READ64(denied->length);
2961 READ32(denied->type);
2962 READ64(denied->owner.clientid);
2963 READ32(namelen);
2964 READ_BUF(namelen);
2965 if (namelen == 4)
2966 READ32(denied->owner.id);
2967 return -NFS4ERR_DENIED;
2968}
2969
2970static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res)
2971{
2972 uint32_t *p;
2973 int status;
2974
2975 status = decode_op_hdr(xdr, OP_LOCK);
2976 if (status == 0) {
06735b34
TM
2977 READ_BUF(sizeof(res->u.stateid.data));
2978 COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
1da177e4
LT
2979 } else if (status == -NFS4ERR_DENIED)
2980 return decode_lock_denied(xdr, &res->u.denied);
2981 return status;
2982}
2983
2984static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockres *res)
2985{
2986 int status;
2987 status = decode_op_hdr(xdr, OP_LOCKT);
2988 if (status == -NFS4ERR_DENIED)
2989 return decode_lock_denied(xdr, &res->u.denied);
2990 return status;
2991}
2992
2993static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res)
2994{
2995 uint32_t *p;
2996 int status;
2997
2998 status = decode_op_hdr(xdr, OP_LOCKU);
2999 if (status == 0) {
faf5f49c
TM
3000 READ_BUF(sizeof(res->u.stateid.data));
3001 COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
1da177e4
LT
3002 }
3003 return status;
3004}
3005
3006static int decode_lookup(struct xdr_stream *xdr)
3007{
3008 return decode_op_hdr(xdr, OP_LOOKUP);
3009}
3010
3011/* This is too sick! */
3012static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
3013{
3014 uint32_t *p;
3015 uint32_t limit_type, nblocks, blocksize;
3016
3017 READ_BUF(12);
3018 READ32(limit_type);
3019 switch (limit_type) {
3020 case 1:
3021 READ64(*maxsize);
3022 break;
3023 case 2:
3024 READ32(nblocks);
3025 READ32(blocksize);
3026 *maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
3027 }
3028 return 0;
3029}
3030
3031static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3032{
3033 uint32_t *p;
3034 uint32_t delegation_type;
3035
3036 READ_BUF(4);
3037 READ32(delegation_type);
3038 if (delegation_type == NFS4_OPEN_DELEGATE_NONE) {
3039 res->delegation_type = 0;
3040 return 0;
3041 }
3042 READ_BUF(20);
3043 COPYMEM(res->delegation.data, sizeof(res->delegation.data));
3044 READ32(res->do_recall);
3045 switch (delegation_type) {
3046 case NFS4_OPEN_DELEGATE_READ:
3047 res->delegation_type = FMODE_READ;
3048 break;
3049 case NFS4_OPEN_DELEGATE_WRITE:
3050 res->delegation_type = FMODE_WRITE|FMODE_READ;
3051 if (decode_space_limit(xdr, &res->maxsize) < 0)
3052 return -EIO;
3053 }
3054 return decode_ace(xdr, NULL, res->server->nfs4_state);
3055}
3056
3057static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3058{
3059 uint32_t *p;
3060 uint32_t bmlen;
3061 int status;
3062
3063 status = decode_op_hdr(xdr, OP_OPEN);
3064 if (status)
3065 return status;
3066 READ_BUF(sizeof(res->stateid.data));
3067 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
3068
3069 decode_change_info(xdr, &res->cinfo);
3070
3071 READ_BUF(8);
3072 READ32(res->rflags);
3073 READ32(bmlen);
3074 if (bmlen > 10)
3075 goto xdr_error;
3076
3077 READ_BUF(bmlen << 2);
3078 p += bmlen;
3079 return decode_delegation(xdr, res);
3080xdr_error:
3081 printk(KERN_NOTICE "%s: xdr error!\n", __FUNCTION__);
3082 return -EIO;
3083}
3084
3085static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
3086{
3087 uint32_t *p;
3088 int status;
3089
3090 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
3091 if (status)
3092 return status;
3093 READ_BUF(sizeof(res->stateid.data));
3094 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
3095 return 0;
3096}
3097
3098static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res)
3099{
3100 uint32_t *p;
3101 int status;
3102
3103 status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
3104 if (status)
3105 return status;
3106 READ_BUF(sizeof(res->stateid.data));
3107 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
3108 return 0;
3109}
3110
3111static int decode_putfh(struct xdr_stream *xdr)
3112{
3113 return decode_op_hdr(xdr, OP_PUTFH);
3114}
3115
3116static int decode_putrootfh(struct xdr_stream *xdr)
3117{
3118 return decode_op_hdr(xdr, OP_PUTROOTFH);
3119}
3120
3121static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res)
3122{
3123 struct kvec *iov = req->rq_rcv_buf.head;
3124 uint32_t *p;
3125 uint32_t count, eof, recvd, hdrlen;
3126 int status;
3127
3128 status = decode_op_hdr(xdr, OP_READ);
3129 if (status)
3130 return status;
3131 READ_BUF(8);
3132 READ32(eof);
3133 READ32(count);
3134 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
3135 recvd = req->rq_rcv_buf.len - hdrlen;
3136 if (count > recvd) {
3137 printk(KERN_WARNING "NFS: server cheating in read reply: "
3138 "count %u > recvd %u\n", count, recvd);
3139 count = recvd;
3140 eof = 0;
3141 }
3142 xdr_read_pages(xdr, count);
3143 res->eof = eof;
3144 res->count = count;
3145 return 0;
3146}
3147
3148static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir)
3149{
3150 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
3151 struct page *page = *rcvbuf->pages;
3152 struct kvec *iov = rcvbuf->head;
3153 unsigned int nr, pglen = rcvbuf->page_len;
3154 uint32_t *end, *entry, *p, *kaddr;
3155 uint32_t len, attrlen;
3156 int hdrlen, recvd, status;
3157
3158 status = decode_op_hdr(xdr, OP_READDIR);
3159 if (status)
3160 return status;
3161 READ_BUF(8);
3162 COPYMEM(readdir->verifier.data, 8);
eadf4598
TM
3163 dprintk("%s: verifier = 0x%x%x\n",
3164 __FUNCTION__,
3165 ((u32 *)readdir->verifier.data)[0],
3166 ((u32 *)readdir->verifier.data)[1]);
3167
1da177e4
LT
3168
3169 hdrlen = (char *) p - (char *) iov->iov_base;
3170 recvd = rcvbuf->len - hdrlen;
3171 if (pglen > recvd)
3172 pglen = recvd;
3173 xdr_read_pages(xdr, pglen);
3174
3175 BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE);
3176 kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0);
3177 end = (uint32_t *) ((char *)p + pglen + readdir->pgbase);
3178 entry = p;
3179 for (nr = 0; *p++; nr++) {
3180 if (p + 3 > end)
3181 goto short_pkt;
eadf4598 3182 dprintk("cookie = %Lu, ", *((unsigned long long *)p));
1da177e4
LT
3183 p += 2; /* cookie */
3184 len = ntohl(*p++); /* filename length */
3185 if (len > NFS4_MAXNAMLEN) {
3186 printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len);
3187 goto err_unmap;
3188 }
eadf4598 3189 dprintk("filename = %*s\n", len, (char *)p);
1da177e4
LT
3190 p += XDR_QUADLEN(len);
3191 if (p + 1 > end)
3192 goto short_pkt;
3193 len = ntohl(*p++); /* bitmap length */
3194 p += len;
3195 if (p + 1 > end)
3196 goto short_pkt;
3197 attrlen = XDR_QUADLEN(ntohl(*p++));
3198 p += attrlen; /* attributes */
3199 if (p + 2 > end)
3200 goto short_pkt;
3201 entry = p;
3202 }
3203 if (!nr && (entry[0] != 0 || entry[1] == 0))
3204 goto short_pkt;
3205out:
3206 kunmap_atomic(kaddr, KM_USER0);
3207 return 0;
3208short_pkt:
eadf4598 3209 dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr);
1da177e4
LT
3210 entry[0] = entry[1] = 0;
3211 /* truncate listing ? */
3212 if (!nr) {
3213 printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
3214 entry[1] = 1;
3215 }
3216 goto out;
3217err_unmap:
3218 kunmap_atomic(kaddr, KM_USER0);
3219 return -errno_NFSERR_IO;
3220}
3221
3222static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
3223{
3224 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
3225 struct kvec *iov = rcvbuf->head;
3226 int hdrlen, len, recvd;
3227 uint32_t *p;
3228 char *kaddr;
3229 int status;
3230
3231 status = decode_op_hdr(xdr, OP_READLINK);
3232 if (status)
3233 return status;
3234
3235 /* Convert length of symlink */
3236 READ_BUF(4);
3237 READ32(len);
3238 if (len >= rcvbuf->page_len || len <= 0) {
3239 dprintk(KERN_WARNING "nfs: server returned giant symlink!\n");
3240 return -ENAMETOOLONG;
3241 }
3242 hdrlen = (char *) xdr->p - (char *) iov->iov_base;
3243 recvd = req->rq_rcv_buf.len - hdrlen;
3244 if (recvd < len) {
3245 printk(KERN_WARNING "NFS: server cheating in readlink reply: "
3246 "count %u > recvd %u\n", len, recvd);
3247 return -EIO;
3248 }
3249 xdr_read_pages(xdr, len);
3250 /*
3251 * The XDR encode routine has set things up so that
3252 * the link text will be copied directly into the
3253 * buffer. We just have to do overflow-checking,
3254 * and and null-terminate the text (the VFS expects
3255 * null-termination).
3256 */
3257 kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
3258 kaddr[len+rcvbuf->page_base] = '\0';
3259 kunmap_atomic(kaddr, KM_USER0);
3260 return 0;
3261}
3262
3263static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
3264{
3265 int status;
3266
3267 status = decode_op_hdr(xdr, OP_REMOVE);
3268 if (status)
3269 goto out;
3270 status = decode_change_info(xdr, cinfo);
3271out:
3272 return status;
3273}
3274
3275static int decode_rename(struct xdr_stream *xdr, struct nfs4_change_info *old_cinfo,
3276 struct nfs4_change_info *new_cinfo)
3277{
3278 int status;
3279
3280 status = decode_op_hdr(xdr, OP_RENAME);
3281 if (status)
3282 goto out;
3283 if ((status = decode_change_info(xdr, old_cinfo)))
3284 goto out;
3285 status = decode_change_info(xdr, new_cinfo);
3286out:
3287 return status;
3288}
3289
3290static int decode_renew(struct xdr_stream *xdr)
3291{
3292 return decode_op_hdr(xdr, OP_RENEW);
3293}
3294
56ae19f3
TM
3295static int
3296decode_restorefh(struct xdr_stream *xdr)
3297{
3298 return decode_op_hdr(xdr, OP_RESTOREFH);
3299}
3300
029d105e
BF
3301static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
3302 size_t *acl_len)
3303{
3304 uint32_t *savep;
3305 uint32_t attrlen,
3306 bitmap[2] = {0};
3307 struct kvec *iov = req->rq_rcv_buf.head;
3308 int status;
3309
3310 *acl_len = 0;
3311 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3312 goto out;
3313 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3314 goto out;
3315 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3316 goto out;
3317
3318 if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
3319 return -EIO;
3320 if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
3321 int hdrlen, recvd;
3322
3323 /* We ignore &savep and don't do consistency checks on
3324 * the attr length. Let userspace figure it out.... */
3325 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
3326 recvd = req->rq_rcv_buf.len - hdrlen;
3327 if (attrlen > recvd) {
3328 printk(KERN_WARNING "NFS: server cheating in getattr"
3329 " acl reply: attrlen %u > recvd %u\n",
3330 attrlen, recvd);
3331 return -EINVAL;
3332 }
3333 if (attrlen <= *acl_len)
3334 xdr_read_pages(xdr, attrlen);
3335 *acl_len = attrlen;
8c233cf9
BF
3336 } else
3337 status = -EOPNOTSUPP;
029d105e
BF
3338
3339out:
3340 return status;
3341}
3342
1da177e4
LT
3343static int
3344decode_savefh(struct xdr_stream *xdr)
3345{
3346 return decode_op_hdr(xdr, OP_SAVEFH);
3347}
3348
3349static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
3350{
3351 uint32_t *p;
3352 uint32_t bmlen;
3353 int status;
3354
3355
3356 status = decode_op_hdr(xdr, OP_SETATTR);
3357 if (status)
3358 return status;
3359 READ_BUF(4);
3360 READ32(bmlen);
3361 READ_BUF(bmlen << 2);
3362 return 0;
3363}
3364
3365static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp)
3366{
3367 uint32_t *p;
3368 uint32_t opnum;
3369 int32_t nfserr;
3370
3371 READ_BUF(8);
3372 READ32(opnum);
3373 if (opnum != OP_SETCLIENTID) {
3374 printk(KERN_NOTICE
3375 "nfs4_decode_setclientid: Server returned operation"
3376 " %d\n", opnum);
3377 return -EIO;
3378 }
3379 READ32(nfserr);
3380 if (nfserr == NFS_OK) {
3381 READ_BUF(8 + sizeof(clp->cl_confirm.data));
3382 READ64(clp->cl_clientid);
3383 COPYMEM(clp->cl_confirm.data, sizeof(clp->cl_confirm.data));
3384 } else if (nfserr == NFSERR_CLID_INUSE) {
3385 uint32_t len;
3386
3387 /* skip netid string */
3388 READ_BUF(4);
3389 READ32(len);
3390 READ_BUF(len);
3391
3392 /* skip uaddr string */
3393 READ_BUF(4);
3394 READ32(len);
3395 READ_BUF(len);
3396 return -NFSERR_CLID_INUSE;
3397 } else
3398 return -nfs_stat_to_errno(nfserr);
3399
3400 return 0;
3401}
3402
3403static int decode_setclientid_confirm(struct xdr_stream *xdr)
3404{
3405 return decode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM);
3406}
3407
3408static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res)
3409{
3410 uint32_t *p;
3411 int status;
3412
3413 status = decode_op_hdr(xdr, OP_WRITE);
3414 if (status)
3415 return status;
3416
3417 READ_BUF(16);
3418 READ32(res->count);
3419 READ32(res->verf->committed);
3420 COPYMEM(res->verf->verifier, 8);
3421 return 0;
3422}
3423
3424static int decode_delegreturn(struct xdr_stream *xdr)
3425{
3426 return decode_op_hdr(xdr, OP_DELEGRETURN);
3427}
3428
3429/*
3430 * Decode OPEN_DOWNGRADE response
3431 */
3432static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_closeres *res)
3433{
3434 struct xdr_stream xdr;
3435 struct compound_hdr hdr;
3436 int status;
3437
3438 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3439 status = decode_compound_hdr(&xdr, &hdr);
3440 if (status)
3441 goto out;
3442 status = decode_putfh(&xdr);
3443 if (status)
3444 goto out;
3445 status = decode_open_downgrade(&xdr, res);
516a6af6
TM
3446 if (status != 0)
3447 goto out;
3448 decode_getfattr(&xdr, res->fattr, res->server);
1da177e4
LT
3449out:
3450 return status;
3451}
3452
3453/*
3454 * END OF "GENERIC" DECODE ROUTINES.
3455 */
3456
3457/*
3458 * Decode ACCESS response
3459 */
3460static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_accessres *res)
3461{
3462 struct xdr_stream xdr;
3463 struct compound_hdr hdr;
3464 int status;
3465
3466 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3467 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3468 goto out;
3469 if ((status = decode_putfh(&xdr)) == 0)
3470 status = decode_access(&xdr, res);
3471out:
3472 return status;
3473}
3474
3475/*
3476 * Decode LOOKUP response
3477 */
3478static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *res)
3479{
3480 struct xdr_stream xdr;
3481 struct compound_hdr hdr;
3482 int status;
3483
3484 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3485 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3486 goto out;
3487 if ((status = decode_putfh(&xdr)) != 0)
3488 goto out;
3489 if ((status = decode_lookup(&xdr)) != 0)
3490 goto out;
3491 if ((status = decode_getfh(&xdr, res->fh)) != 0)
3492 goto out;
3493 status = decode_getfattr(&xdr, res->fattr, res->server);
3494out:
3495 return status;
3496}
3497
3498/*
3499 * Decode LOOKUP_ROOT response
3500 */
3501static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *res)
3502{
3503 struct xdr_stream xdr;
3504 struct compound_hdr hdr;
3505 int status;
3506
3507 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3508 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3509 goto out;
3510 if ((status = decode_putrootfh(&xdr)) != 0)
3511 goto out;
3512 if ((status = decode_getfh(&xdr, res->fh)) == 0)
3513 status = decode_getfattr(&xdr, res->fattr, res->server);
3514out:
3515 return status;
3516}
3517
3518/*
3519 * Decode REMOVE response
3520 */
16e42959 3521static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res)
1da177e4
LT
3522{
3523 struct xdr_stream xdr;
3524 struct compound_hdr hdr;
3525 int status;
3526
3527 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3528 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3529 goto out;
16e42959
TM
3530 if ((status = decode_putfh(&xdr)) != 0)
3531 goto out;
3532 if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
3533 goto out;
3534 decode_getfattr(&xdr, res->dir_attr, res->server);
1da177e4
LT
3535out:
3536 return status;
3537}
3538
3539/*
3540 * Decode RENAME response
3541 */
3542static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_rename_res *res)
3543{
3544 struct xdr_stream xdr;
3545 struct compound_hdr hdr;
3546 int status;
3547
3548 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3549 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3550 goto out;
3551 if ((status = decode_putfh(&xdr)) != 0)
3552 goto out;
3553 if ((status = decode_savefh(&xdr)) != 0)
3554 goto out;
3555 if ((status = decode_putfh(&xdr)) != 0)
3556 goto out;
6caf2c82
TM
3557 if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0)
3558 goto out;
3559 /* Current FH is target directory */
3560 if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0)
3561 goto out;
3562 if ((status = decode_restorefh(&xdr)) != 0)
3563 goto out;
3564 decode_getfattr(&xdr, res->old_fattr, res->server);
1da177e4
LT
3565out:
3566 return status;
3567}
3568
3569/*
3570 * Decode LINK response
3571 */
91ba2eee 3572static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res)
1da177e4
LT
3573{
3574 struct xdr_stream xdr;
3575 struct compound_hdr hdr;
3576 int status;
3577
3578 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3579 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3580 goto out;
3581 if ((status = decode_putfh(&xdr)) != 0)
3582 goto out;
3583 if ((status = decode_savefh(&xdr)) != 0)
3584 goto out;
3585 if ((status = decode_putfh(&xdr)) != 0)
3586 goto out;
91ba2eee
TM
3587 if ((status = decode_link(&xdr, &res->cinfo)) != 0)
3588 goto out;
3589 /*
3590 * Note order: OP_LINK leaves the directory as the current
3591 * filehandle.
3592 */
3593 if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0)
3594 goto out;
3595 if ((status = decode_restorefh(&xdr)) != 0)
3596 goto out;
3597 decode_getfattr(&xdr, res->fattr, res->server);
1da177e4
LT
3598out:
3599 return status;
3600}
3601
3602/*
3603 * Decode CREATE response
3604 */
3605static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res)
3606{
3607 struct xdr_stream xdr;
3608 struct compound_hdr hdr;
3609 int status;
3610
3611 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3612 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3613 goto out;
3614 if ((status = decode_putfh(&xdr)) != 0)
3615 goto out;
56ae19f3
TM
3616 if ((status = decode_savefh(&xdr)) != 0)
3617 goto out;
1da177e4
LT
3618 if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
3619 goto out;
3620 if ((status = decode_getfh(&xdr, res->fh)) != 0)
3621 goto out;
56ae19f3
TM
3622 if (decode_getfattr(&xdr, res->fattr, res->server) != 0)
3623 goto out;
3624 if ((status = decode_restorefh(&xdr)) != 0)
3625 goto out;
3626 decode_getfattr(&xdr, res->dir_fattr, res->server);
1da177e4
LT
3627out:
3628 return status;
3629}
3630
3631/*
3632 * Decode SYMLINK response
3633 */
3634static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res)
3635{
3636 return nfs4_xdr_dec_create(rqstp, p, res);
3637}
3638
3639/*
3640 * Decode GETATTR response
3641 */
3642static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_getattr_res *res)
3643{
3644 struct xdr_stream xdr;
3645 struct compound_hdr hdr;
3646 int status;
3647
3648 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3649 status = decode_compound_hdr(&xdr, &hdr);
3650 if (status)
3651 goto out;
3652 status = decode_putfh(&xdr);
3653 if (status)
3654 goto out;
3655 status = decode_getfattr(&xdr, res->fattr, res->server);
3656out:
3657 return status;
3658
3659}
3660
23ec6965
BF
3661/*
3662 * Encode an SETACL request
3663 */
3664static int
3665nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args)
3666{
3667 struct xdr_stream xdr;
3668 struct compound_hdr hdr = {
3669 .nops = 2,
3670 };
3671 int status;
3672
3673 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
3674 encode_compound_hdr(&xdr, &hdr);
3675 status = encode_putfh(&xdr, args->fh);
3676 if (status)
3677 goto out;
3678 status = encode_setacl(&xdr, args);
3679out:
3680 return status;
3681}
3682/*
3683 * Decode SETACL response
3684 */
3685static int
3686nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res)
3687{
3688 struct xdr_stream xdr;
3689 struct compound_hdr hdr;
3690 int status;
3691
3692 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3693 status = decode_compound_hdr(&xdr, &hdr);
3694 if (status)
3695 goto out;
3696 status = decode_putfh(&xdr);
3697 if (status)
3698 goto out;
3699 status = decode_setattr(&xdr, res);
3700out:
3701 return status;
3702}
1da177e4 3703
029d105e
BF
3704/*
3705 * Decode GETACL response
3706 */
3707static int
3708nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, uint32_t *p, size_t *acl_len)
3709{
3710 struct xdr_stream xdr;
3711 struct compound_hdr hdr;
3712 int status;
3713
3714 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3715 status = decode_compound_hdr(&xdr, &hdr);
3716 if (status)
3717 goto out;
3718 status = decode_putfh(&xdr);
3719 if (status)
3720 goto out;
3721 status = decode_getacl(&xdr, rqstp, acl_len);
3722
3723out:
3724 return status;
3725}
3726
1da177e4
LT
3727/*
3728 * Decode CLOSE response
3729 */
3730static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_closeres *res)
3731{
3732 struct xdr_stream xdr;
3733 struct compound_hdr hdr;
3734 int status;
3735
3736 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3737 status = decode_compound_hdr(&xdr, &hdr);
3738 if (status)
3739 goto out;
3740 status = decode_putfh(&xdr);
3741 if (status)
3742 goto out;
3743 status = decode_close(&xdr, res);
516a6af6
TM
3744 if (status != 0)
3745 goto out;
3746 /*
3747 * Note: Server may do delete on close for this file
3748 * in which case the getattr call will fail with
3749 * an ESTALE error. Shouldn't be a problem,
3750 * though, since fattr->valid will remain unset.
3751 */
3752 decode_getfattr(&xdr, res->fattr, res->server);
1da177e4
LT
3753out:
3754 return status;
3755}
3756
3757/*
3758 * Decode OPEN response
3759 */
3760static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_openres *res)
3761{
3762 struct xdr_stream xdr;
3763 struct compound_hdr hdr;
3764 int status;
3765
3766 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3767 status = decode_compound_hdr(&xdr, &hdr);
3768 if (status)
3769 goto out;
3770 status = decode_putfh(&xdr);
3771 if (status)
3772 goto out;
56ae19f3
TM
3773 status = decode_savefh(&xdr);
3774 if (status)
3775 goto out;
1da177e4
LT
3776 status = decode_open(&xdr, res);
3777 if (status)
3778 goto out;
3779 status = decode_getfh(&xdr, &res->fh);
3780 if (status)
3781 goto out;
56ae19f3
TM
3782 if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
3783 goto out;
3784 if ((status = decode_restorefh(&xdr)) != 0)
3785 goto out;
3786 decode_getfattr(&xdr, res->dir_attr, res->server);
1da177e4
LT
3787out:
3788 return status;
3789}
3790
3791/*
3792 * Decode OPEN_CONFIRM response
3793 */
3794static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_open_confirmres *res)
3795{
3796 struct xdr_stream xdr;
3797 struct compound_hdr hdr;
3798 int status;
3799
3800 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3801 status = decode_compound_hdr(&xdr, &hdr);
3802 if (status)
3803 goto out;
3804 status = decode_putfh(&xdr);
3805 if (status)
3806 goto out;
3807 status = decode_open_confirm(&xdr, res);
3808out:
3809 return status;
3810}
3811
3812/*
3813 * Decode OPEN response
3814 */
3815static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_openres *res)
3816{
3817 struct xdr_stream xdr;
3818 struct compound_hdr hdr;
3819 int status;
3820
3821 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3822 status = decode_compound_hdr(&xdr, &hdr);
3823 if (status)
3824 goto out;
3825 status = decode_putfh(&xdr);
3826 if (status)
3827 goto out;
3828 status = decode_open(&xdr, res);
3829out:
3830 return status;
3831}
3832
3833/*
3834 * Decode SETATTR response
3835 */
3836static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_setattrres *res)
3837{
3838 struct xdr_stream xdr;
3839 struct compound_hdr hdr;
3840 int status;
3841
3842 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3843 status = decode_compound_hdr(&xdr, &hdr);
3844 if (status)
3845 goto out;
3846 status = decode_putfh(&xdr);
3847 if (status)
3848 goto out;
3849 status = decode_setattr(&xdr, res);
3850 if (status)
3851 goto out;
3852 status = decode_getfattr(&xdr, res->fattr, res->server);
3853 if (status == NFS4ERR_DELAY)
3854 status = 0;
3855out:
3856 return status;
3857}
3858
3859/*
3860 * Decode LOCK response
3861 */
3862static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
3863{
3864 struct xdr_stream xdr;
3865 struct compound_hdr hdr;
3866 int status;
3867
3868 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3869 status = decode_compound_hdr(&xdr, &hdr);
3870 if (status)
3871 goto out;
3872 status = decode_putfh(&xdr);
3873 if (status)
3874 goto out;
3875 status = decode_lock(&xdr, res);
3876out:
3877 return status;
3878}
3879
3880/*
3881 * Decode LOCKT response
3882 */
3883static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
3884{
3885 struct xdr_stream xdr;
3886 struct compound_hdr hdr;
3887 int status;
3888
3889 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3890 status = decode_compound_hdr(&xdr, &hdr);
3891 if (status)
3892 goto out;
3893 status = decode_putfh(&xdr);
3894 if (status)
3895 goto out;
3896 status = decode_lockt(&xdr, res);
3897out:
3898 return status;
3899}
3900
3901/*
3902 * Decode LOCKU response
3903 */
3904static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
3905{
3906 struct xdr_stream xdr;
3907 struct compound_hdr hdr;
3908 int status;
3909
3910 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3911 status = decode_compound_hdr(&xdr, &hdr);
3912 if (status)
3913 goto out;
3914 status = decode_putfh(&xdr);
3915 if (status)
3916 goto out;
3917 status = decode_locku(&xdr, res);
3918out:
3919 return status;
3920}
3921
3922/*
3923 * Decode READLINK response
3924 */
3925static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, uint32_t *p, void *res)
3926{
3927 struct xdr_stream xdr;
3928 struct compound_hdr hdr;
3929 int status;
3930
3931 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3932 status = decode_compound_hdr(&xdr, &hdr);
3933 if (status)
3934 goto out;
3935 status = decode_putfh(&xdr);
3936 if (status)
3937 goto out;
3938 status = decode_readlink(&xdr, rqstp);
3939out:
3940 return status;
3941}
3942
3943/*
3944 * Decode READDIR response
3945 */
3946static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_readdir_res *res)
3947{
3948 struct xdr_stream xdr;
3949 struct compound_hdr hdr;
3950 int status;
3951
3952 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3953 status = decode_compound_hdr(&xdr, &hdr);
3954 if (status)
3955 goto out;
3956 status = decode_putfh(&xdr);
3957 if (status)
3958 goto out;
3959 status = decode_readdir(&xdr, rqstp, res);
3960out:
3961 return status;
3962}
3963
3964/*
3965 * Decode Read response
3966 */
3967static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_readres *res)
3968{
3969 struct xdr_stream xdr;
3970 struct compound_hdr hdr;
3971 int status;
3972
3973 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3974 status = decode_compound_hdr(&xdr, &hdr);
3975 if (status)
3976 goto out;
3977 status = decode_putfh(&xdr);
3978 if (status)
3979 goto out;
3980 status = decode_read(&xdr, rqstp, res);
3981 if (!status)
3982 status = res->count;
3983out:
3984 return status;
3985}
3986
3987/*
3988 * Decode WRITE response
3989 */
3990static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res)
3991{
3992 struct xdr_stream xdr;
3993 struct compound_hdr hdr;
3994 int status;
3995
3996 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3997 status = decode_compound_hdr(&xdr, &hdr);
3998 if (status)
3999 goto out;
4000 status = decode_putfh(&xdr);
4001 if (status)
4002 goto out;
4003 status = decode_write(&xdr, res);
4004 if (!status)
4005 status = res->count;
4006out:
4007 return status;
4008}
4009
4010/*
4011 * Decode COMMIT response
4012 */
4013static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res)
4014{
4015 struct xdr_stream xdr;
4016 struct compound_hdr hdr;
4017 int status;
4018
4019 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4020 status = decode_compound_hdr(&xdr, &hdr);
4021 if (status)
4022 goto out;
4023 status = decode_putfh(&xdr);
4024 if (status)
4025 goto out;
4026 status = decode_commit(&xdr, res);
4027out:
4028 return status;
4029}
4030
4031/*
4032 * FSINFO request
4033 */
4034static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo)
4035{
4036 struct xdr_stream xdr;
4037 struct compound_hdr hdr;
4038 int status;
4039
4040 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4041 status = decode_compound_hdr(&xdr, &hdr);
4042 if (!status)
4043 status = decode_putfh(&xdr);
4044 if (!status)
4045 status = decode_fsinfo(&xdr, fsinfo);
4046 if (!status)
4047 status = -nfs_stat_to_errno(hdr.status);
4048 return status;
4049}
4050
4051/*
4052 * PATHCONF request
4053 */
4054static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, uint32_t *p, struct nfs_pathconf *pathconf)
4055{
4056 struct xdr_stream xdr;
4057 struct compound_hdr hdr;
4058 int status;
4059
4060 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4061 status = decode_compound_hdr(&xdr, &hdr);
4062 if (!status)
4063 status = decode_putfh(&xdr);
4064 if (!status)
4065 status = decode_pathconf(&xdr, pathconf);
4066 return status;
4067}
4068
4069/*
4070 * STATFS request
4071 */
4072static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, uint32_t *p, struct nfs_fsstat *fsstat)
4073{
4074 struct xdr_stream xdr;
4075 struct compound_hdr hdr;
4076 int status;
4077
4078 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4079 status = decode_compound_hdr(&xdr, &hdr);
4080 if (!status)
4081 status = decode_putfh(&xdr);
4082 if (!status)
4083 status = decode_statfs(&xdr, fsstat);
4084 return status;
4085}
4086
4087/*
4088 * GETATTR_BITMAP request
4089 */
4090static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, uint32_t *p, struct nfs4_server_caps_res *res)
4091{
4092 struct xdr_stream xdr;
4093 struct compound_hdr hdr;
4094 int status;
4095
4096 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4097 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
4098 goto out;
4099 if ((status = decode_putfh(&xdr)) != 0)
4100 goto out;
4101 status = decode_server_caps(&xdr, res);
4102out:
4103 return status;
4104}
4105
4106/*
4107 * Decode RENEW response
4108 */
4109static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
4110{
4111 struct xdr_stream xdr;
4112 struct compound_hdr hdr;
4113 int status;
4114
4115 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4116 status = decode_compound_hdr(&xdr, &hdr);
4117 if (!status)
4118 status = decode_renew(&xdr);
4119 return status;
4120}
4121
4122/*
4123 * a SETCLIENTID request
4124 */
4125static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
4126 struct nfs4_client *clp)
4127{
4128 struct xdr_stream xdr;
4129 struct compound_hdr hdr;
4130 int status;
4131
4132 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4133 status = decode_compound_hdr(&xdr, &hdr);
4134 if (!status)
4135 status = decode_setclientid(&xdr, clp);
4136 if (!status)
4137 status = -nfs_stat_to_errno(hdr.status);
4138 return status;
4139}
4140
4141/*
4142 * a SETCLIENTID_CONFIRM request
4143 */
4144static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo)
4145{
4146 struct xdr_stream xdr;
4147 struct compound_hdr hdr;
4148 int status;
4149
4150 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4151 status = decode_compound_hdr(&xdr, &hdr);
4152 if (!status)
4153 status = decode_setclientid_confirm(&xdr);
4154 if (!status)
4155 status = decode_putrootfh(&xdr);
4156 if (!status)
4157 status = decode_fsinfo(&xdr, fsinfo);
4158 if (!status)
4159 status = -nfs_stat_to_errno(hdr.status);
4160 return status;
4161}
4162
4163/*
4164 * DELEGRETURN request
4165 */
4166static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
4167{
4168 struct xdr_stream xdr;
4169 struct compound_hdr hdr;
4170 int status;
4171
4172 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4173 status = decode_compound_hdr(&xdr, &hdr);
4174 if (status == 0) {
4175 status = decode_putfh(&xdr);
4176 if (status == 0)
4177 status = decode_delegreturn(&xdr);
4178 }
4179 return status;
4180}
4181
4182uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
4183{
4184 uint32_t bitmap[2] = {0};
4185 uint32_t len;
4186
4187 if (!*p++) {
4188 if (!*p)
4189 return ERR_PTR(-EAGAIN);
4190 entry->eof = 1;
4191 return ERR_PTR(-EBADCOOKIE);
4192 }
4193
4194 entry->prev_cookie = entry->cookie;
4195 p = xdr_decode_hyper(p, &entry->cookie);
4196 entry->len = ntohl(*p++);
4197 entry->name = (const char *) p;
4198 p += XDR_QUADLEN(entry->len);
4199
4200 /*
4201 * In case the server doesn't return an inode number,
4202 * we fake one here. (We don't use inode number 0,
4203 * since glibc seems to choke on it...)
4204 */
4205 entry->ino = 1;
4206
4207 len = ntohl(*p++); /* bitmap length */
4208 if (len-- > 0) {
4209 bitmap[0] = ntohl(*p++);
4210 if (len-- > 0) {
4211 bitmap[1] = ntohl(*p++);
4212 p += len;
4213 }
4214 }
4215 len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
4216 if (len > 0) {
97d312d0
MN
4217 if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) {
4218 bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
4219 /* Ignore the return value of rdattr_error for now */
4220 p++;
4221 len--;
4222 }
1da177e4
LT
4223 if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
4224 xdr_decode_hyper(p, &entry->ino);
4225 else if (bitmap[0] == FATTR4_WORD0_FILEID)
4226 xdr_decode_hyper(p, &entry->ino);
4227 p += len;
4228 }
4229
4230 entry->eof = !p[0] && p[1];
4231 return p;
4232}
4233
4234/*
4235 * We need to translate between nfs status return values and
4236 * the local errno values which may not be the same.
4237 */
4238static struct {
4239 int stat;
4240 int errno;
4241} nfs_errtbl[] = {
4242 { NFS4_OK, 0 },
4243 { NFS4ERR_PERM, EPERM },
4244 { NFS4ERR_NOENT, ENOENT },
4245 { NFS4ERR_IO, errno_NFSERR_IO },
4246 { NFS4ERR_NXIO, ENXIO },
4247 { NFS4ERR_ACCESS, EACCES },
4248 { NFS4ERR_EXIST, EEXIST },
4249 { NFS4ERR_XDEV, EXDEV },
4250 { NFS4ERR_NOTDIR, ENOTDIR },
4251 { NFS4ERR_ISDIR, EISDIR },
4252 { NFS4ERR_INVAL, EINVAL },
4253 { NFS4ERR_FBIG, EFBIG },
4254 { NFS4ERR_NOSPC, ENOSPC },
4255 { NFS4ERR_ROFS, EROFS },
4256 { NFS4ERR_MLINK, EMLINK },
4257 { NFS4ERR_NAMETOOLONG, ENAMETOOLONG },
4258 { NFS4ERR_NOTEMPTY, ENOTEMPTY },
4259 { NFS4ERR_DQUOT, EDQUOT },
4260 { NFS4ERR_STALE, ESTALE },
4261 { NFS4ERR_BADHANDLE, EBADHANDLE },
6ebf3656
MN
4262 { NFS4ERR_BADOWNER, EINVAL },
4263 { NFS4ERR_BADNAME, EINVAL },
1da177e4
LT
4264 { NFS4ERR_BAD_COOKIE, EBADCOOKIE },
4265 { NFS4ERR_NOTSUPP, ENOTSUPP },
4266 { NFS4ERR_TOOSMALL, ETOOSMALL },
4267 { NFS4ERR_SERVERFAULT, ESERVERFAULT },
4268 { NFS4ERR_BADTYPE, EBADTYPE },
4269 { NFS4ERR_LOCKED, EAGAIN },
4270 { NFS4ERR_RESOURCE, EREMOTEIO },
4271 { NFS4ERR_SYMLINK, ELOOP },
4272 { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP },
4273 { NFS4ERR_DEADLOCK, EDEADLK },
4274 { NFS4ERR_WRONGSEC, EPERM }, /* FIXME: this needs
4275 * to be handled by a
4276 * middle-layer.
4277 */
4278 { -1, EIO }
4279};
4280
4281/*
4282 * Convert an NFS error code to a local one.
4283 * This one is used jointly by NFSv2 and NFSv3.
4284 */
4285static int
4286nfs_stat_to_errno(int stat)
4287{
4288 int i;
4289 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
4290 if (nfs_errtbl[i].stat == stat)
4291 return nfs_errtbl[i].errno;
4292 }
4293 if (stat <= 10000 || stat > 10100) {
4294 /* The server is looney tunes. */
4295 return ESERVERFAULT;
4296 }
4297 /* If we cannot translate the error, the recovery routines should
4298 * handle it.
4299 * Note: remaining NFSv4 error codes have values > 10000, so should
4300 * not conflict with native Linux error codes.
4301 */
4302 return stat;
4303}
4304
4305#ifndef MAX
4306# define MAX(a, b) (((a) > (b))? (a) : (b))
4307#endif
4308
4309#define PROC(proc, argtype, restype) \
4310[NFSPROC4_CLNT_##proc] = { \
4311 .p_proc = NFSPROC4_COMPOUND, \
4312 .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
4313 .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
4314 .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \
4315 }
4316
4317struct rpc_procinfo nfs4_procedures[] = {
4318 PROC(READ, enc_read, dec_read),
4319 PROC(WRITE, enc_write, dec_write),
4320 PROC(COMMIT, enc_commit, dec_commit),
4321 PROC(OPEN, enc_open, dec_open),
4322 PROC(OPEN_CONFIRM, enc_open_confirm, dec_open_confirm),
4323 PROC(OPEN_NOATTR, enc_open_noattr, dec_open_noattr),
4324 PROC(OPEN_DOWNGRADE, enc_open_downgrade, dec_open_downgrade),
4325 PROC(CLOSE, enc_close, dec_close),
4326 PROC(SETATTR, enc_setattr, dec_setattr),
4327 PROC(FSINFO, enc_fsinfo, dec_fsinfo),
4328 PROC(RENEW, enc_renew, dec_renew),
4329 PROC(SETCLIENTID, enc_setclientid, dec_setclientid),
4330 PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm),
4331 PROC(LOCK, enc_lock, dec_lock),
4332 PROC(LOCKT, enc_lockt, dec_lockt),
4333 PROC(LOCKU, enc_locku, dec_locku),
4334 PROC(ACCESS, enc_access, dec_access),
4335 PROC(GETATTR, enc_getattr, dec_getattr),
4336 PROC(LOOKUP, enc_lookup, dec_lookup),
4337 PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
4338 PROC(REMOVE, enc_remove, dec_remove),
4339 PROC(RENAME, enc_rename, dec_rename),
4340 PROC(LINK, enc_link, dec_link),
4341 PROC(SYMLINK, enc_symlink, dec_symlink),
4342 PROC(CREATE, enc_create, dec_create),
4343 PROC(PATHCONF, enc_pathconf, dec_pathconf),
4344 PROC(STATFS, enc_statfs, dec_statfs),
4345 PROC(READLINK, enc_readlink, dec_readlink),
4346 PROC(READDIR, enc_readdir, dec_readdir),
4347 PROC(SERVER_CAPS, enc_server_caps, dec_server_caps),
4348 PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn),
029d105e 4349 PROC(GETACL, enc_getacl, dec_getacl),
23ec6965 4350 PROC(SETACL, enc_setacl, dec_setacl),
1da177e4
LT
4351};
4352
4353struct rpc_version nfs_version4 = {
4354 .number = 4,
4355 .nrprocs = sizeof(nfs4_procedures)/sizeof(nfs4_procedures[0]),
4356 .procs = nfs4_procedures
4357};
4358
4359/*
4360 * Local variables:
4361 * c-basic-offset: 8
4362 * End:
4363 */
This page took 0.240164 seconds and 5 git commands to generate.