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