~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfs/nfs3xdr.c

Version: ~ [ linux-4.16-rc1 ] ~ [ linux-4.15.2 ] ~ [ linux-4.14.18 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.80 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.115 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.49 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.94 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.53 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.98 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp