NFS: Remove unused old NFSv3 decoder functions
[deliverable/linux.git] / fs / nfs / nfs3xdr.c
1 /*
2 * linux/fs/nfs/nfs3xdr.c
3 *
4 * XDR functions to encode/decode NFSv3 RPC arguments and results.
5 *
6 * Copyright (C) 1996, 1997 Olaf Kirch
7 */
8
9 #include <linux/param.h>
10 #include <linux/time.h>
11 #include <linux/mm.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/in.h>
15 #include <linux/pagemap.h>
16 #include <linux/proc_fs.h>
17 #include <linux/kdev_t.h>
18 #include <linux/sunrpc/clnt.h>
19 #include <linux/nfs.h>
20 #include <linux/nfs3.h>
21 #include <linux/nfs_fs.h>
22 #include <linux/nfsacl.h>
23 #include "internal.h"
24
25 #define NFSDBG_FACILITY NFSDBG_XDR
26
27 /* Mapping from NFS error code to "errno" error code. */
28 #define errno_NFSERR_IO EIO
29
30 /*
31 * Declare the space requirements for NFS arguments and replies as
32 * number of 32bit-words
33 */
34 #define NFS3_fhandle_sz (1+16)
35 #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */
36 #define NFS3_sattr_sz (15)
37 #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
38 #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
39 #define NFS3_fattr_sz (21)
40 #define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2)
41 #define NFS3_wcc_attr_sz (6)
42 #define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
43 #define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
44 #define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
45 #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
46
47 #define NFS3_getattrargs_sz (NFS3_fh_sz)
48 #define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
49 #define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz)
50 #define NFS3_accessargs_sz (NFS3_fh_sz+1)
51 #define NFS3_readlinkargs_sz (NFS3_fh_sz)
52 #define NFS3_readargs_sz (NFS3_fh_sz+3)
53 #define NFS3_writeargs_sz (NFS3_fh_sz+5)
54 #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
55 #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
56 #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
57 #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
58 #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
59 #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
60 #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
61 #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
62 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
63 #define NFS3_commitargs_sz (NFS3_fh_sz+3)
64
65 #define NFS3_getattrres_sz (1+NFS3_fattr_sz)
66 #define NFS3_setattrres_sz (1+NFS3_wcc_data_sz)
67 #define NFS3_removeres_sz (NFS3_setattrres_sz)
68 #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
69 #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
70 #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
71 #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
72 #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
73 #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
74 #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
75 #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
76 #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
77 #define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
78 #define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
79 #define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
80 #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
81
82 #define ACL3_getaclargs_sz (NFS3_fh_sz+1)
83 #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
84 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
85 #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
86 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
87 #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
88
89 /*
90 * Map file type to S_IFMT bits
91 */
92 static const umode_t nfs_type2fmt[] = {
93 [NF3BAD] = 0,
94 [NF3REG] = S_IFREG,
95 [NF3DIR] = S_IFDIR,
96 [NF3BLK] = S_IFBLK,
97 [NF3CHR] = S_IFCHR,
98 [NF3LNK] = S_IFLNK,
99 [NF3SOCK] = S_IFSOCK,
100 [NF3FIFO] = S_IFIFO,
101 };
102
103 /*
104 * While encoding arguments, set up the reply buffer in advance to
105 * receive reply data directly into the page cache.
106 */
107 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
108 unsigned int base, unsigned int len,
109 unsigned int bufsize)
110 {
111 struct rpc_auth *auth = req->rq_cred->cr_auth;
112 unsigned int replen;
113
114 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
115 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
116 }
117
118 /*
119 * Handle decode buffer overflows out-of-line.
120 */
121 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
122 {
123 dprintk("NFS: %s prematurely hit the end of our receive buffer. "
124 "Remaining buffer length is %tu words.\n",
125 func, xdr->end - xdr->p);
126 }
127
128
129 /*
130 * Common NFS XDR functions as inlines
131 */
132
133 /*
134 * Encode/decode time.
135 */
136 static inline __be32 *
137 xdr_decode_time3(__be32 *p, struct timespec *timep)
138 {
139 timep->tv_sec = ntohl(*p++);
140 timep->tv_nsec = ntohl(*p++);
141 return p;
142 }
143
144 static __be32 *
145 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
146 {
147 unsigned int type, major, minor;
148 umode_t fmode;
149
150 type = ntohl(*p++);
151 if (type > NF3FIFO)
152 type = NF3NON;
153 fmode = nfs_type2fmt[type];
154 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
155 fattr->nlink = ntohl(*p++);
156 fattr->uid = ntohl(*p++);
157 fattr->gid = ntohl(*p++);
158 p = xdr_decode_hyper(p, &fattr->size);
159 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
160
161 /* Turn remote device info into Linux-specific dev_t */
162 major = ntohl(*p++);
163 minor = ntohl(*p++);
164 fattr->rdev = MKDEV(major, minor);
165 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
166 fattr->rdev = 0;
167
168 p = xdr_decode_hyper(p, &fattr->fsid.major);
169 fattr->fsid.minor = 0;
170 p = xdr_decode_hyper(p, &fattr->fileid);
171 p = xdr_decode_time3(p, &fattr->atime);
172 p = xdr_decode_time3(p, &fattr->mtime);
173 p = xdr_decode_time3(p, &fattr->ctime);
174
175 /* Update the mode bits */
176 fattr->valid |= NFS_ATTR_FATTR_V3;
177 return p;
178 }
179
180 static inline __be32 *
181 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
182 {
183 p = xdr_decode_hyper(p, &fattr->pre_size);
184 p = xdr_decode_time3(p, &fattr->pre_mtime);
185 p = xdr_decode_time3(p, &fattr->pre_ctime);
186 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
187 | NFS_ATTR_FATTR_PREMTIME
188 | NFS_ATTR_FATTR_PRECTIME;
189 return p;
190 }
191
192 /*
193 * Encode/decode NFSv3 basic data types
194 *
195 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
196 * "NFS Version 3 Protocol Specification".
197 *
198 * Not all basic data types have their own encoding and decoding
199 * functions. For run-time efficiency, some data types are encoded
200 * or decoded inline.
201 */
202
203 static void encode_uint32(struct xdr_stream *xdr, u32 value)
204 {
205 __be32 *p = xdr_reserve_space(xdr, 4);
206 *p = cpu_to_be32(value);
207 }
208
209 static int decode_uint32(struct xdr_stream *xdr, u32 *value)
210 {
211 __be32 *p;
212
213 p = xdr_inline_decode(xdr, 4);
214 if (unlikely(p == NULL))
215 goto out_overflow;
216 *value = be32_to_cpup(p);
217 return 0;
218 out_overflow:
219 print_overflow_msg(__func__, xdr);
220 return -EIO;
221 }
222
223 static int decode_uint64(struct xdr_stream *xdr, u64 *value)
224 {
225 __be32 *p;
226
227 p = xdr_inline_decode(xdr, 8);
228 if (unlikely(p == NULL))
229 goto out_overflow;
230 xdr_decode_hyper(p, value);
231 return 0;
232 out_overflow:
233 print_overflow_msg(__func__, xdr);
234 return -EIO;
235 }
236
237 /*
238 * fileid3
239 *
240 * typedef uint64 fileid3;
241 */
242 static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
243 {
244 return decode_uint64(xdr, fileid);
245 }
246
247 /*
248 * filename3
249 *
250 * typedef string filename3<>;
251 */
252 static void encode_filename3(struct xdr_stream *xdr,
253 const char *name, u32 length)
254 {
255 __be32 *p;
256
257 BUG_ON(length > NFS3_MAXNAMLEN);
258 p = xdr_reserve_space(xdr, 4 + length);
259 xdr_encode_opaque(p, name, length);
260 }
261
262 static int decode_inline_filename3(struct xdr_stream *xdr,
263 const char **name, u32 *length)
264 {
265 __be32 *p;
266 u32 count;
267
268 p = xdr_inline_decode(xdr, 4);
269 if (unlikely(p == NULL))
270 goto out_overflow;
271 count = be32_to_cpup(p);
272 if (count > NFS3_MAXNAMLEN)
273 goto out_nametoolong;
274 p = xdr_inline_decode(xdr, count);
275 if (unlikely(p == NULL))
276 goto out_overflow;
277 *name = (const char *)p;
278 *length = count;
279 return 0;
280
281 out_nametoolong:
282 dprintk("NFS: returned filename too long: %u\n", count);
283 return -ENAMETOOLONG;
284 out_overflow:
285 print_overflow_msg(__func__, xdr);
286 return -EIO;
287 }
288
289 /*
290 * nfspath3
291 *
292 * typedef string nfspath3<>;
293 */
294 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
295 const u32 length)
296 {
297 BUG_ON(length > NFS3_MAXPATHLEN);
298 encode_uint32(xdr, length);
299 xdr_write_pages(xdr, pages, 0, length);
300 }
301
302 static int decode_nfspath3(struct xdr_stream *xdr)
303 {
304 u32 recvd, count;
305 size_t hdrlen;
306 __be32 *p;
307
308 p = xdr_inline_decode(xdr, 4);
309 if (unlikely(p == NULL))
310 goto out_overflow;
311 count = be32_to_cpup(p);
312 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
313 goto out_nametoolong;
314 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
315 recvd = xdr->buf->len - hdrlen;
316 if (unlikely(count > recvd))
317 goto out_cheating;
318
319 xdr_read_pages(xdr, count);
320 xdr_terminate_string(xdr->buf, count);
321 return 0;
322
323 out_nametoolong:
324 dprintk("NFS: returned pathname too long: %u\n", count);
325 return -ENAMETOOLONG;
326 out_cheating:
327 dprintk("NFS: server cheating in pathname result: "
328 "count %u > recvd %u\n", count, recvd);
329 return -EIO;
330 out_overflow:
331 print_overflow_msg(__func__, xdr);
332 return -EIO;
333 }
334
335 /*
336 * cookie3
337 *
338 * typedef uint64 cookie3
339 */
340 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
341 {
342 return xdr_encode_hyper(p, cookie);
343 }
344
345 static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
346 {
347 return decode_uint64(xdr, cookie);
348 }
349
350 /*
351 * cookieverf3
352 *
353 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
354 */
355 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
356 {
357 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
358 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
359 }
360
361 static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
362 {
363 __be32 *p;
364
365 p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
366 if (unlikely(p == NULL))
367 goto out_overflow;
368 memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
369 return 0;
370 out_overflow:
371 print_overflow_msg(__func__, xdr);
372 return -EIO;
373 }
374
375 /*
376 * createverf3
377 *
378 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
379 */
380 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
381 {
382 __be32 *p;
383
384 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
385 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
386 }
387
388 static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier)
389 {
390 __be32 *p;
391
392 p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
393 if (unlikely(p == NULL))
394 goto out_overflow;
395 memcpy(verifier, p, NFS3_WRITEVERFSIZE);
396 return 0;
397 out_overflow:
398 print_overflow_msg(__func__, xdr);
399 return -EIO;
400 }
401
402 /*
403 * size3
404 *
405 * typedef uint64 size3;
406 */
407 static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
408 {
409 return xdr_decode_hyper(p, size);
410 }
411
412 /*
413 * nfsstat3
414 *
415 * enum nfsstat3 {
416 * NFS3_OK = 0,
417 * ...
418 * }
419 */
420 #define NFS3_OK NFS_OK
421
422 static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
423 {
424 __be32 *p;
425
426 p = xdr_inline_decode(xdr, 4);
427 if (unlikely(p == NULL))
428 goto out_overflow;
429 *status = be32_to_cpup(p);
430 return 0;
431 out_overflow:
432 print_overflow_msg(__func__, xdr);
433 return -EIO;
434 }
435
436 /*
437 * ftype3
438 *
439 * enum ftype3 {
440 * NF3REG = 1,
441 * NF3DIR = 2,
442 * NF3BLK = 3,
443 * NF3CHR = 4,
444 * NF3LNK = 5,
445 * NF3SOCK = 6,
446 * NF3FIFO = 7
447 * };
448 */
449 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
450 {
451 BUG_ON(type > NF3FIFO);
452 encode_uint32(xdr, type);
453 }
454
455 /*
456 * specdata3
457 *
458 * struct specdata3 {
459 * uint32 specdata1;
460 * uint32 specdata2;
461 * };
462 */
463 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
464 {
465 __be32 *p;
466
467 p = xdr_reserve_space(xdr, 8);
468 *p++ = cpu_to_be32(MAJOR(rdev));
469 *p = cpu_to_be32(MINOR(rdev));
470 }
471
472 /*
473 * nfs_fh3
474 *
475 * struct nfs_fh3 {
476 * opaque data<NFS3_FHSIZE>;
477 * };
478 */
479 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
480 {
481 __be32 *p;
482
483 BUG_ON(fh->size > NFS3_FHSIZE);
484 p = xdr_reserve_space(xdr, 4 + fh->size);
485 xdr_encode_opaque(p, fh->data, fh->size);
486 }
487
488 static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
489 {
490 u32 length;
491 __be32 *p;
492
493 p = xdr_inline_decode(xdr, 4);
494 if (unlikely(p == NULL))
495 goto out_overflow;
496 length = be32_to_cpup(p++);
497 if (unlikely(length > NFS3_FHSIZE))
498 goto out_toobig;
499 p = xdr_inline_decode(xdr, length);
500 if (unlikely(p == NULL))
501 goto out_overflow;
502 fh->size = length;
503 memcpy(fh->data, p, length);
504 return 0;
505 out_toobig:
506 dprintk("NFS: file handle size (%u) too big\n", length);
507 return -E2BIG;
508 out_overflow:
509 print_overflow_msg(__func__, xdr);
510 return -EIO;
511 }
512
513 static void zero_nfs_fh3(struct nfs_fh *fh)
514 {
515 memset(fh, 0, sizeof(*fh));
516 }
517
518 /*
519 * nfstime3
520 *
521 * struct nfstime3 {
522 * uint32 seconds;
523 * uint32 nseconds;
524 * };
525 */
526 static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
527 {
528 *p++ = cpu_to_be32(timep->tv_sec);
529 *p++ = cpu_to_be32(timep->tv_nsec);
530 return p;
531 }
532
533 /*
534 * sattr3
535 *
536 * enum time_how {
537 * DONT_CHANGE = 0,
538 * SET_TO_SERVER_TIME = 1,
539 * SET_TO_CLIENT_TIME = 2
540 * };
541 *
542 * union set_mode3 switch (bool set_it) {
543 * case TRUE:
544 * mode3 mode;
545 * default:
546 * void;
547 * };
548 *
549 * union set_uid3 switch (bool set_it) {
550 * case TRUE:
551 * uid3 uid;
552 * default:
553 * void;
554 * };
555 *
556 * union set_gid3 switch (bool set_it) {
557 * case TRUE:
558 * gid3 gid;
559 * default:
560 * void;
561 * };
562 *
563 * union set_size3 switch (bool set_it) {
564 * case TRUE:
565 * size3 size;
566 * default:
567 * void;
568 * };
569 *
570 * union set_atime switch (time_how set_it) {
571 * case SET_TO_CLIENT_TIME:
572 * nfstime3 atime;
573 * default:
574 * void;
575 * };
576 *
577 * union set_mtime switch (time_how set_it) {
578 * case SET_TO_CLIENT_TIME:
579 * nfstime3 mtime;
580 * default:
581 * void;
582 * };
583 *
584 * struct sattr3 {
585 * set_mode3 mode;
586 * set_uid3 uid;
587 * set_gid3 gid;
588 * set_size3 size;
589 * set_atime atime;
590 * set_mtime mtime;
591 * };
592 */
593 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
594 {
595 u32 nbytes;
596 __be32 *p;
597
598 /*
599 * In order to make only a single xdr_reserve_space() call,
600 * pre-compute the total number of bytes to be reserved.
601 * Six boolean values, one for each set_foo field, are always
602 * present in the encoded result, so start there.
603 */
604 nbytes = 6 * 4;
605 if (attr->ia_valid & ATTR_MODE)
606 nbytes += 4;
607 if (attr->ia_valid & ATTR_UID)
608 nbytes += 4;
609 if (attr->ia_valid & ATTR_GID)
610 nbytes += 4;
611 if (attr->ia_valid & ATTR_SIZE)
612 nbytes += 8;
613 if (attr->ia_valid & ATTR_ATIME_SET)
614 nbytes += 8;
615 if (attr->ia_valid & ATTR_MTIME_SET)
616 nbytes += 8;
617 p = xdr_reserve_space(xdr, nbytes);
618
619 if (attr->ia_valid & ATTR_MODE) {
620 *p++ = xdr_one;
621 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
622 } else
623 *p++ = xdr_zero;
624
625 if (attr->ia_valid & ATTR_UID) {
626 *p++ = xdr_one;
627 *p++ = cpu_to_be32(attr->ia_uid);
628 } else
629 *p++ = xdr_zero;
630
631 if (attr->ia_valid & ATTR_GID) {
632 *p++ = xdr_one;
633 *p++ = cpu_to_be32(attr->ia_gid);
634 } else
635 *p++ = xdr_zero;
636
637 if (attr->ia_valid & ATTR_SIZE) {
638 *p++ = xdr_one;
639 p = xdr_encode_hyper(p, (u64)attr->ia_size);
640 } else
641 *p++ = xdr_zero;
642
643 if (attr->ia_valid & ATTR_ATIME_SET) {
644 *p++ = xdr_two;
645 p = xdr_encode_nfstime3(p, &attr->ia_atime);
646 } else if (attr->ia_valid & ATTR_ATIME) {
647 *p++ = xdr_one;
648 } else
649 *p++ = xdr_zero;
650
651 if (attr->ia_valid & ATTR_MTIME_SET) {
652 *p++ = xdr_two;
653 xdr_encode_nfstime3(p, &attr->ia_mtime);
654 } else if (attr->ia_valid & ATTR_MTIME) {
655 *p = xdr_one;
656 } else
657 *p = xdr_zero;
658 }
659
660 /*
661 * fattr3
662 *
663 * struct fattr3 {
664 * ftype3 type;
665 * mode3 mode;
666 * uint32 nlink;
667 * uid3 uid;
668 * gid3 gid;
669 * size3 size;
670 * size3 used;
671 * specdata3 rdev;
672 * uint64 fsid;
673 * fileid3 fileid;
674 * nfstime3 atime;
675 * nfstime3 mtime;
676 * nfstime3 ctime;
677 * };
678 */
679 static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
680 {
681 __be32 *p;
682
683 p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
684 if (unlikely(p == NULL))
685 goto out_overflow;
686 xdr_decode_fattr(p, fattr);
687 return 0;
688 out_overflow:
689 print_overflow_msg(__func__, xdr);
690 return -EIO;
691 }
692
693 /*
694 * post_op_attr
695 *
696 * union post_op_attr switch (bool attributes_follow) {
697 * case TRUE:
698 * fattr3 attributes;
699 * case FALSE:
700 * void;
701 * };
702 */
703 static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
704 {
705 __be32 *p;
706
707 p = xdr_inline_decode(xdr, 4);
708 if (unlikely(p == NULL))
709 goto out_overflow;
710 if (*p != xdr_zero)
711 return decode_fattr3(xdr, fattr);
712 return 0;
713 out_overflow:
714 print_overflow_msg(__func__, xdr);
715 return -EIO;
716 }
717
718 /*
719 * wcc_attr
720 * struct wcc_attr {
721 * size3 size;
722 * nfstime3 mtime;
723 * nfstime3 ctime;
724 * };
725 */
726 static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
727 {
728 __be32 *p;
729
730 p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
731 if (unlikely(p == NULL))
732 goto out_overflow;
733 xdr_decode_wcc_attr(p, fattr);
734 return 0;
735 out_overflow:
736 print_overflow_msg(__func__, xdr);
737 return -EIO;
738 }
739
740 /*
741 * pre_op_attr
742 * union pre_op_attr switch (bool attributes_follow) {
743 * case TRUE:
744 * wcc_attr attributes;
745 * case FALSE:
746 * void;
747 * };
748 *
749 * wcc_data
750 *
751 * struct wcc_data {
752 * pre_op_attr before;
753 * post_op_attr after;
754 * };
755 */
756 static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
757 {
758 __be32 *p;
759
760 p = xdr_inline_decode(xdr, 4);
761 if (unlikely(p == NULL))
762 goto out_overflow;
763 if (*p != xdr_zero)
764 return decode_wcc_attr(xdr, fattr);
765 return 0;
766 out_overflow:
767 print_overflow_msg(__func__, xdr);
768 return -EIO;
769 }
770
771 static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
772 {
773 int error;
774
775 error = decode_pre_op_attr(xdr, fattr);
776 if (unlikely(error))
777 goto out;
778 error = decode_post_op_attr(xdr, fattr);
779 out:
780 return error;
781 }
782
783 /*
784 * post_op_fh3
785 *
786 * union post_op_fh3 switch (bool handle_follows) {
787 * case TRUE:
788 * nfs_fh3 handle;
789 * case FALSE:
790 * void;
791 * };
792 */
793 static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
794 {
795 __be32 *p = xdr_inline_decode(xdr, 4);
796 if (unlikely(p == NULL))
797 goto out_overflow;
798 if (*p != xdr_zero)
799 return decode_nfs_fh3(xdr, fh);
800 zero_nfs_fh3(fh);
801 return 0;
802 out_overflow:
803 print_overflow_msg(__func__, xdr);
804 return -EIO;
805 }
806
807 /*
808 * diropargs3
809 *
810 * struct diropargs3 {
811 * nfs_fh3 dir;
812 * filename3 name;
813 * };
814 */
815 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
816 const char *name, u32 length)
817 {
818 encode_nfs_fh3(xdr, fh);
819 encode_filename3(xdr, name, length);
820 }
821
822
823 /*
824 * NFSv3 XDR encode functions
825 *
826 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
827 * "NFS Version 3 Protocol Specification".
828 */
829
830 /*
831 * 3.3.1 GETATTR3args
832 *
833 * struct GETATTR3args {
834 * nfs_fh3 object;
835 * };
836 */
837 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
838 const struct nfs_fh *fh)
839 {
840 struct xdr_stream xdr;
841
842 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
843 encode_nfs_fh3(&xdr, fh);
844 return 0;
845 }
846
847 /*
848 * 3.3.2 SETATTR3args
849 *
850 * union sattrguard3 switch (bool check) {
851 * case TRUE:
852 * nfstime3 obj_ctime;
853 * case FALSE:
854 * void;
855 * };
856 *
857 * struct SETATTR3args {
858 * nfs_fh3 object;
859 * sattr3 new_attributes;
860 * sattrguard3 guard;
861 * };
862 */
863 static void encode_sattrguard3(struct xdr_stream *xdr,
864 const struct nfs3_sattrargs *args)
865 {
866 __be32 *p;
867
868 if (args->guard) {
869 p = xdr_reserve_space(xdr, 4 + 8);
870 *p++ = xdr_one;
871 xdr_encode_nfstime3(p, &args->guardtime);
872 } else {
873 p = xdr_reserve_space(xdr, 4);
874 *p = xdr_zero;
875 }
876 }
877
878 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
879 const struct nfs3_sattrargs *args)
880 {
881 struct xdr_stream xdr;
882
883 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
884 encode_nfs_fh3(&xdr, args->fh);
885 encode_sattr3(&xdr, args->sattr);
886 encode_sattrguard3(&xdr, args);
887 return 0;
888 }
889
890 /*
891 * 3.3.3 LOOKUP3args
892 *
893 * struct LOOKUP3args {
894 * diropargs3 what;
895 * };
896 */
897 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
898 const struct nfs3_diropargs *args)
899 {
900 struct xdr_stream xdr;
901
902 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
903 encode_diropargs3(&xdr, args->fh, args->name, args->len);
904 return 0;
905 }
906
907 /*
908 * 3.3.4 ACCESS3args
909 *
910 * struct ACCESS3args {
911 * nfs_fh3 object;
912 * uint32 access;
913 * };
914 */
915 static void encode_access3args(struct xdr_stream *xdr,
916 const struct nfs3_accessargs *args)
917 {
918 encode_nfs_fh3(xdr, args->fh);
919 encode_uint32(xdr, args->access);
920 }
921
922 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
923 const struct nfs3_accessargs *args)
924 {
925 struct xdr_stream xdr;
926
927 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
928 encode_access3args(&xdr, args);
929 return 0;
930 }
931
932 /*
933 * 3.3.5 READLINK3args
934 *
935 * struct READLINK3args {
936 * nfs_fh3 symlink;
937 * };
938 */
939 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
940 const struct nfs3_readlinkargs *args)
941 {
942 struct xdr_stream xdr;
943
944 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
945 encode_nfs_fh3(&xdr, args->fh);
946 prepare_reply_buffer(req, args->pages, args->pgbase,
947 args->pglen, NFS3_readlinkres_sz);
948 return 0;
949 }
950
951 /*
952 * 3.3.6 READ3args
953 *
954 * struct READ3args {
955 * nfs_fh3 file;
956 * offset3 offset;
957 * count3 count;
958 * };
959 */
960 static void encode_read3args(struct xdr_stream *xdr,
961 const struct nfs_readargs *args)
962 {
963 __be32 *p;
964
965 encode_nfs_fh3(xdr, args->fh);
966
967 p = xdr_reserve_space(xdr, 8 + 4);
968 p = xdr_encode_hyper(p, args->offset);
969 *p = cpu_to_be32(args->count);
970 }
971
972 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
973 const struct nfs_readargs *args)
974 {
975 struct xdr_stream xdr;
976
977 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
978 encode_read3args(&xdr, args);
979 prepare_reply_buffer(req, args->pages, args->pgbase,
980 args->count, NFS3_readres_sz);
981 req->rq_rcv_buf.flags |= XDRBUF_READ;
982 return 0;
983 }
984
985 /*
986 * 3.3.7 WRITE3args
987 *
988 * enum stable_how {
989 * UNSTABLE = 0,
990 * DATA_SYNC = 1,
991 * FILE_SYNC = 2
992 * };
993 *
994 * struct WRITE3args {
995 * nfs_fh3 file;
996 * offset3 offset;
997 * count3 count;
998 * stable_how stable;
999 * opaque data<>;
1000 * };
1001 */
1002 static void encode_write3args(struct xdr_stream *xdr,
1003 const struct nfs_writeargs *args)
1004 {
1005 __be32 *p;
1006
1007 encode_nfs_fh3(xdr, args->fh);
1008
1009 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
1010 p = xdr_encode_hyper(p, args->offset);
1011 *p++ = cpu_to_be32(args->count);
1012
1013 BUG_ON(args->stable > NFS_FILE_SYNC);
1014 *p++ = cpu_to_be32(args->stable);
1015
1016 *p = cpu_to_be32(args->count);
1017 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1018 }
1019
1020 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
1021 const struct nfs_writeargs *args)
1022 {
1023 struct xdr_stream xdr;
1024
1025 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1026 encode_write3args(&xdr, args);
1027 xdr.buf->flags |= XDRBUF_WRITE;
1028 return 0;
1029 }
1030
1031 /*
1032 * 3.3.8 CREATE3args
1033 *
1034 * enum createmode3 {
1035 * UNCHECKED = 0,
1036 * GUARDED = 1,
1037 * EXCLUSIVE = 2
1038 * };
1039 *
1040 * union createhow3 switch (createmode3 mode) {
1041 * case UNCHECKED:
1042 * case GUARDED:
1043 * sattr3 obj_attributes;
1044 * case EXCLUSIVE:
1045 * createverf3 verf;
1046 * };
1047 *
1048 * struct CREATE3args {
1049 * diropargs3 where;
1050 * createhow3 how;
1051 * };
1052 */
1053 static void encode_createhow3(struct xdr_stream *xdr,
1054 const struct nfs3_createargs *args)
1055 {
1056 encode_uint32(xdr, args->createmode);
1057 switch (args->createmode) {
1058 case NFS3_CREATE_UNCHECKED:
1059 case NFS3_CREATE_GUARDED:
1060 encode_sattr3(xdr, args->sattr);
1061 break;
1062 case NFS3_CREATE_EXCLUSIVE:
1063 encode_createverf3(xdr, args->verifier);
1064 break;
1065 default:
1066 BUG();
1067 }
1068 }
1069
1070 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
1071 const struct nfs3_createargs *args)
1072 {
1073 struct xdr_stream xdr;
1074
1075 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1076 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1077 encode_createhow3(&xdr, args);
1078 return 0;
1079 }
1080
1081 /*
1082 * 3.3.9 MKDIR3args
1083 *
1084 * struct MKDIR3args {
1085 * diropargs3 where;
1086 * sattr3 attributes;
1087 * };
1088 */
1089 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
1090 const struct nfs3_mkdirargs *args)
1091 {
1092 struct xdr_stream xdr;
1093
1094 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1095 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1096 encode_sattr3(&xdr, args->sattr);
1097 return 0;
1098 }
1099
1100 /*
1101 * 3.3.10 SYMLINK3args
1102 *
1103 * struct symlinkdata3 {
1104 * sattr3 symlink_attributes;
1105 * nfspath3 symlink_data;
1106 * };
1107 *
1108 * struct SYMLINK3args {
1109 * diropargs3 where;
1110 * symlinkdata3 symlink;
1111 * };
1112 */
1113 static void encode_symlinkdata3(struct xdr_stream *xdr,
1114 const struct nfs3_symlinkargs *args)
1115 {
1116 encode_sattr3(xdr, args->sattr);
1117 encode_nfspath3(xdr, args->pages, args->pathlen);
1118 }
1119
1120 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1121 const struct nfs3_symlinkargs *args)
1122 {
1123 struct xdr_stream xdr;
1124
1125 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1126 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1127 encode_symlinkdata3(&xdr, args);
1128 return 0;
1129 }
1130
1131 /*
1132 * 3.3.11 MKNOD3args
1133 *
1134 * struct devicedata3 {
1135 * sattr3 dev_attributes;
1136 * specdata3 spec;
1137 * };
1138 *
1139 * union mknoddata3 switch (ftype3 type) {
1140 * case NF3CHR:
1141 * case NF3BLK:
1142 * devicedata3 device;
1143 * case NF3SOCK:
1144 * case NF3FIFO:
1145 * sattr3 pipe_attributes;
1146 * default:
1147 * void;
1148 * };
1149 *
1150 * struct MKNOD3args {
1151 * diropargs3 where;
1152 * mknoddata3 what;
1153 * };
1154 */
1155 static void encode_devicedata3(struct xdr_stream *xdr,
1156 const struct nfs3_mknodargs *args)
1157 {
1158 encode_sattr3(xdr, args->sattr);
1159 encode_specdata3(xdr, args->rdev);
1160 }
1161
1162 static void encode_mknoddata3(struct xdr_stream *xdr,
1163 const struct nfs3_mknodargs *args)
1164 {
1165 encode_ftype3(xdr, args->type);
1166 switch (args->type) {
1167 case NF3CHR:
1168 case NF3BLK:
1169 encode_devicedata3(xdr, args);
1170 break;
1171 case NF3SOCK:
1172 case NF3FIFO:
1173 encode_sattr3(xdr, args->sattr);
1174 break;
1175 case NF3REG:
1176 case NF3DIR:
1177 break;
1178 default:
1179 BUG();
1180 }
1181 }
1182
1183 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1184 const struct nfs3_mknodargs *args)
1185 {
1186 struct xdr_stream xdr;
1187
1188 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1189 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1190 encode_mknoddata3(&xdr, args);
1191 return 0;
1192 }
1193
1194 /*
1195 * 3.3.12 REMOVE3args
1196 *
1197 * struct REMOVE3args {
1198 * diropargs3 object;
1199 * };
1200 */
1201 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1202 const struct nfs_removeargs *args)
1203 {
1204 struct xdr_stream xdr;
1205
1206 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1207 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1208 return 0;
1209 }
1210
1211 /*
1212 * 3.3.14 RENAME3args
1213 *
1214 * struct RENAME3args {
1215 * diropargs3 from;
1216 * diropargs3 to;
1217 * };
1218 */
1219 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1220 const struct nfs_renameargs *args)
1221 {
1222 const struct qstr *old = args->old_name;
1223 const struct qstr *new = args->new_name;
1224 struct xdr_stream xdr;
1225
1226 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1227 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1228 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1229 return 0;
1230 }
1231
1232 /*
1233 * 3.3.15 LINK3args
1234 *
1235 * struct LINK3args {
1236 * nfs_fh3 file;
1237 * diropargs3 link;
1238 * };
1239 */
1240 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1241 const struct nfs3_linkargs *args)
1242 {
1243 struct xdr_stream xdr;
1244
1245 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1246 encode_nfs_fh3(&xdr, args->fromfh);
1247 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1248 return 0;
1249 }
1250
1251 /*
1252 * 3.3.16 READDIR3args
1253 *
1254 * struct READDIR3args {
1255 * nfs_fh3 dir;
1256 * cookie3 cookie;
1257 * cookieverf3 cookieverf;
1258 * count3 count;
1259 * };
1260 */
1261 static void encode_readdir3args(struct xdr_stream *xdr,
1262 const struct nfs3_readdirargs *args)
1263 {
1264 __be32 *p;
1265
1266 encode_nfs_fh3(xdr, args->fh);
1267
1268 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1269 p = xdr_encode_cookie3(p, args->cookie);
1270 p = xdr_encode_cookieverf3(p, args->verf);
1271 *p = cpu_to_be32(args->count);
1272 }
1273
1274 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1275 const struct nfs3_readdirargs *args)
1276 {
1277 struct xdr_stream xdr;
1278
1279 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1280 encode_readdir3args(&xdr, args);
1281 prepare_reply_buffer(req, args->pages, 0,
1282 args->count, NFS3_readdirres_sz);
1283 return 0;
1284 }
1285
1286 /*
1287 * 3.3.17 READDIRPLUS3args
1288 *
1289 * struct READDIRPLUS3args {
1290 * nfs_fh3 dir;
1291 * cookie3 cookie;
1292 * cookieverf3 cookieverf;
1293 * count3 dircount;
1294 * count3 maxcount;
1295 * };
1296 */
1297 static void encode_readdirplus3args(struct xdr_stream *xdr,
1298 const struct nfs3_readdirargs *args)
1299 {
1300 __be32 *p;
1301
1302 encode_nfs_fh3(xdr, args->fh);
1303
1304 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1305 p = xdr_encode_cookie3(p, args->cookie);
1306 p = xdr_encode_cookieverf3(p, args->verf);
1307
1308 /*
1309 * readdirplus: need dircount + buffer size.
1310 * We just make sure we make dircount big enough
1311 */
1312 *p++ = cpu_to_be32(args->count >> 3);
1313
1314 *p = cpu_to_be32(args->count);
1315 }
1316
1317 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1318 const struct nfs3_readdirargs *args)
1319 {
1320 struct xdr_stream xdr;
1321
1322 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1323 encode_readdirplus3args(&xdr, args);
1324 prepare_reply_buffer(req, args->pages, 0,
1325 args->count, NFS3_readdirres_sz);
1326 return 0;
1327 }
1328
1329 /*
1330 * 3.3.21 COMMIT3args
1331 *
1332 * struct COMMIT3args {
1333 * nfs_fh3 file;
1334 * offset3 offset;
1335 * count3 count;
1336 * };
1337 */
1338 static void encode_commit3args(struct xdr_stream *xdr,
1339 const struct nfs_writeargs *args)
1340 {
1341 __be32 *p;
1342
1343 encode_nfs_fh3(xdr, args->fh);
1344
1345 p = xdr_reserve_space(xdr, 8 + 4);
1346 p = xdr_encode_hyper(p, args->offset);
1347 *p = cpu_to_be32(args->count);
1348 }
1349
1350 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1351 const struct nfs_writeargs *args)
1352 {
1353 struct xdr_stream xdr;
1354
1355 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1356 encode_commit3args(&xdr, args);
1357 return 0;
1358 }
1359
1360 #ifdef CONFIG_NFS_V3_ACL
1361
1362 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1363 const struct nfs3_getaclargs *args)
1364 {
1365 struct xdr_stream xdr;
1366
1367 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1368 encode_nfs_fh3(&xdr, args->fh);
1369 encode_uint32(&xdr, args->mask);
1370 if (args->mask & (NFS_ACL | NFS_DFACL))
1371 prepare_reply_buffer(req, args->pages, 0,
1372 NFSACL_MAXPAGES << PAGE_SHIFT,
1373 ACL3_getaclres_sz);
1374 return 0;
1375 }
1376
1377 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1378 const struct nfs3_setaclargs *args)
1379 {
1380 struct xdr_stream xdr;
1381 unsigned int base;
1382 int error;
1383
1384 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1385 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1386 encode_uint32(&xdr, args->mask);
1387 if (args->npages != 0)
1388 xdr_write_pages(&xdr, args->pages, 0, args->len);
1389
1390 base = req->rq_slen;
1391 error = nfsacl_encode(xdr.buf, base, args->inode,
1392 (args->mask & NFS_ACL) ?
1393 args->acl_access : NULL, 1, 0);
1394 BUG_ON(error < 0);
1395 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1396 (args->mask & NFS_DFACL) ?
1397 args->acl_default : NULL, 1,
1398 NFS_ACL_DEFAULT);
1399 BUG_ON(error < 0);
1400 return 0;
1401 }
1402
1403 #endif /* CONFIG_NFS_V3_ACL */
1404
1405 /*
1406 * NFSv3 XDR decode functions
1407 *
1408 * NFSv3 result types are defined in section 3.3 of RFC 1813:
1409 * "NFS Version 3 Protocol Specification".
1410 */
1411
1412 /*
1413 * 3.3.1 GETATTR3res
1414 *
1415 * struct GETATTR3resok {
1416 * fattr3 obj_attributes;
1417 * };
1418 *
1419 * union GETATTR3res switch (nfsstat3 status) {
1420 * case NFS3_OK:
1421 * GETATTR3resok resok;
1422 * default:
1423 * void;
1424 * };
1425 */
1426 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p,
1427 struct nfs_fattr *result)
1428 {
1429 struct xdr_stream xdr;
1430 enum nfs_stat status;
1431 int error;
1432
1433 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1434 error = decode_nfsstat3(&xdr, &status);
1435 if (unlikely(error))
1436 goto out;
1437 if (status != NFS3_OK)
1438 goto out_default;
1439 error = decode_fattr3(&xdr, result);
1440 out:
1441 return error;
1442 out_default:
1443 return nfs_stat_to_errno(status);
1444 }
1445
1446 /*
1447 * 3.3.2 SETATTR3res
1448 *
1449 * struct SETATTR3resok {
1450 * wcc_data obj_wcc;
1451 * };
1452 *
1453 * struct SETATTR3resfail {
1454 * wcc_data obj_wcc;
1455 * };
1456 *
1457 * union SETATTR3res switch (nfsstat3 status) {
1458 * case NFS3_OK:
1459 * SETATTR3resok resok;
1460 * default:
1461 * SETATTR3resfail resfail;
1462 * };
1463 */
1464 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p,
1465 struct nfs_fattr *result)
1466 {
1467 struct xdr_stream xdr;
1468 enum nfs_stat status;
1469 int error;
1470
1471 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1472 error = decode_nfsstat3(&xdr, &status);
1473 if (unlikely(error))
1474 goto out;
1475 error = decode_wcc_data(&xdr, result);
1476 if (unlikely(error))
1477 goto out;
1478 if (status != NFS3_OK)
1479 goto out_status;
1480 out:
1481 return error;
1482 out_status:
1483 return nfs_stat_to_errno(status);
1484 }
1485
1486 /*
1487 * 3.3.3 LOOKUP3res
1488 *
1489 * struct LOOKUP3resok {
1490 * nfs_fh3 object;
1491 * post_op_attr obj_attributes;
1492 * post_op_attr dir_attributes;
1493 * };
1494 *
1495 * struct LOOKUP3resfail {
1496 * post_op_attr dir_attributes;
1497 * };
1498 *
1499 * union LOOKUP3res switch (nfsstat3 status) {
1500 * case NFS3_OK:
1501 * LOOKUP3resok resok;
1502 * default:
1503 * LOOKUP3resfail resfail;
1504 * };
1505 */
1506 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p,
1507 struct nfs3_diropres *result)
1508 {
1509 struct xdr_stream xdr;
1510 enum nfs_stat status;
1511 int error;
1512
1513 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1514 error = decode_nfsstat3(&xdr, &status);
1515 if (unlikely(error))
1516 goto out;
1517 if (status != NFS3_OK)
1518 goto out_default;
1519 error = decode_nfs_fh3(&xdr, result->fh);
1520 if (unlikely(error))
1521 goto out;
1522 error = decode_post_op_attr(&xdr, result->fattr);
1523 if (unlikely(error))
1524 goto out;
1525 error = decode_post_op_attr(&xdr, result->dir_attr);
1526 out:
1527 return error;
1528 out_default:
1529 error = decode_post_op_attr(&xdr, result->dir_attr);
1530 if (unlikely(error))
1531 goto out;
1532 return nfs_stat_to_errno(status);
1533 }
1534
1535 /*
1536 * 3.3.4 ACCESS3res
1537 *
1538 * struct ACCESS3resok {
1539 * post_op_attr obj_attributes;
1540 * uint32 access;
1541 * };
1542 *
1543 * struct ACCESS3resfail {
1544 * post_op_attr obj_attributes;
1545 * };
1546 *
1547 * union ACCESS3res switch (nfsstat3 status) {
1548 * case NFS3_OK:
1549 * ACCESS3resok resok;
1550 * default:
1551 * ACCESS3resfail resfail;
1552 * };
1553 */
1554 static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p,
1555 struct nfs3_accessres *result)
1556 {
1557 struct xdr_stream xdr;
1558 enum nfs_stat status;
1559 int error;
1560
1561 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1562 error = decode_nfsstat3(&xdr, &status);
1563 if (unlikely(error))
1564 goto out;
1565 error = decode_post_op_attr(&xdr, result->fattr);
1566 if (unlikely(error))
1567 goto out;
1568 if (status != NFS3_OK)
1569 goto out_default;
1570 error = decode_uint32(&xdr, &result->access);
1571 out:
1572 return error;
1573 out_default:
1574 return nfs_stat_to_errno(status);
1575 }
1576
1577 /*
1578 * 3.3.5 READLINK3res
1579 *
1580 * struct READLINK3resok {
1581 * post_op_attr symlink_attributes;
1582 * nfspath3 data;
1583 * };
1584 *
1585 * struct READLINK3resfail {
1586 * post_op_attr symlink_attributes;
1587 * };
1588 *
1589 * union READLINK3res switch (nfsstat3 status) {
1590 * case NFS3_OK:
1591 * READLINK3resok resok;
1592 * default:
1593 * READLINK3resfail resfail;
1594 * };
1595 */
1596 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p,
1597 struct nfs_fattr *result)
1598 {
1599 struct xdr_stream xdr;
1600 enum nfs_stat status;
1601 int error;
1602
1603 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1604 error = decode_nfsstat3(&xdr, &status);
1605 if (unlikely(error))
1606 goto out;
1607 error = decode_post_op_attr(&xdr, result);
1608 if (unlikely(error))
1609 goto out;
1610 if (status != NFS3_OK)
1611 goto out_default;
1612 error = decode_nfspath3(&xdr);
1613 out:
1614 return error;
1615 out_default:
1616 return nfs_stat_to_errno(status);
1617 }
1618
1619 /*
1620 * 3.3.6 READ3res
1621 *
1622 * struct READ3resok {
1623 * post_op_attr file_attributes;
1624 * count3 count;
1625 * bool eof;
1626 * opaque data<>;
1627 * };
1628 *
1629 * struct READ3resfail {
1630 * post_op_attr file_attributes;
1631 * };
1632 *
1633 * union READ3res switch (nfsstat3 status) {
1634 * case NFS3_OK:
1635 * READ3resok resok;
1636 * default:
1637 * READ3resfail resfail;
1638 * };
1639 */
1640 static int decode_read3resok(struct xdr_stream *xdr,
1641 struct nfs_readres *result)
1642 {
1643 u32 eof, count, ocount, recvd;
1644 size_t hdrlen;
1645 __be32 *p;
1646
1647 p = xdr_inline_decode(xdr, 4 + 4 + 4);
1648 if (unlikely(p == NULL))
1649 goto out_overflow;
1650 count = be32_to_cpup(p++);
1651 eof = be32_to_cpup(p++);
1652 ocount = be32_to_cpup(p++);
1653 if (unlikely(ocount != count))
1654 goto out_mismatch;
1655 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
1656 recvd = xdr->buf->len - hdrlen;
1657 if (unlikely(count > recvd))
1658 goto out_cheating;
1659
1660 out:
1661 xdr_read_pages(xdr, count);
1662 result->eof = eof;
1663 result->count = count;
1664 return count;
1665 out_mismatch:
1666 dprintk("NFS: READ count doesn't match length of opaque: "
1667 "count %u != ocount %u\n", count, ocount);
1668 return -EIO;
1669 out_cheating:
1670 dprintk("NFS: server cheating in read result: "
1671 "count %u > recvd %u\n", count, recvd);
1672 count = recvd;
1673 eof = 0;
1674 goto out;
1675 out_overflow:
1676 print_overflow_msg(__func__, xdr);
1677 return -EIO;
1678 }
1679
1680 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p,
1681 struct nfs_readres *result)
1682 {
1683 struct xdr_stream xdr;
1684 enum nfs_stat status;
1685 int error;
1686
1687 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1688 error = decode_nfsstat3(&xdr, &status);
1689 if (unlikely(error))
1690 goto out;
1691 error = decode_post_op_attr(&xdr, result->fattr);
1692 if (unlikely(error))
1693 goto out;
1694 if (status != NFS3_OK)
1695 goto out_status;
1696 error = decode_read3resok(&xdr, result);
1697 out:
1698 return error;
1699 out_status:
1700 return nfs_stat_to_errno(status);
1701 }
1702
1703 /*
1704 * 3.3.7 WRITE3res
1705 *
1706 * enum stable_how {
1707 * UNSTABLE = 0,
1708 * DATA_SYNC = 1,
1709 * FILE_SYNC = 2
1710 * };
1711 *
1712 * struct WRITE3resok {
1713 * wcc_data file_wcc;
1714 * count3 count;
1715 * stable_how committed;
1716 * writeverf3 verf;
1717 * };
1718 *
1719 * struct WRITE3resfail {
1720 * wcc_data file_wcc;
1721 * };
1722 *
1723 * union WRITE3res switch (nfsstat3 status) {
1724 * case NFS3_OK:
1725 * WRITE3resok resok;
1726 * default:
1727 * WRITE3resfail resfail;
1728 * };
1729 */
1730 static int decode_write3resok(struct xdr_stream *xdr,
1731 struct nfs_writeres *result)
1732 {
1733 __be32 *p;
1734
1735 p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE);
1736 if (unlikely(p == NULL))
1737 goto out_overflow;
1738 result->count = be32_to_cpup(p++);
1739 result->verf->committed = be32_to_cpup(p++);
1740 if (unlikely(result->verf->committed > NFS_FILE_SYNC))
1741 goto out_badvalue;
1742 memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE);
1743 return result->count;
1744 out_badvalue:
1745 dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
1746 return -EIO;
1747 out_overflow:
1748 print_overflow_msg(__func__, xdr);
1749 return -EIO;
1750 }
1751
1752 static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p,
1753 struct nfs_writeres *result)
1754 {
1755 struct xdr_stream xdr;
1756 enum nfs_stat status;
1757 int error;
1758
1759 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1760 error = decode_nfsstat3(&xdr, &status);
1761 if (unlikely(error))
1762 goto out;
1763 error = decode_wcc_data(&xdr, result->fattr);
1764 if (unlikely(error))
1765 goto out;
1766 if (status != NFS3_OK)
1767 goto out_status;
1768 error = decode_write3resok(&xdr, result);
1769 out:
1770 return error;
1771 out_status:
1772 return nfs_stat_to_errno(status);
1773 }
1774
1775 /*
1776 * 3.3.8 CREATE3res
1777 *
1778 * struct CREATE3resok {
1779 * post_op_fh3 obj;
1780 * post_op_attr obj_attributes;
1781 * wcc_data dir_wcc;
1782 * };
1783 *
1784 * struct CREATE3resfail {
1785 * wcc_data dir_wcc;
1786 * };
1787 *
1788 * union CREATE3res switch (nfsstat3 status) {
1789 * case NFS3_OK:
1790 * CREATE3resok resok;
1791 * default:
1792 * CREATE3resfail resfail;
1793 * };
1794 */
1795 static int decode_create3resok(struct xdr_stream *xdr,
1796 struct nfs3_diropres *result)
1797 {
1798 int error;
1799
1800 error = decode_post_op_fh3(xdr, result->fh);
1801 if (unlikely(error))
1802 goto out;
1803 error = decode_post_op_attr(xdr, result->fattr);
1804 if (unlikely(error))
1805 goto out;
1806 /* The server isn't required to return a file handle.
1807 * If it didn't, force the client to perform a LOOKUP
1808 * to determine the correct file handle and attribute
1809 * values for the new object. */
1810 if (result->fh->size == 0)
1811 result->fattr->valid = 0;
1812 error = decode_wcc_data(xdr, result->dir_attr);
1813 out:
1814 return error;
1815 }
1816
1817 static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p,
1818 struct nfs3_diropres *result)
1819 {
1820 struct xdr_stream xdr;
1821 enum nfs_stat status;
1822 int error;
1823
1824 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1825 error = decode_nfsstat3(&xdr, &status);
1826 if (unlikely(error))
1827 goto out;
1828 if (status != NFS3_OK)
1829 goto out_default;
1830 error = decode_create3resok(&xdr, result);
1831 out:
1832 return error;
1833 out_default:
1834 error = decode_wcc_data(&xdr, result->dir_attr);
1835 if (unlikely(error))
1836 goto out;
1837 return nfs_stat_to_errno(status);
1838 }
1839
1840 /*
1841 * 3.3.12 REMOVE3res
1842 *
1843 * struct REMOVE3resok {
1844 * wcc_data dir_wcc;
1845 * };
1846 *
1847 * struct REMOVE3resfail {
1848 * wcc_data dir_wcc;
1849 * };
1850 *
1851 * union REMOVE3res switch (nfsstat3 status) {
1852 * case NFS3_OK:
1853 * REMOVE3resok resok;
1854 * default:
1855 * REMOVE3resfail resfail;
1856 * };
1857 */
1858 static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p,
1859 struct nfs_removeres *result)
1860 {
1861 struct xdr_stream xdr;
1862 enum nfs_stat status;
1863 int error;
1864
1865 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1866 error = decode_nfsstat3(&xdr, &status);
1867 if (unlikely(error))
1868 goto out;
1869 error = decode_wcc_data(&xdr, result->dir_attr);
1870 if (unlikely(error))
1871 goto out;
1872 if (status != NFS3_OK)
1873 goto out_status;
1874 out:
1875 return error;
1876 out_status:
1877 return nfs_stat_to_errno(status);
1878 }
1879
1880 /*
1881 * 3.3.14 RENAME3res
1882 *
1883 * struct RENAME3resok {
1884 * wcc_data fromdir_wcc;
1885 * wcc_data todir_wcc;
1886 * };
1887 *
1888 * struct RENAME3resfail {
1889 * wcc_data fromdir_wcc;
1890 * wcc_data todir_wcc;
1891 * };
1892 *
1893 * union RENAME3res switch (nfsstat3 status) {
1894 * case NFS3_OK:
1895 * RENAME3resok resok;
1896 * default:
1897 * RENAME3resfail resfail;
1898 * };
1899 */
1900 static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p,
1901 struct nfs_renameres *result)
1902 {
1903 struct xdr_stream xdr;
1904 enum nfs_stat status;
1905 int error;
1906
1907 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1908 error = decode_nfsstat3(&xdr, &status);
1909 if (unlikely(error))
1910 goto out;
1911 error = decode_wcc_data(&xdr, result->old_fattr);
1912 if (unlikely(error))
1913 goto out;
1914 error = decode_wcc_data(&xdr, result->new_fattr);
1915 if (unlikely(error))
1916 goto out;
1917 if (status != NFS3_OK)
1918 goto out_status;
1919 out:
1920 return error;
1921 out_status:
1922 return nfs_stat_to_errno(status);
1923 }
1924
1925 /*
1926 * 3.3.15 LINK3res
1927 *
1928 * struct LINK3resok {
1929 * post_op_attr file_attributes;
1930 * wcc_data linkdir_wcc;
1931 * };
1932 *
1933 * struct LINK3resfail {
1934 * post_op_attr file_attributes;
1935 * wcc_data linkdir_wcc;
1936 * };
1937 *
1938 * union LINK3res switch (nfsstat3 status) {
1939 * case NFS3_OK:
1940 * LINK3resok resok;
1941 * default:
1942 * LINK3resfail resfail;
1943 * };
1944 */
1945 static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p,
1946 struct nfs3_linkres *result)
1947 {
1948 struct xdr_stream xdr;
1949 enum nfs_stat status;
1950 int error;
1951
1952 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1953 error = decode_nfsstat3(&xdr, &status);
1954 if (unlikely(error))
1955 goto out;
1956 error = decode_post_op_attr(&xdr, result->fattr);
1957 if (unlikely(error))
1958 goto out;
1959 error = decode_wcc_data(&xdr, result->dir_attr);
1960 if (unlikely(error))
1961 goto out;
1962 if (status != NFS3_OK)
1963 goto out_status;
1964 out:
1965 return error;
1966 out_status:
1967 return nfs_stat_to_errno(status);
1968 }
1969
1970 /**
1971 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1972 * the local page cache
1973 * @xdr: XDR stream where entry resides
1974 * @entry: buffer to fill in with entry data
1975 * @server: nfs_server data for this directory
1976 * @plus: boolean indicating whether this should be a readdirplus entry
1977 *
1978 * Returns the position of the next item in the buffer, or an ERR_PTR.
1979 *
1980 * This function is not invoked during READDIR reply decoding, but
1981 * rather whenever an application invokes the getdents(2) system call
1982 * on a directory already in our cache.
1983 *
1984 * 3.3.16 entry3
1985 *
1986 * struct entry3 {
1987 * fileid3 fileid;
1988 * filename3 name;
1989 * cookie3 cookie;
1990 * fhandle3 filehandle;
1991 * post_op_attr3 attributes;
1992 * entry3 *nextentry;
1993 * };
1994 *
1995 * 3.3.17 entryplus3
1996 * struct entryplus3 {
1997 * fileid3 fileid;
1998 * filename3 name;
1999 * cookie3 cookie;
2000 * post_op_attr name_attributes;
2001 * post_op_fh3 name_handle;
2002 * entryplus3 *nextentry;
2003 * };
2004 */
2005 __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
2006 struct nfs_server *server, int plus)
2007 {
2008 struct nfs_entry old = *entry;
2009 __be32 *p;
2010 int error;
2011
2012 p = xdr_inline_decode(xdr, 4);
2013 if (unlikely(p == NULL))
2014 goto out_overflow;
2015 if (*p == xdr_zero) {
2016 p = xdr_inline_decode(xdr, 4);
2017 if (unlikely(p == NULL))
2018 goto out_overflow;
2019 if (*p == xdr_zero)
2020 return ERR_PTR(-EAGAIN);
2021 entry->eof = 1;
2022 return ERR_PTR(-EBADCOOKIE);
2023 }
2024
2025 error = decode_fileid3(xdr, &entry->ino);
2026 if (unlikely(error))
2027 return ERR_PTR(error);
2028
2029 error = decode_inline_filename3(xdr, &entry->name, &entry->len);
2030 if (unlikely(error))
2031 return ERR_PTR(error);
2032
2033 entry->prev_cookie = entry->cookie;
2034 error = decode_cookie3(xdr, &entry->cookie);
2035 if (unlikely(error))
2036 return ERR_PTR(error);
2037
2038 entry->d_type = DT_UNKNOWN;
2039
2040 if (plus) {
2041 entry->fattr->valid = 0;
2042 error = decode_post_op_attr(xdr, entry->fattr);
2043 if (unlikely(error))
2044 return ERR_PTR(error);
2045 if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2046 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2047
2048 /* In fact, a post_op_fh3: */
2049 p = xdr_inline_decode(xdr, 4);
2050 if (unlikely(p == NULL))
2051 goto out_overflow;
2052 if (*p != xdr_zero) {
2053 error = decode_nfs_fh3(xdr, entry->fh);
2054 if (unlikely(error)) {
2055 if (error == -E2BIG)
2056 goto out_truncated;
2057 return ERR_PTR(error);
2058 }
2059 } else
2060 zero_nfs_fh3(entry->fh);
2061 }
2062
2063 /* Peek at the next entry to see if we're at EOD */
2064 p = xdr_inline_peek(xdr, 4 + 4);
2065 entry->eof = 0;
2066 if (p != NULL)
2067 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
2068 return p;
2069
2070 out_overflow:
2071 print_overflow_msg(__func__, xdr);
2072 return ERR_PTR(-EAGAIN);
2073 out_truncated:
2074 dprintk("NFS: directory entry contains invalid file handle\n");
2075 *entry = old;
2076 return ERR_PTR(-EAGAIN);
2077 }
2078
2079 /*
2080 * 3.3.16 READDIR3res
2081 *
2082 * struct dirlist3 {
2083 * entry3 *entries;
2084 * bool eof;
2085 * };
2086 *
2087 * struct READDIR3resok {
2088 * post_op_attr dir_attributes;
2089 * cookieverf3 cookieverf;
2090 * dirlist3 reply;
2091 * };
2092 *
2093 * struct READDIR3resfail {
2094 * post_op_attr dir_attributes;
2095 * };
2096 *
2097 * union READDIR3res switch (nfsstat3 status) {
2098 * case NFS3_OK:
2099 * READDIR3resok resok;
2100 * default:
2101 * READDIR3resfail resfail;
2102 * };
2103 *
2104 * Read the directory contents into the page cache, but otherwise
2105 * don't touch them. The actual decoding is done by nfs3_decode_entry()
2106 * during subsequent nfs_readdir() calls.
2107 */
2108 static int decode_dirlist3(struct xdr_stream *xdr)
2109 {
2110 u32 recvd, pglen;
2111 size_t hdrlen;
2112
2113 pglen = xdr->buf->page_len;
2114 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2115 recvd = xdr->buf->len - hdrlen;
2116 if (unlikely(pglen > recvd))
2117 goto out_cheating;
2118 out:
2119 xdr_read_pages(xdr, pglen);
2120 return pglen;
2121 out_cheating:
2122 dprintk("NFS: server cheating in readdir result: "
2123 "pglen %u > recvd %u\n", pglen, recvd);
2124 pglen = recvd;
2125 goto out;
2126 }
2127
2128 static int decode_readdir3resok(struct xdr_stream *xdr,
2129 struct nfs3_readdirres *result)
2130 {
2131 int error;
2132
2133 error = decode_post_op_attr(xdr, result->dir_attr);
2134 if (unlikely(error))
2135 goto out;
2136 /* XXX: do we need to check if result->verf != NULL ? */
2137 error = decode_cookieverf3(xdr, result->verf);
2138 if (unlikely(error))
2139 goto out;
2140 error = decode_dirlist3(xdr);
2141 out:
2142 return error;
2143 }
2144
2145 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p,
2146 struct nfs3_readdirres *result)
2147 {
2148 struct xdr_stream xdr;
2149 enum nfs_stat status;
2150 int error;
2151
2152 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2153 error = decode_nfsstat3(&xdr, &status);
2154 if (unlikely(error))
2155 goto out;
2156 if (status != NFS3_OK)
2157 goto out_default;
2158 error = decode_readdir3resok(&xdr, result);
2159 out:
2160 return error;
2161 out_default:
2162 error = decode_post_op_attr(&xdr, result->dir_attr);
2163 if (unlikely(error))
2164 goto out;
2165 return nfs_stat_to_errno(status);
2166 }
2167
2168 /*
2169 * 3.3.18 FSSTAT3res
2170 *
2171 * struct FSSTAT3resok {
2172 * post_op_attr obj_attributes;
2173 * size3 tbytes;
2174 * size3 fbytes;
2175 * size3 abytes;
2176 * size3 tfiles;
2177 * size3 ffiles;
2178 * size3 afiles;
2179 * uint32 invarsec;
2180 * };
2181 *
2182 * struct FSSTAT3resfail {
2183 * post_op_attr obj_attributes;
2184 * };
2185 *
2186 * union FSSTAT3res switch (nfsstat3 status) {
2187 * case NFS3_OK:
2188 * FSSTAT3resok resok;
2189 * default:
2190 * FSSTAT3resfail resfail;
2191 * };
2192 */
2193 static int decode_fsstat3resok(struct xdr_stream *xdr,
2194 struct nfs_fsstat *result)
2195 {
2196 __be32 *p;
2197
2198 p = xdr_inline_decode(xdr, 8 * 6 + 4);
2199 if (unlikely(p == NULL))
2200 goto out_overflow;
2201 p = xdr_decode_size3(p, &result->tbytes);
2202 p = xdr_decode_size3(p, &result->fbytes);
2203 p = xdr_decode_size3(p, &result->abytes);
2204 p = xdr_decode_size3(p, &result->tfiles);
2205 p = xdr_decode_size3(p, &result->ffiles);
2206 xdr_decode_size3(p, &result->afiles);
2207 /* ignore invarsec */
2208 return 0;
2209 out_overflow:
2210 print_overflow_msg(__func__, xdr);
2211 return -EIO;
2212 }
2213
2214 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p,
2215 struct nfs_fsstat *result)
2216 {
2217 struct xdr_stream xdr;
2218 enum nfs_stat status;
2219 int error;
2220
2221 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2222 error = decode_nfsstat3(&xdr, &status);
2223 if (unlikely(error))
2224 goto out;
2225 error = decode_post_op_attr(&xdr, result->fattr);
2226 if (unlikely(error))
2227 goto out;
2228 if (status != NFS3_OK)
2229 goto out_status;
2230 error = decode_fsstat3resok(&xdr, result);
2231 out:
2232 return error;
2233 out_status:
2234 return nfs_stat_to_errno(status);
2235 }
2236
2237 /*
2238 * 3.3.19 FSINFO3res
2239 *
2240 * struct FSINFO3resok {
2241 * post_op_attr obj_attributes;
2242 * uint32 rtmax;
2243 * uint32 rtpref;
2244 * uint32 rtmult;
2245 * uint32 wtmax;
2246 * uint32 wtpref;
2247 * uint32 wtmult;
2248 * uint32 dtpref;
2249 * size3 maxfilesize;
2250 * nfstime3 time_delta;
2251 * uint32 properties;
2252 * };
2253 *
2254 * struct FSINFO3resfail {
2255 * post_op_attr obj_attributes;
2256 * };
2257 *
2258 * union FSINFO3res switch (nfsstat3 status) {
2259 * case NFS3_OK:
2260 * FSINFO3resok resok;
2261 * default:
2262 * FSINFO3resfail resfail;
2263 * };
2264 */
2265 static int decode_fsinfo3resok(struct xdr_stream *xdr,
2266 struct nfs_fsinfo *result)
2267 {
2268 __be32 *p;
2269
2270 p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2271 if (unlikely(p == NULL))
2272 goto out_overflow;
2273 result->rtmax = be32_to_cpup(p++);
2274 result->rtpref = be32_to_cpup(p++);
2275 result->rtmult = be32_to_cpup(p++);
2276 result->wtmax = be32_to_cpup(p++);
2277 result->wtpref = be32_to_cpup(p++);
2278 result->wtmult = be32_to_cpup(p++);
2279 result->dtpref = be32_to_cpup(p++);
2280 p = xdr_decode_size3(p, &result->maxfilesize);
2281 xdr_decode_time3(p, &result->time_delta);
2282
2283 /* ignore properties */
2284 result->lease_time = 0;
2285 return 0;
2286 out_overflow:
2287 print_overflow_msg(__func__, xdr);
2288 return -EIO;
2289 }
2290
2291 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p,
2292 struct nfs_fsinfo *result)
2293 {
2294 struct xdr_stream xdr;
2295 enum nfs_stat status;
2296 int error;
2297
2298 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2299 error = decode_nfsstat3(&xdr, &status);
2300 if (unlikely(error))
2301 goto out;
2302 error = decode_post_op_attr(&xdr, result->fattr);
2303 if (unlikely(error))
2304 goto out;
2305 if (status != NFS3_OK)
2306 goto out_status;
2307 error = decode_fsinfo3resok(&xdr, result);
2308 out:
2309 return error;
2310 out_status:
2311 return nfs_stat_to_errno(status);
2312 }
2313
2314 /*
2315 * 3.3.20 PATHCONF3res
2316 *
2317 * struct PATHCONF3resok {
2318 * post_op_attr obj_attributes;
2319 * uint32 linkmax;
2320 * uint32 name_max;
2321 * bool no_trunc;
2322 * bool chown_restricted;
2323 * bool case_insensitive;
2324 * bool case_preserving;
2325 * };
2326 *
2327 * struct PATHCONF3resfail {
2328 * post_op_attr obj_attributes;
2329 * };
2330 *
2331 * union PATHCONF3res switch (nfsstat3 status) {
2332 * case NFS3_OK:
2333 * PATHCONF3resok resok;
2334 * default:
2335 * PATHCONF3resfail resfail;
2336 * };
2337 */
2338 static int decode_pathconf3resok(struct xdr_stream *xdr,
2339 struct nfs_pathconf *result)
2340 {
2341 __be32 *p;
2342
2343 p = xdr_inline_decode(xdr, 4 * 6);
2344 if (unlikely(p == NULL))
2345 goto out_overflow;
2346 result->max_link = be32_to_cpup(p++);
2347 result->max_namelen = be32_to_cpup(p);
2348 /* ignore remaining fields */
2349 return 0;
2350 out_overflow:
2351 print_overflow_msg(__func__, xdr);
2352 return -EIO;
2353 }
2354
2355 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p,
2356 struct nfs_pathconf *result)
2357 {
2358 struct xdr_stream xdr;
2359 enum nfs_stat status;
2360 int error;
2361
2362 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2363 error = decode_nfsstat3(&xdr, &status);
2364 if (unlikely(error))
2365 goto out;
2366 error = decode_post_op_attr(&xdr, result->fattr);
2367 if (unlikely(error))
2368 goto out;
2369 if (status != NFS3_OK)
2370 goto out_status;
2371 error = decode_pathconf3resok(&xdr, result);
2372 out:
2373 return error;
2374 out_status:
2375 return nfs_stat_to_errno(status);
2376 }
2377
2378 /*
2379 * 3.3.21 COMMIT3res
2380 *
2381 * struct COMMIT3resok {
2382 * wcc_data file_wcc;
2383 * writeverf3 verf;
2384 * };
2385 *
2386 * struct COMMIT3resfail {
2387 * wcc_data file_wcc;
2388 * };
2389 *
2390 * union COMMIT3res switch (nfsstat3 status) {
2391 * case NFS3_OK:
2392 * COMMIT3resok resok;
2393 * default:
2394 * COMMIT3resfail resfail;
2395 * };
2396 */
2397 static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p,
2398 struct nfs_writeres *result)
2399 {
2400 struct xdr_stream xdr;
2401 enum nfs_stat status;
2402 int error;
2403
2404 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2405 error = decode_nfsstat3(&xdr, &status);
2406 if (unlikely(error))
2407 goto out;
2408 error = decode_wcc_data(&xdr, result->fattr);
2409 if (unlikely(error))
2410 goto out;
2411 if (status != NFS3_OK)
2412 goto out_status;
2413 error = decode_writeverf3(&xdr, result->verf->verifier);
2414 out:
2415 return error;
2416 out_status:
2417 return nfs_stat_to_errno(status);
2418 }
2419
2420 #ifdef CONFIG_NFS_V3_ACL
2421
2422 static inline int decode_getacl3resok(struct xdr_stream *xdr,
2423 struct nfs3_getaclres *result)
2424 {
2425 struct posix_acl **acl;
2426 unsigned int *aclcnt;
2427 size_t hdrlen;
2428 int error;
2429
2430 error = decode_post_op_attr(xdr, result->fattr);
2431 if (unlikely(error))
2432 goto out;
2433 error = decode_uint32(xdr, &result->mask);
2434 if (unlikely(error))
2435 goto out;
2436 error = -EINVAL;
2437 if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2438 goto out;
2439
2440 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2441
2442 acl = NULL;
2443 if (result->mask & NFS_ACL)
2444 acl = &result->acl_access;
2445 aclcnt = NULL;
2446 if (result->mask & NFS_ACLCNT)
2447 aclcnt = &result->acl_access_count;
2448 error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2449 if (unlikely(error <= 0))
2450 goto out;
2451
2452 acl = NULL;
2453 if (result->mask & NFS_DFACL)
2454 acl = &result->acl_default;
2455 aclcnt = NULL;
2456 if (result->mask & NFS_DFACLCNT)
2457 aclcnt = &result->acl_default_count;
2458 error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2459 if (unlikely(error <= 0))
2460 return error;
2461 error = 0;
2462 out:
2463 return error;
2464 }
2465
2466 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p,
2467 struct nfs3_getaclres *result)
2468 {
2469 struct xdr_stream xdr;
2470 enum nfs_stat status;
2471 int error;
2472
2473 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2474 error = decode_nfsstat3(&xdr, &status);
2475 if (unlikely(error))
2476 goto out;
2477 if (status != NFS3_OK)
2478 goto out_default;
2479 error = decode_getacl3resok(&xdr, result);
2480 out:
2481 return error;
2482 out_default:
2483 return nfs_stat_to_errno(status);
2484 }
2485
2486 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p,
2487 struct nfs_fattr *result)
2488 {
2489 struct xdr_stream xdr;
2490 enum nfs_stat status;
2491 int error;
2492
2493 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2494 error = decode_nfsstat3(&xdr, &status);
2495 if (unlikely(error))
2496 goto out;
2497 if (status != NFS3_OK)
2498 goto out_default;
2499 error = decode_post_op_attr(&xdr, result);
2500 out:
2501 return error;
2502 out_default:
2503 return nfs_stat_to_errno(status);
2504 }
2505
2506 #endif /* CONFIG_NFS_V3_ACL */
2507
2508 #define PROC(proc, argtype, restype, timer) \
2509 [NFS3PROC_##proc] = { \
2510 .p_proc = NFS3PROC_##proc, \
2511 .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
2512 .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \
2513 .p_arglen = NFS3_##argtype##args_sz, \
2514 .p_replen = NFS3_##restype##res_sz, \
2515 .p_timer = timer, \
2516 .p_statidx = NFS3PROC_##proc, \
2517 .p_name = #proc, \
2518 }
2519
2520 struct rpc_procinfo nfs3_procedures[] = {
2521 PROC(GETATTR, getattr, getattr, 1),
2522 PROC(SETATTR, setattr, setattr, 0),
2523 PROC(LOOKUP, lookup, lookup, 2),
2524 PROC(ACCESS, access, access, 1),
2525 PROC(READLINK, readlink, readlink, 3),
2526 PROC(READ, read, read, 3),
2527 PROC(WRITE, write, write, 4),
2528 PROC(CREATE, create, create, 0),
2529 PROC(MKDIR, mkdir, create, 0),
2530 PROC(SYMLINK, symlink, create, 0),
2531 PROC(MKNOD, mknod, create, 0),
2532 PROC(REMOVE, remove, remove, 0),
2533 PROC(RMDIR, lookup, setattr, 0),
2534 PROC(RENAME, rename, rename, 0),
2535 PROC(LINK, link, link, 0),
2536 PROC(READDIR, readdir, readdir, 3),
2537 PROC(READDIRPLUS, readdirplus, readdir, 3),
2538 PROC(FSSTAT, getattr, fsstat, 0),
2539 PROC(FSINFO, getattr, fsinfo, 0),
2540 PROC(PATHCONF, getattr, pathconf, 0),
2541 PROC(COMMIT, commit, commit, 5),
2542 };
2543
2544 struct rpc_version nfs_version3 = {
2545 .number = 3,
2546 .nrprocs = ARRAY_SIZE(nfs3_procedures),
2547 .procs = nfs3_procedures
2548 };
2549
2550 #ifdef CONFIG_NFS_V3_ACL
2551 static struct rpc_procinfo nfs3_acl_procedures[] = {
2552 [ACLPROC3_GETACL] = {
2553 .p_proc = ACLPROC3_GETACL,
2554 .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
2555 .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res,
2556 .p_arglen = ACL3_getaclargs_sz,
2557 .p_replen = ACL3_getaclres_sz,
2558 .p_timer = 1,
2559 .p_name = "GETACL",
2560 },
2561 [ACLPROC3_SETACL] = {
2562 .p_proc = ACLPROC3_SETACL,
2563 .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
2564 .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res,
2565 .p_arglen = ACL3_setaclargs_sz,
2566 .p_replen = ACL3_setaclres_sz,
2567 .p_timer = 0,
2568 .p_name = "SETACL",
2569 },
2570 };
2571
2572 struct rpc_version nfsacl_version3 = {
2573 .number = 3,
2574 .nrprocs = sizeof(nfs3_acl_procedures)/
2575 sizeof(nfs3_acl_procedures[0]),
2576 .procs = nfs3_acl_procedures,
2577 };
2578 #endif /* CONFIG_NFS_V3_ACL */
This page took 0.0823 seconds and 5 git commands to generate.