Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nfs2xdr.c
Go to the documentation of this file.
1 /*
2  * linux/fs/nfs/nfs2xdr.c
3  *
4  * XDR functions to encode/decode NFS RPC arguments and results.
5  *
6  * Copyright (C) 1992, 1993, 1994 Rick Sladkey
7  * Copyright (C) 1996 Olaf Kirch
8  * 04 Aug 1998 Ion Badulescu <[email protected]>
9  * FIFO's need special handling in NFSv2
10  */
11 
12 #include <linux/param.h>
13 #include <linux/time.h>
14 #include <linux/mm.h>
15 #include <linux/errno.h>
16 #include <linux/string.h>
17 #include <linux/in.h>
18 #include <linux/pagemap.h>
19 #include <linux/proc_fs.h>
20 #include <linux/sunrpc/clnt.h>
21 #include <linux/nfs.h>
22 #include <linux/nfs2.h>
23 #include <linux/nfs_fs.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 NFS_fhandle_sz (8)
36 #define NFS_sattr_sz (8)
37 #define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2))
38 #define NFS_path_sz (1+(NFS2_MAXPATHLEN>>2))
39 #define NFS_fattr_sz (17)
40 #define NFS_info_sz (5)
41 #define NFS_entry_sz (NFS_filename_sz+3)
42 
43 #define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz)
44 #define NFS_removeargs_sz (NFS_fhandle_sz+NFS_filename_sz)
45 #define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz)
46 #define NFS_readlinkargs_sz (NFS_fhandle_sz)
47 #define NFS_readargs_sz (NFS_fhandle_sz+3)
48 #define NFS_writeargs_sz (NFS_fhandle_sz+4)
49 #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz)
50 #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz)
51 #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz)
52 #define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz)
53 #define NFS_readdirargs_sz (NFS_fhandle_sz+2)
54 
55 #define NFS_attrstat_sz (1+NFS_fattr_sz)
56 #define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz)
57 #define NFS_readlinkres_sz (2)
58 #define NFS_readres_sz (1+NFS_fattr_sz+1)
59 #define NFS_writeres_sz (NFS_attrstat_sz)
60 #define NFS_stat_sz (1)
61 #define NFS_readdirres_sz (1)
62 #define NFS_statfsres_sz (1+NFS_info_sz)
63 
64 static int nfs_stat_to_errno(enum nfs_stat);
65 
66 /*
67  * While encoding arguments, set up the reply buffer in advance to
68  * receive reply data directly into the page cache.
69  */
70 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
71  unsigned int base, unsigned int len,
72  unsigned int bufsize)
73 {
74  struct rpc_auth *auth = req->rq_cred->cr_auth;
75  unsigned int replen;
76 
77  replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
78  xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
79 }
80 
81 /*
82  * Handle decode buffer overflows out-of-line.
83  */
84 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
85 {
86  dprintk("NFS: %s prematurely hit the end of our receive buffer. "
87  "Remaining buffer length is %tu words.\n",
88  func, xdr->end - xdr->p);
89 }
90 
91 
92 /*
93  * Encode/decode NFSv2 basic data types
94  *
95  * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
96  * "NFS: Network File System Protocol Specification".
97  *
98  * Not all basic data types have their own encoding and decoding
99  * functions. For run-time efficiency, some data types are encoded
100  * or decoded inline.
101  */
102 
103 /*
104  * typedef opaque nfsdata<>;
105  */
106 static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result)
107 {
108  u32 recvd, count;
109  __be32 *p;
110 
111  p = xdr_inline_decode(xdr, 4);
112  if (unlikely(p == NULL))
113  goto out_overflow;
114  count = be32_to_cpup(p);
115  recvd = xdr_read_pages(xdr, count);
116  if (unlikely(count > recvd))
117  goto out_cheating;
118 out:
119  result->eof = 0; /* NFSv2 does not pass EOF flag on the wire. */
120  result->count = count;
121  return count;
122 out_cheating:
123  dprintk("NFS: server cheating in read result: "
124  "count %u > recvd %u\n", count, recvd);
125  count = recvd;
126  goto out;
127 out_overflow:
128  print_overflow_msg(__func__, xdr);
129  return -EIO;
130 }
131 
132 /*
133  * enum stat {
134  * NFS_OK = 0,
135  * NFSERR_PERM = 1,
136  * NFSERR_NOENT = 2,
137  * NFSERR_IO = 5,
138  * NFSERR_NXIO = 6,
139  * NFSERR_ACCES = 13,
140  * NFSERR_EXIST = 17,
141  * NFSERR_NODEV = 19,
142  * NFSERR_NOTDIR = 20,
143  * NFSERR_ISDIR = 21,
144  * NFSERR_FBIG = 27,
145  * NFSERR_NOSPC = 28,
146  * NFSERR_ROFS = 30,
147  * NFSERR_NAMETOOLONG = 63,
148  * NFSERR_NOTEMPTY = 66,
149  * NFSERR_DQUOT = 69,
150  * NFSERR_STALE = 70,
151  * NFSERR_WFLUSH = 99
152  * };
153  */
154 static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
155 {
156  __be32 *p;
157 
158  p = xdr_inline_decode(xdr, 4);
159  if (unlikely(p == NULL))
160  goto out_overflow;
161  *status = be32_to_cpup(p);
162  return 0;
163 out_overflow:
164  print_overflow_msg(__func__, xdr);
165  return -EIO;
166 }
167 
168 /*
169  * 2.3.2. ftype
170  *
171  * enum ftype {
172  * NFNON = 0,
173  * NFREG = 1,
174  * NFDIR = 2,
175  * NFBLK = 3,
176  * NFCHR = 4,
177  * NFLNK = 5
178  * };
179  *
180  */
181 static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
182 {
183  *type = be32_to_cpup(p++);
184  if (unlikely(*type > NF2FIFO))
185  *type = NFBAD;
186  return p;
187 }
188 
189 /*
190  * 2.3.3. fhandle
191  *
192  * typedef opaque fhandle[FHSIZE];
193  */
194 static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
195 {
196  __be32 *p;
197 
198  BUG_ON(fh->size != NFS2_FHSIZE);
199  p = xdr_reserve_space(xdr, NFS2_FHSIZE);
200  memcpy(p, fh->data, NFS2_FHSIZE);
201 }
202 
203 static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
204 {
205  __be32 *p;
206 
207  p = xdr_inline_decode(xdr, NFS2_FHSIZE);
208  if (unlikely(p == NULL))
209  goto out_overflow;
210  fh->size = NFS2_FHSIZE;
211  memcpy(fh->data, p, NFS2_FHSIZE);
212  return 0;
213 out_overflow:
214  print_overflow_msg(__func__, xdr);
215  return -EIO;
216 }
217 
218 /*
219  * 2.3.4. timeval
220  *
221  * struct timeval {
222  * unsigned int seconds;
223  * unsigned int useconds;
224  * };
225  */
226 static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
227 {
228  *p++ = cpu_to_be32(timep->tv_sec);
229  if (timep->tv_nsec != 0)
230  *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
231  else
232  *p++ = cpu_to_be32(0);
233  return p;
234 }
235 
236 /*
237  * Passing the invalid value useconds=1000000 is a Sun convention for
238  * "set to current server time". It's needed to make permissions checks
239  * for the "touch" program across v2 mounts to Solaris and Irix servers
240  * work correctly. See description of sattr in section 6.1 of "NFS
241  * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
242  */
243 static __be32 *xdr_encode_current_server_time(__be32 *p,
244  const struct timespec *timep)
245 {
246  *p++ = cpu_to_be32(timep->tv_sec);
247  *p++ = cpu_to_be32(1000000);
248  return p;
249 }
250 
251 static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
252 {
253  timep->tv_sec = be32_to_cpup(p++);
254  timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
255  return p;
256 }
257 
258 /*
259  * 2.3.5. fattr
260  *
261  * struct fattr {
262  * ftype type;
263  * unsigned int mode;
264  * unsigned int nlink;
265  * unsigned int uid;
266  * unsigned int gid;
267  * unsigned int size;
268  * unsigned int blocksize;
269  * unsigned int rdev;
270  * unsigned int blocks;
271  * unsigned int fsid;
272  * unsigned int fileid;
273  * timeval atime;
274  * timeval mtime;
275  * timeval ctime;
276  * };
277  *
278  */
279 static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
280 {
281  u32 rdev, type;
282  __be32 *p;
283 
284  p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
285  if (unlikely(p == NULL))
286  goto out_overflow;
287 
288  fattr->valid |= NFS_ATTR_FATTR_V2;
289 
290  p = xdr_decode_ftype(p, &type);
291 
292  fattr->mode = be32_to_cpup(p++);
293  fattr->nlink = be32_to_cpup(p++);
294  fattr->uid = be32_to_cpup(p++);
295  fattr->gid = be32_to_cpup(p++);
296  fattr->size = be32_to_cpup(p++);
297  fattr->du.nfs2.blocksize = be32_to_cpup(p++);
298 
299  rdev = be32_to_cpup(p++);
300  fattr->rdev = new_decode_dev(rdev);
301  if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
302  fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
303  fattr->rdev = 0;
304  }
305 
306  fattr->du.nfs2.blocks = be32_to_cpup(p++);
307  fattr->fsid.major = be32_to_cpup(p++);
308  fattr->fsid.minor = 0;
309  fattr->fileid = be32_to_cpup(p++);
310 
311  p = xdr_decode_time(p, &fattr->atime);
312  p = xdr_decode_time(p, &fattr->mtime);
313  xdr_decode_time(p, &fattr->ctime);
314  fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
315 
316  return 0;
317 out_overflow:
318  print_overflow_msg(__func__, xdr);
319  return -EIO;
320 }
321 
322 /*
323  * 2.3.6. sattr
324  *
325  * struct sattr {
326  * unsigned int mode;
327  * unsigned int uid;
328  * unsigned int gid;
329  * unsigned int size;
330  * timeval atime;
331  * timeval mtime;
332  * };
333  */
334 
335 #define NFS2_SATTR_NOT_SET (0xffffffff)
336 
337 static __be32 *xdr_time_not_set(__be32 *p)
338 {
341  return p;
342 }
343 
344 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
345 {
346  __be32 *p;
347 
348  p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
349 
350  if (attr->ia_valid & ATTR_MODE)
351  *p++ = cpu_to_be32(attr->ia_mode);
352  else
354  if (attr->ia_valid & ATTR_UID)
355  *p++ = cpu_to_be32(attr->ia_uid);
356  else
358  if (attr->ia_valid & ATTR_GID)
359  *p++ = cpu_to_be32(attr->ia_gid);
360  else
362  if (attr->ia_valid & ATTR_SIZE)
363  *p++ = cpu_to_be32((u32)attr->ia_size);
364  else
366 
367  if (attr->ia_valid & ATTR_ATIME_SET)
368  p = xdr_encode_time(p, &attr->ia_atime);
369  else if (attr->ia_valid & ATTR_ATIME)
370  p = xdr_encode_current_server_time(p, &attr->ia_atime);
371  else
372  p = xdr_time_not_set(p);
373  if (attr->ia_valid & ATTR_MTIME_SET)
374  xdr_encode_time(p, &attr->ia_mtime);
375  else if (attr->ia_valid & ATTR_MTIME)
376  xdr_encode_current_server_time(p, &attr->ia_mtime);
377  else
378  xdr_time_not_set(p);
379 }
380 
381 /*
382  * 2.3.7. filename
383  *
384  * typedef string filename<MAXNAMLEN>;
385  */
386 static void encode_filename(struct xdr_stream *xdr,
387  const char *name, u32 length)
388 {
389  __be32 *p;
390 
391  BUG_ON(length > NFS2_MAXNAMLEN);
392  p = xdr_reserve_space(xdr, 4 + length);
393  xdr_encode_opaque(p, name, length);
394 }
395 
396 static int decode_filename_inline(struct xdr_stream *xdr,
397  const char **name, u32 *length)
398 {
399  __be32 *p;
400  u32 count;
401 
402  p = xdr_inline_decode(xdr, 4);
403  if (unlikely(p == NULL))
404  goto out_overflow;
405  count = be32_to_cpup(p);
406  if (count > NFS3_MAXNAMLEN)
407  goto out_nametoolong;
408  p = xdr_inline_decode(xdr, count);
409  if (unlikely(p == NULL))
410  goto out_overflow;
411  *name = (const char *)p;
412  *length = count;
413  return 0;
414 out_nametoolong:
415  dprintk("NFS: returned filename too long: %u\n", count);
416  return -ENAMETOOLONG;
417 out_overflow:
418  print_overflow_msg(__func__, xdr);
419  return -EIO;
420 }
421 
422 /*
423  * 2.3.8. path
424  *
425  * typedef string path<MAXPATHLEN>;
426  */
427 static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
428 {
429  __be32 *p;
430 
431  BUG_ON(length > NFS2_MAXPATHLEN);
432  p = xdr_reserve_space(xdr, 4);
433  *p = cpu_to_be32(length);
434  xdr_write_pages(xdr, pages, 0, length);
435 }
436 
437 static int decode_path(struct xdr_stream *xdr)
438 {
439  u32 length, recvd;
440  __be32 *p;
441 
442  p = xdr_inline_decode(xdr, 4);
443  if (unlikely(p == NULL))
444  goto out_overflow;
445  length = be32_to_cpup(p);
446  if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
447  goto out_size;
448  recvd = xdr_read_pages(xdr, length);
449  if (unlikely(length > recvd))
450  goto out_cheating;
451  xdr_terminate_string(xdr->buf, length);
452  return 0;
453 out_size:
454  dprintk("NFS: returned pathname too long: %u\n", length);
455  return -ENAMETOOLONG;
456 out_cheating:
457  dprintk("NFS: server cheating in pathname result: "
458  "length %u > received %u\n", length, recvd);
459  return -EIO;
460 out_overflow:
461  print_overflow_msg(__func__, xdr);
462  return -EIO;
463 }
464 
465 /*
466  * 2.3.9. attrstat
467  *
468  * union attrstat switch (stat status) {
469  * case NFS_OK:
470  * fattr attributes;
471  * default:
472  * void;
473  * };
474  */
475 static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
476 {
477  enum nfs_stat status;
478  int error;
479 
480  error = decode_stat(xdr, &status);
481  if (unlikely(error))
482  goto out;
483  if (status != NFS_OK)
484  goto out_default;
485  error = decode_fattr(xdr, result);
486 out:
487  return error;
488 out_default:
489  return nfs_stat_to_errno(status);
490 }
491 
492 /*
493  * 2.3.10. diropargs
494  *
495  * struct diropargs {
496  * fhandle dir;
497  * filename name;
498  * };
499  */
500 static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
501  const char *name, u32 length)
502 {
503  encode_fhandle(xdr, fh);
504  encode_filename(xdr, name, length);
505 }
506 
507 /*
508  * 2.3.11. diropres
509  *
510  * union diropres switch (stat status) {
511  * case NFS_OK:
512  * struct {
513  * fhandle file;
514  * fattr attributes;
515  * } diropok;
516  * default:
517  * void;
518  * };
519  */
520 static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
521 {
522  int error;
523 
524  error = decode_fhandle(xdr, result->fh);
525  if (unlikely(error))
526  goto out;
527  error = decode_fattr(xdr, result->fattr);
528 out:
529  return error;
530 }
531 
532 static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
533 {
534  enum nfs_stat status;
535  int error;
536 
537  error = decode_stat(xdr, &status);
538  if (unlikely(error))
539  goto out;
540  if (status != NFS_OK)
541  goto out_default;
542  error = decode_diropok(xdr, result);
543 out:
544  return error;
545 out_default:
546  return nfs_stat_to_errno(status);
547 }
548 
549 
550 /*
551  * NFSv2 XDR encode functions
552  *
553  * NFSv2 argument types are defined in section 2.2 of RFC 1094:
554  * "NFS: Network File System Protocol Specification".
555  */
556 
557 static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
558  struct xdr_stream *xdr,
559  const struct nfs_fh *fh)
560 {
561  encode_fhandle(xdr, fh);
562 }
563 
564 /*
565  * 2.2.3. sattrargs
566  *
567  * struct sattrargs {
568  * fhandle file;
569  * sattr attributes;
570  * };
571  */
572 static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
573  struct xdr_stream *xdr,
574  const struct nfs_sattrargs *args)
575 {
576  encode_fhandle(xdr, args->fh);
577  encode_sattr(xdr, args->sattr);
578 }
579 
580 static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
581  struct xdr_stream *xdr,
582  const struct nfs_diropargs *args)
583 {
584  encode_diropargs(xdr, args->fh, args->name, args->len);
585 }
586 
587 static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
588  struct xdr_stream *xdr,
589  const struct nfs_readlinkargs *args)
590 {
591  encode_fhandle(xdr, args->fh);
592  prepare_reply_buffer(req, args->pages, args->pgbase,
593  args->pglen, NFS_readlinkres_sz);
594 }
595 
596 /*
597  * 2.2.7. readargs
598  *
599  * struct readargs {
600  * fhandle file;
601  * unsigned offset;
602  * unsigned count;
603  * unsigned totalcount;
604  * };
605  */
606 static void encode_readargs(struct xdr_stream *xdr,
607  const struct nfs_readargs *args)
608 {
609  u32 offset = args->offset;
610  u32 count = args->count;
611  __be32 *p;
612 
613  encode_fhandle(xdr, args->fh);
614 
615  p = xdr_reserve_space(xdr, 4 + 4 + 4);
616  *p++ = cpu_to_be32(offset);
617  *p++ = cpu_to_be32(count);
618  *p = cpu_to_be32(count);
619 }
620 
621 static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
622  struct xdr_stream *xdr,
623  const struct nfs_readargs *args)
624 {
625  encode_readargs(xdr, args);
626  prepare_reply_buffer(req, args->pages, args->pgbase,
627  args->count, NFS_readres_sz);
628  req->rq_rcv_buf.flags |= XDRBUF_READ;
629 }
630 
631 /*
632  * 2.2.9. writeargs
633  *
634  * struct writeargs {
635  * fhandle file;
636  * unsigned beginoffset;
637  * unsigned offset;
638  * unsigned totalcount;
639  * nfsdata data;
640  * };
641  */
642 static void encode_writeargs(struct xdr_stream *xdr,
643  const struct nfs_writeargs *args)
644 {
645  u32 offset = args->offset;
646  u32 count = args->count;
647  __be32 *p;
648 
649  encode_fhandle(xdr, args->fh);
650 
651  p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
652  *p++ = cpu_to_be32(offset);
653  *p++ = cpu_to_be32(offset);
654  *p++ = cpu_to_be32(count);
655 
656  /* nfsdata */
657  *p = cpu_to_be32(count);
658  xdr_write_pages(xdr, args->pages, args->pgbase, count);
659 }
660 
661 static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
662  struct xdr_stream *xdr,
663  const struct nfs_writeargs *args)
664 {
665  encode_writeargs(xdr, args);
666  xdr->buf->flags |= XDRBUF_WRITE;
667 }
668 
669 /*
670  * 2.2.10. createargs
671  *
672  * struct createargs {
673  * diropargs where;
674  * sattr attributes;
675  * };
676  */
677 static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
678  struct xdr_stream *xdr,
679  const struct nfs_createargs *args)
680 {
681  encode_diropargs(xdr, args->fh, args->name, args->len);
682  encode_sattr(xdr, args->sattr);
683 }
684 
685 static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
686  struct xdr_stream *xdr,
687  const struct nfs_removeargs *args)
688 {
689  encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
690 }
691 
692 /*
693  * 2.2.12. renameargs
694  *
695  * struct renameargs {
696  * diropargs from;
697  * diropargs to;
698  * };
699  */
700 static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
701  struct xdr_stream *xdr,
702  const struct nfs_renameargs *args)
703 {
704  const struct qstr *old = args->old_name;
705  const struct qstr *new = args->new_name;
706 
707  encode_diropargs(xdr, args->old_dir, old->name, old->len);
708  encode_diropargs(xdr, args->new_dir, new->name, new->len);
709 }
710 
711 /*
712  * 2.2.13. linkargs
713  *
714  * struct linkargs {
715  * fhandle from;
716  * diropargs to;
717  * };
718  */
719 static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
720  struct xdr_stream *xdr,
721  const struct nfs_linkargs *args)
722 {
723  encode_fhandle(xdr, args->fromfh);
724  encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
725 }
726 
727 /*
728  * 2.2.14. symlinkargs
729  *
730  * struct symlinkargs {
731  * diropargs from;
732  * path to;
733  * sattr attributes;
734  * };
735  */
736 static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
737  struct xdr_stream *xdr,
738  const struct nfs_symlinkargs *args)
739 {
740  encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
741  encode_path(xdr, args->pages, args->pathlen);
742  encode_sattr(xdr, args->sattr);
743 }
744 
745 /*
746  * 2.2.17. readdirargs
747  *
748  * struct readdirargs {
749  * fhandle dir;
750  * nfscookie cookie;
751  * unsigned count;
752  * };
753  */
754 static void encode_readdirargs(struct xdr_stream *xdr,
755  const struct nfs_readdirargs *args)
756 {
757  __be32 *p;
758 
759  encode_fhandle(xdr, args->fh);
760 
761  p = xdr_reserve_space(xdr, 4 + 4);
762  *p++ = cpu_to_be32(args->cookie);
763  *p = cpu_to_be32(args->count);
764 }
765 
766 static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
767  struct xdr_stream *xdr,
768  const struct nfs_readdirargs *args)
769 {
770  encode_readdirargs(xdr, args);
771  prepare_reply_buffer(req, args->pages, 0,
772  args->count, NFS_readdirres_sz);
773 }
774 
775 /*
776  * NFSv2 XDR decode functions
777  *
778  * NFSv2 result types are defined in section 2.2 of RFC 1094:
779  * "NFS: Network File System Protocol Specification".
780  */
781 
782 static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
783  void *__unused)
784 {
785  enum nfs_stat status;
786  int error;
787 
788  error = decode_stat(xdr, &status);
789  if (unlikely(error))
790  goto out;
791  if (status != NFS_OK)
792  goto out_default;
793 out:
794  return error;
795 out_default:
796  return nfs_stat_to_errno(status);
797 }
798 
799 static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
800  struct nfs_fattr *result)
801 {
802  return decode_attrstat(xdr, result);
803 }
804 
805 static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
806  struct nfs_diropok *result)
807 {
808  return decode_diropres(xdr, result);
809 }
810 
811 /*
812  * 2.2.6. readlinkres
813  *
814  * union readlinkres switch (stat status) {
815  * case NFS_OK:
816  * path data;
817  * default:
818  * void;
819  * };
820  */
821 static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
822  struct xdr_stream *xdr, void *__unused)
823 {
824  enum nfs_stat status;
825  int error;
826 
827  error = decode_stat(xdr, &status);
828  if (unlikely(error))
829  goto out;
830  if (status != NFS_OK)
831  goto out_default;
832  error = decode_path(xdr);
833 out:
834  return error;
835 out_default:
836  return nfs_stat_to_errno(status);
837 }
838 
839 /*
840  * 2.2.7. readres
841  *
842  * union readres switch (stat status) {
843  * case NFS_OK:
844  * fattr attributes;
845  * nfsdata data;
846  * default:
847  * void;
848  * };
849  */
850 static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
851  struct nfs_readres *result)
852 {
853  enum nfs_stat status;
854  int error;
855 
856  error = decode_stat(xdr, &status);
857  if (unlikely(error))
858  goto out;
859  if (status != NFS_OK)
860  goto out_default;
861  error = decode_fattr(xdr, result->fattr);
862  if (unlikely(error))
863  goto out;
864  error = decode_nfsdata(xdr, result);
865 out:
866  return error;
867 out_default:
868  return nfs_stat_to_errno(status);
869 }
870 
871 static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
872  struct nfs_writeres *result)
873 {
874  /* All NFSv2 writes are "file sync" writes */
875  result->verf->committed = NFS_FILE_SYNC;
876  return decode_attrstat(xdr, result->fattr);
877 }
878 
902 int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
903  int plus)
904 {
905  __be32 *p;
906  int error;
907 
908  p = xdr_inline_decode(xdr, 4);
909  if (unlikely(p == NULL))
910  goto out_overflow;
911  if (*p++ == xdr_zero) {
912  p = xdr_inline_decode(xdr, 4);
913  if (unlikely(p == NULL))
914  goto out_overflow;
915  if (*p++ == xdr_zero)
916  return -EAGAIN;
917  entry->eof = 1;
918  return -EBADCOOKIE;
919  }
920 
921  p = xdr_inline_decode(xdr, 4);
922  if (unlikely(p == NULL))
923  goto out_overflow;
924  entry->ino = be32_to_cpup(p);
925 
926  error = decode_filename_inline(xdr, &entry->name, &entry->len);
927  if (unlikely(error))
928  return error;
929 
930  /*
931  * The type (size and byte order) of nfscookie isn't defined in
932  * RFC 1094. This implementation assumes that it's an XDR uint32.
933  */
934  entry->prev_cookie = entry->cookie;
935  p = xdr_inline_decode(xdr, 4);
936  if (unlikely(p == NULL))
937  goto out_overflow;
938  entry->cookie = be32_to_cpup(p);
939 
940  entry->d_type = DT_UNKNOWN;
941 
942  return 0;
943 
944 out_overflow:
945  print_overflow_msg(__func__, xdr);
946  return -EAGAIN;
947 }
948 
949 /*
950  * 2.2.17. readdirres
951  *
952  * union readdirres switch (stat status) {
953  * case NFS_OK:
954  * struct {
955  * entry *entries;
956  * bool eof;
957  * } readdirok;
958  * default:
959  * void;
960  * };
961  *
962  * Read the directory contents into the page cache, but don't
963  * touch them. The actual decoding is done by nfs2_decode_dirent()
964  * during subsequent nfs_readdir() calls.
965  */
966 static int decode_readdirok(struct xdr_stream *xdr)
967 {
968  return xdr_read_pages(xdr, xdr->buf->page_len);
969 }
970 
971 static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
972  struct xdr_stream *xdr, void *__unused)
973 {
974  enum nfs_stat status;
975  int error;
976 
977  error = decode_stat(xdr, &status);
978  if (unlikely(error))
979  goto out;
980  if (status != NFS_OK)
981  goto out_default;
982  error = decode_readdirok(xdr);
983 out:
984  return error;
985 out_default:
986  return nfs_stat_to_errno(status);
987 }
988 
989 /*
990  * 2.2.18. statfsres
991  *
992  * union statfsres (stat status) {
993  * case NFS_OK:
994  * struct {
995  * unsigned tsize;
996  * unsigned bsize;
997  * unsigned blocks;
998  * unsigned bfree;
999  * unsigned bavail;
1000  * } info;
1001  * default:
1002  * void;
1003  * };
1004  */
1005 static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
1006 {
1007  __be32 *p;
1008 
1009  p = xdr_inline_decode(xdr, NFS_info_sz << 2);
1010  if (unlikely(p == NULL))
1011  goto out_overflow;
1012  result->tsize = be32_to_cpup(p++);
1013  result->bsize = be32_to_cpup(p++);
1014  result->blocks = be32_to_cpup(p++);
1015  result->bfree = be32_to_cpup(p++);
1016  result->bavail = be32_to_cpup(p);
1017  return 0;
1018 out_overflow:
1019  print_overflow_msg(__func__, xdr);
1020  return -EIO;
1021 }
1022 
1023 static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
1024  struct nfs2_fsstat *result)
1025 {
1026  enum nfs_stat status;
1027  int error;
1028 
1029  error = decode_stat(xdr, &status);
1030  if (unlikely(error))
1031  goto out;
1032  if (status != NFS_OK)
1033  goto out_default;
1034  error = decode_info(xdr, result);
1035 out:
1036  return error;
1037 out_default:
1038  return nfs_stat_to_errno(status);
1039 }
1040 
1041 
1042 /*
1043  * We need to translate between nfs status return values and
1044  * the local errno values which may not be the same.
1045  */
1046 static const struct {
1047  int stat;
1048  int errno;
1049 } nfs_errtbl[] = {
1050  { NFS_OK, 0 },
1051  { NFSERR_PERM, -EPERM },
1052  { NFSERR_NOENT, -ENOENT },
1054  { NFSERR_NXIO, -ENXIO },
1055 /* { NFSERR_EAGAIN, -EAGAIN }, */
1056  { NFSERR_ACCES, -EACCES },
1057  { NFSERR_EXIST, -EEXIST },
1058  { NFSERR_XDEV, -EXDEV },
1059  { NFSERR_NODEV, -ENODEV },
1060  { NFSERR_NOTDIR, -ENOTDIR },
1061  { NFSERR_ISDIR, -EISDIR },
1062  { NFSERR_INVAL, -EINVAL },
1063  { NFSERR_FBIG, -EFBIG },
1064  { NFSERR_NOSPC, -ENOSPC },
1065  { NFSERR_ROFS, -EROFS },
1066  { NFSERR_MLINK, -EMLINK },
1068  { NFSERR_NOTEMPTY, -ENOTEMPTY },
1069  { NFSERR_DQUOT, -EDQUOT },
1070  { NFSERR_STALE, -ESTALE },
1071  { NFSERR_REMOTE, -EREMOTE },
1072 #ifdef EWFLUSH
1073  { NFSERR_WFLUSH, -EWFLUSH },
1074 #endif
1076  { NFSERR_NOT_SYNC, -ENOTSYNC },
1078  { NFSERR_NOTSUPP, -ENOTSUPP },
1079  { NFSERR_TOOSMALL, -ETOOSMALL },
1081  { NFSERR_BADTYPE, -EBADTYPE },
1082  { NFSERR_JUKEBOX, -EJUKEBOX },
1083  { -1, -EIO }
1084 };
1085 
1093 static int nfs_stat_to_errno(enum nfs_stat status)
1094 {
1095  int i;
1096 
1097  for (i = 0; nfs_errtbl[i].stat != -1; i++) {
1098  if (nfs_errtbl[i].stat == (int)status)
1099  return nfs_errtbl[i].errno;
1100  }
1101  dprintk("NFS: Unrecognized nfs status value: %u\n", status);
1102  return nfs_errtbl[i].errno;
1103 }
1104 
1105 #define PROC(proc, argtype, restype, timer) \
1106 [NFSPROC_##proc] = { \
1107  .p_proc = NFSPROC_##proc, \
1108  .p_encode = (kxdreproc_t)nfs2_xdr_enc_##argtype, \
1109  .p_decode = (kxdrdproc_t)nfs2_xdr_dec_##restype, \
1110  .p_arglen = NFS_##argtype##_sz, \
1111  .p_replen = NFS_##restype##_sz, \
1112  .p_timer = timer, \
1113  .p_statidx = NFSPROC_##proc, \
1114  .p_name = #proc, \
1115  }
1117  PROC(GETATTR, fhandle, attrstat, 1),
1118  PROC(SETATTR, sattrargs, attrstat, 0),
1119  PROC(LOOKUP, diropargs, diropres, 2),
1120  PROC(READLINK, readlinkargs, readlinkres, 3),
1121  PROC(READ, readargs, readres, 3),
1122  PROC(WRITE, writeargs, writeres, 4),
1123  PROC(CREATE, createargs, diropres, 0),
1124  PROC(REMOVE, removeargs, stat, 0),
1125  PROC(RENAME, renameargs, stat, 0),
1126  PROC(LINK, linkargs, stat, 0),
1127  PROC(SYMLINK, symlinkargs, stat, 0),
1128  PROC(MKDIR, createargs, diropres, 0),
1129  PROC(RMDIR, diropargs, stat, 0),
1130  PROC(READDIR, readdirargs, readdirres, 3),
1131  PROC(STATFS, fhandle, statfsres, 0),
1132 };
1133 
1134 const struct rpc_version nfs_version2 = {
1135  .number = 2,
1136  .nrprocs = ARRAY_SIZE(nfs_procedures),
1137  .procs = nfs_procedures
1138 };