NFS: Use the "nfs_stat" enum for nfs_stat_to_errno()'s argument
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / nfs / nfs2xdr.c
blob2da9824d432adc3d8f082d861e4e2e0aaba89918
1 /*
2 * linux/fs/nfs/nfs2xdr.c
4 * XDR functions to encode/decode NFS RPC arguments and results.
6 * Copyright (C) 1992, 1993, 1994 Rick Sladkey
7 * Copyright (C) 1996 Olaf Kirch
8 * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu>
9 * FIFO's need special handling in NFSv2
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"
26 #define NFSDBG_FACILITY NFSDBG_XDR
28 /* Mapping from NFS error code to "errno" error code. */
29 #define errno_NFSERR_IO EIO
32 * Declare the space requirements for NFS arguments and replies as
33 * number of 32bit-words
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)
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)
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)
66 * While encoding arguments, set up the reply buffer in advance to
67 * receive reply data directly into the page cache.
69 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
70 unsigned int base, unsigned int len,
71 unsigned int bufsize)
73 struct rpc_auth *auth = req->rq_cred->cr_auth;
74 unsigned int replen;
76 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
77 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
82 * Common NFS XDR functions as inlines
84 static inline __be32 *
85 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
87 /* NFSv2 handles have a fixed length */
88 fhandle->size = NFS2_FHSIZE;
89 memcpy(fhandle->data, p, NFS2_FHSIZE);
90 return p + XDR_QUADLEN(NFS2_FHSIZE);
93 static inline __be32*
94 xdr_decode_time(__be32 *p, struct timespec *timep)
96 timep->tv_sec = ntohl(*p++);
97 /* Convert microseconds into nanoseconds */
98 timep->tv_nsec = ntohl(*p++) * 1000;
99 return p;
102 static __be32 *
103 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
105 u32 rdev, type;
106 type = ntohl(*p++);
107 fattr->mode = ntohl(*p++);
108 fattr->nlink = ntohl(*p++);
109 fattr->uid = ntohl(*p++);
110 fattr->gid = ntohl(*p++);
111 fattr->size = ntohl(*p++);
112 fattr->du.nfs2.blocksize = ntohl(*p++);
113 rdev = ntohl(*p++);
114 fattr->du.nfs2.blocks = ntohl(*p++);
115 fattr->fsid.major = ntohl(*p++);
116 fattr->fsid.minor = 0;
117 fattr->fileid = ntohl(*p++);
118 p = xdr_decode_time(p, &fattr->atime);
119 p = xdr_decode_time(p, &fattr->mtime);
120 p = xdr_decode_time(p, &fattr->ctime);
121 fattr->valid |= NFS_ATTR_FATTR_V2;
122 fattr->rdev = new_decode_dev(rdev);
123 if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
124 fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
125 fattr->rdev = 0;
127 return p;
131 * Encode/decode NFSv2 basic data types
133 * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
134 * "NFS: Network File System Protocol Specification".
136 * Not all basic data types have their own encoding and decoding
137 * functions. For run-time efficiency, some data types are encoded
138 * or decoded inline.
142 * 2.3.3. fhandle
144 * typedef opaque fhandle[FHSIZE];
146 static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
148 __be32 *p;
150 BUG_ON(fh->size != NFS2_FHSIZE);
151 p = xdr_reserve_space(xdr, NFS2_FHSIZE);
152 memcpy(p, fh->data, NFS2_FHSIZE);
156 * 2.3.4. timeval
158 * struct timeval {
159 * unsigned int seconds;
160 * unsigned int useconds;
161 * };
163 static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
165 *p++ = cpu_to_be32(timep->tv_sec);
166 if (timep->tv_nsec != 0)
167 *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
168 else
169 *p++ = cpu_to_be32(0);
170 return p;
174 * Passing the invalid value useconds=1000000 is a Sun convention for
175 * "set to current server time". It's needed to make permissions checks
176 * for the "touch" program across v2 mounts to Solaris and Irix servers
177 * work correctly. See description of sattr in section 6.1 of "NFS
178 * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
180 static __be32 *xdr_encode_current_server_time(__be32 *p,
181 const struct timespec *timep)
183 *p++ = cpu_to_be32(timep->tv_sec);
184 *p++ = cpu_to_be32(1000000);
185 return p;
189 * 2.3.6. sattr
191 * struct sattr {
192 * unsigned int mode;
193 * unsigned int uid;
194 * unsigned int gid;
195 * unsigned int size;
196 * timeval atime;
197 * timeval mtime;
198 * };
201 #define NFS2_SATTR_NOT_SET (0xffffffff)
203 static __be32 *xdr_time_not_set(__be32 *p)
205 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
206 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
207 return p;
210 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
212 __be32 *p;
214 p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
216 if (attr->ia_valid & ATTR_MODE)
217 *p++ = cpu_to_be32(attr->ia_mode);
218 else
219 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
220 if (attr->ia_valid & ATTR_UID)
221 *p++ = cpu_to_be32(attr->ia_uid);
222 else
223 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
224 if (attr->ia_valid & ATTR_GID)
225 *p++ = cpu_to_be32(attr->ia_gid);
226 else
227 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
228 if (attr->ia_valid & ATTR_SIZE)
229 *p++ = cpu_to_be32((u32)attr->ia_size);
230 else
231 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
233 if (attr->ia_valid & ATTR_ATIME_SET)
234 p = xdr_encode_time(p, &attr->ia_atime);
235 else if (attr->ia_valid & ATTR_ATIME)
236 p = xdr_encode_current_server_time(p, &attr->ia_atime);
237 else
238 p = xdr_time_not_set(p);
239 if (attr->ia_valid & ATTR_MTIME_SET)
240 xdr_encode_time(p, &attr->ia_mtime);
241 else if (attr->ia_valid & ATTR_MTIME)
242 xdr_encode_current_server_time(p, &attr->ia_mtime);
243 else
244 xdr_time_not_set(p);
248 * 2.3.7. filename
250 * typedef string filename<MAXNAMLEN>;
252 static void encode_filename(struct xdr_stream *xdr,
253 const char *name, u32 length)
255 __be32 *p;
257 BUG_ON(length > NFS2_MAXNAMLEN);
258 p = xdr_reserve_space(xdr, 4 + length);
259 xdr_encode_opaque(p, name, length);
263 * 2.3.8. path
265 * typedef string path<MAXPATHLEN>;
267 static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
269 __be32 *p;
271 BUG_ON(length > NFS2_MAXPATHLEN);
272 p = xdr_reserve_space(xdr, 4);
273 *p = cpu_to_be32(length);
274 xdr_write_pages(xdr, pages, 0, length);
278 * 2.3.10. diropargs
280 * struct diropargs {
281 * fhandle dir;
282 * filename name;
283 * };
285 static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
286 const char *name, u32 length)
288 encode_fhandle(xdr, fh);
289 encode_filename(xdr, name, length);
294 * NFSv2 XDR encode functions
296 * NFSv2 argument types are defined in section 2.2 of RFC 1094:
297 * "NFS: Network File System Protocol Specification".
300 static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
301 const struct nfs_fh *fh)
303 struct xdr_stream xdr;
305 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
306 encode_fhandle(&xdr, fh);
307 return 0;
311 * 2.2.3. sattrargs
313 * struct sattrargs {
314 * fhandle file;
315 * sattr attributes;
316 * };
318 static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
319 const struct nfs_sattrargs *args)
321 struct xdr_stream xdr;
323 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
324 encode_fhandle(&xdr, args->fh);
325 encode_sattr(&xdr, args->sattr);
326 return 0;
329 static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
330 const struct nfs_diropargs *args)
332 struct xdr_stream xdr;
334 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
335 encode_diropargs(&xdr, args->fh, args->name, args->len);
336 return 0;
339 static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
340 const struct nfs_readlinkargs *args)
342 struct xdr_stream xdr;
344 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
345 encode_fhandle(&xdr, args->fh);
346 prepare_reply_buffer(req, args->pages, args->pgbase,
347 args->pglen, NFS_readlinkres_sz);
348 return 0;
352 * 2.2.7. readargs
354 * struct readargs {
355 * fhandle file;
356 * unsigned offset;
357 * unsigned count;
358 * unsigned totalcount;
359 * };
361 static void encode_readargs(struct xdr_stream *xdr,
362 const struct nfs_readargs *args)
364 u32 offset = args->offset;
365 u32 count = args->count;
366 __be32 *p;
368 encode_fhandle(xdr, args->fh);
370 p = xdr_reserve_space(xdr, 4 + 4 + 4);
371 *p++ = cpu_to_be32(offset);
372 *p++ = cpu_to_be32(count);
373 *p = cpu_to_be32(count);
376 static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
377 const struct nfs_readargs *args)
379 struct xdr_stream xdr;
381 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
382 encode_readargs(&xdr, args);
383 prepare_reply_buffer(req, args->pages, args->pgbase,
384 args->count, NFS_readres_sz);
385 req->rq_rcv_buf.flags |= XDRBUF_READ;
386 return 0;
390 * Decode READ reply
392 static int
393 nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
395 struct kvec *iov = req->rq_rcv_buf.head;
396 size_t hdrlen;
397 u32 count, recvd;
398 int status;
400 if ((status = ntohl(*p++)))
401 return nfs_stat_to_errno(status);
402 p = xdr_decode_fattr(p, res->fattr);
404 count = ntohl(*p++);
405 res->eof = 0;
406 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
407 if (iov->iov_len < hdrlen) {
408 dprintk("NFS: READ reply header overflowed:"
409 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
410 return -errno_NFSERR_IO;
411 } else if (iov->iov_len != hdrlen) {
412 dprintk("NFS: READ header is short. iovec will be shifted.\n");
413 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
416 recvd = req->rq_rcv_buf.len - hdrlen;
417 if (count > recvd) {
418 dprintk("NFS: server cheating in read reply: "
419 "count %u > recvd %u\n", count, recvd);
420 count = recvd;
423 dprintk("RPC: readres OK count %u\n", count);
424 if (count < res->count)
425 res->count = count;
427 return count;
432 * 2.2.9. writeargs
434 * struct writeargs {
435 * fhandle file;
436 * unsigned beginoffset;
437 * unsigned offset;
438 * unsigned totalcount;
439 * nfsdata data;
440 * };
442 static void encode_writeargs(struct xdr_stream *xdr,
443 const struct nfs_writeargs *args)
445 u32 offset = args->offset;
446 u32 count = args->count;
447 __be32 *p;
449 encode_fhandle(xdr, args->fh);
451 p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
452 *p++ = cpu_to_be32(offset);
453 *p++ = cpu_to_be32(offset);
454 *p++ = cpu_to_be32(count);
456 /* nfsdata */
457 *p = cpu_to_be32(count);
458 xdr_write_pages(xdr, args->pages, args->pgbase, count);
461 static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
462 const struct nfs_writeargs *args)
464 struct xdr_stream xdr;
466 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
467 encode_writeargs(&xdr, args);
468 xdr.buf->flags |= XDRBUF_WRITE;
469 return 0;
473 * 2.2.10. createargs
475 * struct createargs {
476 * diropargs where;
477 * sattr attributes;
478 * };
480 static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
481 const struct nfs_createargs *args)
483 struct xdr_stream xdr;
485 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
486 encode_diropargs(&xdr, args->fh, args->name, args->len);
487 encode_sattr(&xdr, args->sattr);
488 return 0;
491 static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
492 const struct nfs_removeargs *args)
494 struct xdr_stream xdr;
496 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
497 encode_diropargs(&xdr, args->fh, args->name.name, args->name.len);
498 return 0;
502 * 2.2.12. renameargs
504 * struct renameargs {
505 * diropargs from;
506 * diropargs to;
507 * };
509 static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
510 const struct nfs_renameargs *args)
512 const struct qstr *old = args->old_name;
513 const struct qstr *new = args->new_name;
514 struct xdr_stream xdr;
516 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
517 encode_diropargs(&xdr, args->old_dir, old->name, old->len);
518 encode_diropargs(&xdr, args->new_dir, new->name, new->len);
519 return 0;
523 * 2.2.13. linkargs
525 * struct linkargs {
526 * fhandle from;
527 * diropargs to;
528 * };
530 static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
531 const struct nfs_linkargs *args)
533 struct xdr_stream xdr;
535 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
536 encode_fhandle(&xdr, args->fromfh);
537 encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
538 return 0;
542 * 2.2.14. symlinkargs
544 * struct symlinkargs {
545 * diropargs from;
546 * path to;
547 * sattr attributes;
548 * };
550 static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
551 const struct nfs_symlinkargs *args)
553 struct xdr_stream xdr;
555 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
556 encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
557 encode_path(&xdr, args->pages, args->pathlen);
558 encode_sattr(&xdr, args->sattr);
559 return 0;
563 * 2.2.17. readdirargs
565 * struct readdirargs {
566 * fhandle dir;
567 * nfscookie cookie;
568 * unsigned count;
569 * };
571 static void encode_readdirargs(struct xdr_stream *xdr,
572 const struct nfs_readdirargs *args)
574 __be32 *p;
576 encode_fhandle(xdr, args->fh);
578 p = xdr_reserve_space(xdr, 4 + 4);
579 *p++ = cpu_to_be32(args->cookie);
580 *p = cpu_to_be32(args->count);
583 static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
584 const struct nfs_readdirargs *args)
586 struct xdr_stream xdr;
588 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
589 encode_readdirargs(&xdr, args);
590 prepare_reply_buffer(req, args->pages, 0,
591 args->count, NFS_readdirres_sz);
592 return 0;
596 * Decode the result of a readdir call.
597 * We're not really decoding anymore, we just leave the buffer untouched
598 * and only check that it is syntactically correct.
599 * The real decoding happens in nfs_decode_entry below, called directly
600 * from nfs_readdir for each entry.
602 static int
603 nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
605 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
606 struct kvec *iov = rcvbuf->head;
607 struct page **page;
608 size_t hdrlen;
609 unsigned int pglen, recvd;
610 int status;
612 if ((status = ntohl(*p++)))
613 return nfs_stat_to_errno(status);
615 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
616 if (iov->iov_len < hdrlen) {
617 dprintk("NFS: READDIR reply header overflowed:"
618 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
619 return -errno_NFSERR_IO;
620 } else if (iov->iov_len != hdrlen) {
621 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
622 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
625 pglen = rcvbuf->page_len;
626 recvd = rcvbuf->len - hdrlen;
627 if (pglen > recvd)
628 pglen = recvd;
629 page = rcvbuf->pages;
630 return pglen;
633 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
635 dprintk("nfs: %s: prematurely hit end of receive buffer. "
636 "Remaining buffer length is %tu words.\n",
637 func, xdr->end - xdr->p);
640 __be32 *
641 nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
643 __be32 *p;
644 p = xdr_inline_decode(xdr, 4);
645 if (unlikely(!p))
646 goto out_overflow;
647 if (!ntohl(*p++)) {
648 p = xdr_inline_decode(xdr, 4);
649 if (unlikely(!p))
650 goto out_overflow;
651 if (!ntohl(*p++))
652 return ERR_PTR(-EAGAIN);
653 entry->eof = 1;
654 return ERR_PTR(-EBADCOOKIE);
657 p = xdr_inline_decode(xdr, 8);
658 if (unlikely(!p))
659 goto out_overflow;
661 entry->ino = ntohl(*p++);
662 entry->len = ntohl(*p++);
664 p = xdr_inline_decode(xdr, entry->len + 4);
665 if (unlikely(!p))
666 goto out_overflow;
667 entry->name = (const char *) p;
668 p += XDR_QUADLEN(entry->len);
669 entry->prev_cookie = entry->cookie;
670 entry->cookie = ntohl(*p++);
672 entry->d_type = DT_UNKNOWN;
674 p = xdr_inline_peek(xdr, 8);
675 if (p != NULL)
676 entry->eof = !p[0] && p[1];
677 else
678 entry->eof = 0;
680 return p;
682 out_overflow:
683 print_overflow_msg(__func__, xdr);
684 return ERR_PTR(-EAGAIN);
688 * NFS XDR decode functions
691 * Decode simple status reply
693 static int
694 nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
696 int status;
698 if ((status = ntohl(*p++)) != 0)
699 status = nfs_stat_to_errno(status);
700 return status;
704 * Decode attrstat reply
705 * GETATTR, SETATTR, WRITE
707 static int
708 nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
710 int status;
712 if ((status = ntohl(*p++)))
713 return nfs_stat_to_errno(status);
714 xdr_decode_fattr(p, fattr);
715 return 0;
719 * Decode diropres reply
720 * LOOKUP, CREATE, MKDIR
722 static int
723 nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
725 int status;
727 if ((status = ntohl(*p++)))
728 return nfs_stat_to_errno(status);
729 p = xdr_decode_fhandle(p, res->fh);
730 xdr_decode_fattr(p, res->fattr);
731 return 0;
735 * Decode READLINK reply
737 static int
738 nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
740 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
741 struct kvec *iov = rcvbuf->head;
742 size_t hdrlen;
743 u32 len, recvd;
744 int status;
746 if ((status = ntohl(*p++)))
747 return nfs_stat_to_errno(status);
748 /* Convert length of symlink */
749 len = ntohl(*p++);
750 if (len >= rcvbuf->page_len) {
751 dprintk("nfs: server returned giant symlink!\n");
752 return -ENAMETOOLONG;
754 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
755 if (iov->iov_len < hdrlen) {
756 dprintk("NFS: READLINK reply header overflowed:"
757 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
758 return -errno_NFSERR_IO;
759 } else if (iov->iov_len != hdrlen) {
760 dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
761 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
763 recvd = req->rq_rcv_buf.len - hdrlen;
764 if (recvd < len) {
765 dprintk("NFS: server cheating in readlink reply: "
766 "count %u > recvd %u\n", len, recvd);
767 return -EIO;
770 xdr_terminate_string(rcvbuf, len);
771 return 0;
775 * Decode WRITE reply
777 static int
778 nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
780 res->verf->committed = NFS_FILE_SYNC;
781 return nfs_xdr_attrstat(req, p, res->fattr);
785 * Decode STATFS reply
787 static int
788 nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
790 int status;
792 if ((status = ntohl(*p++)))
793 return nfs_stat_to_errno(status);
795 res->tsize = ntohl(*p++);
796 res->bsize = ntohl(*p++);
797 res->blocks = ntohl(*p++);
798 res->bfree = ntohl(*p++);
799 res->bavail = ntohl(*p++);
800 return 0;
804 * We need to translate between nfs status return values and
805 * the local errno values which may not be the same.
807 static const struct {
808 int stat;
809 int errno;
810 } nfs_errtbl[] = {
811 { NFS_OK, 0 },
812 { NFSERR_PERM, -EPERM },
813 { NFSERR_NOENT, -ENOENT },
814 { NFSERR_IO, -errno_NFSERR_IO},
815 { NFSERR_NXIO, -ENXIO },
816 /* { NFSERR_EAGAIN, -EAGAIN }, */
817 { NFSERR_ACCES, -EACCES },
818 { NFSERR_EXIST, -EEXIST },
819 { NFSERR_XDEV, -EXDEV },
820 { NFSERR_NODEV, -ENODEV },
821 { NFSERR_NOTDIR, -ENOTDIR },
822 { NFSERR_ISDIR, -EISDIR },
823 { NFSERR_INVAL, -EINVAL },
824 { NFSERR_FBIG, -EFBIG },
825 { NFSERR_NOSPC, -ENOSPC },
826 { NFSERR_ROFS, -EROFS },
827 { NFSERR_MLINK, -EMLINK },
828 { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
829 { NFSERR_NOTEMPTY, -ENOTEMPTY },
830 { NFSERR_DQUOT, -EDQUOT },
831 { NFSERR_STALE, -ESTALE },
832 { NFSERR_REMOTE, -EREMOTE },
833 #ifdef EWFLUSH
834 { NFSERR_WFLUSH, -EWFLUSH },
835 #endif
836 { NFSERR_BADHANDLE, -EBADHANDLE },
837 { NFSERR_NOT_SYNC, -ENOTSYNC },
838 { NFSERR_BAD_COOKIE, -EBADCOOKIE },
839 { NFSERR_NOTSUPP, -ENOTSUPP },
840 { NFSERR_TOOSMALL, -ETOOSMALL },
841 { NFSERR_SERVERFAULT, -EREMOTEIO },
842 { NFSERR_BADTYPE, -EBADTYPE },
843 { NFSERR_JUKEBOX, -EJUKEBOX },
844 { -1, -EIO }
848 * nfs_stat_to_errno - convert an NFS status code to a local errno
849 * @status: NFS status code to convert
851 * Returns a local errno value, or -EIO if the NFS status code is
852 * not recognized. This function is used jointly by NFSv2 and NFSv3.
854 int nfs_stat_to_errno(enum nfs_stat status)
856 int i;
858 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
859 if (nfs_errtbl[i].stat == (int)status)
860 return nfs_errtbl[i].errno;
862 dprintk("NFS: Unrecognized nfs status value: %u\n", status);
863 return nfs_errtbl[i].errno;
866 #define PROC(proc, argtype, restype, timer) \
867 [NFSPROC_##proc] = { \
868 .p_proc = NFSPROC_##proc, \
869 .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \
870 .p_decode = (kxdrproc_t) nfs_xdr_##restype, \
871 .p_arglen = NFS_##argtype##_sz, \
872 .p_replen = NFS_##restype##_sz, \
873 .p_timer = timer, \
874 .p_statidx = NFSPROC_##proc, \
875 .p_name = #proc, \
877 struct rpc_procinfo nfs_procedures[] = {
878 PROC(GETATTR, fhandle, attrstat, 1),
879 PROC(SETATTR, sattrargs, attrstat, 0),
880 PROC(LOOKUP, diropargs, diropres, 2),
881 PROC(READLINK, readlinkargs, readlinkres, 3),
882 PROC(READ, readargs, readres, 3),
883 PROC(WRITE, writeargs, writeres, 4),
884 PROC(CREATE, createargs, diropres, 0),
885 PROC(REMOVE, removeargs, stat, 0),
886 PROC(RENAME, renameargs, stat, 0),
887 PROC(LINK, linkargs, stat, 0),
888 PROC(SYMLINK, symlinkargs, stat, 0),
889 PROC(MKDIR, createargs, diropres, 0),
890 PROC(RMDIR, diropargs, stat, 0),
891 PROC(READDIR, readdirargs, readdirres, 3),
892 PROC(STATFS, fhandle, statfsres, 0),
895 struct rpc_version nfs_version2 = {
896 .number = 2,
897 .nrprocs = ARRAY_SIZE(nfs_procedures),
898 .procs = nfs_procedures