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