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>
15 #include <linux/errno.h>
16 #include <linux/string.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>
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
,
73 struct rpc_auth
*auth
= req
->rq_cred
->cr_auth
;
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
);
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;
103 xdr_decode_fattr(__be32
*p
, struct nfs_fattr
*fattr
)
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
++);
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
;
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
144 * typedef opaque fhandle[FHSIZE];
146 static void encode_fhandle(struct xdr_stream
*xdr
, const struct nfs_fh
*fh
)
150 BUG_ON(fh
->size
!= NFS2_FHSIZE
);
151 p
= xdr_reserve_space(xdr
, NFS2_FHSIZE
);
152 memcpy(p
, fh
->data
, NFS2_FHSIZE
);
159 * unsigned int seconds;
160 * unsigned int useconds;
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
);
169 *p
++ = cpu_to_be32(0);
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);
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
);
210 static void encode_sattr(struct xdr_stream
*xdr
, const struct iattr
*attr
)
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
);
219 *p
++ = cpu_to_be32(NFS2_SATTR_NOT_SET
);
220 if (attr
->ia_valid
& ATTR_UID
)
221 *p
++ = cpu_to_be32(attr
->ia_uid
);
223 *p
++ = cpu_to_be32(NFS2_SATTR_NOT_SET
);
224 if (attr
->ia_valid
& ATTR_GID
)
225 *p
++ = cpu_to_be32(attr
->ia_gid
);
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
);
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
);
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
);
250 * typedef string filename<MAXNAMLEN>;
252 static void encode_filename(struct xdr_stream
*xdr
,
253 const char *name
, u32 length
)
257 BUG_ON(length
> NFS2_MAXNAMLEN
);
258 p
= xdr_reserve_space(xdr
, 4 + length
);
259 xdr_encode_opaque(p
, name
, length
);
265 * typedef string path<MAXPATHLEN>;
267 static void encode_path(struct xdr_stream
*xdr
, struct page
**pages
, u32 length
)
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
);
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
);
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
);
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
);
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
);
358 * unsigned totalcount;
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
;
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
;
393 nfs_xdr_readres(struct rpc_rqst
*req
, __be32
*p
, struct nfs_readres
*res
)
395 struct kvec
*iov
= req
->rq_rcv_buf
.head
;
400 if ((status
= ntohl(*p
++)))
401 return nfs_stat_to_errno(status
);
402 p
= xdr_decode_fattr(p
, res
->fattr
);
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
;
418 dprintk("NFS: server cheating in read reply: "
419 "count %u > recvd %u\n", count
, recvd
);
423 dprintk("RPC: readres OK count %u\n", count
);
424 if (count
< res
->count
)
436 * unsigned beginoffset;
438 * unsigned totalcount;
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
;
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
);
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
;
475 * struct createargs {
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
);
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
);
504 * struct renameargs {
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
);
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
);
542 * 2.2.14. symlinkargs
544 * struct symlinkargs {
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
);
563 * 2.2.17. readdirargs
565 * struct readdirargs {
571 static void encode_readdirargs(struct xdr_stream
*xdr
,
572 const struct nfs_readdirargs
*args
)
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
);
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.
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
;
609 unsigned int pglen
, recvd
;
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
;
629 page
= rcvbuf
->pages
;
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
);
641 nfs_decode_dirent(struct xdr_stream
*xdr
, struct nfs_entry
*entry
, struct nfs_server
*server
, int plus
)
644 p
= xdr_inline_decode(xdr
, 4);
648 p
= xdr_inline_decode(xdr
, 4);
652 return ERR_PTR(-EAGAIN
);
654 return ERR_PTR(-EBADCOOKIE
);
657 p
= xdr_inline_decode(xdr
, 8);
661 entry
->ino
= ntohl(*p
++);
662 entry
->len
= ntohl(*p
++);
664 p
= xdr_inline_decode(xdr
, entry
->len
+ 4);
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);
676 entry
->eof
= !p
[0] && p
[1];
683 print_overflow_msg(__func__
, xdr
);
684 return ERR_PTR(-EAGAIN
);
688 * NFS XDR decode functions
691 * Decode simple status reply
694 nfs_xdr_stat(struct rpc_rqst
*req
, __be32
*p
, void *dummy
)
698 if ((status
= ntohl(*p
++)) != 0)
699 status
= nfs_stat_to_errno(status
);
704 * Decode attrstat reply
705 * GETATTR, SETATTR, WRITE
708 nfs_xdr_attrstat(struct rpc_rqst
*req
, __be32
*p
, struct nfs_fattr
*fattr
)
712 if ((status
= ntohl(*p
++)))
713 return nfs_stat_to_errno(status
);
714 xdr_decode_fattr(p
, fattr
);
719 * Decode diropres reply
720 * LOOKUP, CREATE, MKDIR
723 nfs_xdr_diropres(struct rpc_rqst
*req
, __be32
*p
, struct nfs_diropok
*res
)
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
);
735 * Decode READLINK reply
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
;
746 if ((status
= ntohl(*p
++)))
747 return nfs_stat_to_errno(status
);
748 /* Convert length of symlink */
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
;
765 dprintk("NFS: server cheating in readlink reply: "
766 "count %u > recvd %u\n", len
, recvd
);
770 xdr_terminate_string(rcvbuf
, len
);
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
788 nfs_xdr_statfsres(struct rpc_rqst
*req
, __be32
*p
, struct nfs2_fsstat
*res
)
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
++);
804 * We need to translate between nfs status return values and
805 * the local errno values which may not be the same.
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
},
834 { NFSERR_WFLUSH
, -EWFLUSH
},
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
},
848 * Convert an NFS error code to a local one.
849 * This one is used jointly by NFSv2 and NFSv3.
852 nfs_stat_to_errno(int stat
)
856 for (i
= 0; nfs_errtbl
[i
].stat
!= -1; i
++) {
857 if (nfs_errtbl
[i
].stat
== stat
)
858 return nfs_errtbl
[i
].errno
;
860 dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat
);
861 return nfs_errtbl
[i
].errno
;
864 #define PROC(proc, argtype, restype, timer) \
865 [NFSPROC_##proc] = { \
866 .p_proc = NFSPROC_##proc, \
867 .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \
868 .p_decode = (kxdrproc_t) nfs_xdr_##restype, \
869 .p_arglen = NFS_##argtype##_sz, \
870 .p_replen = NFS_##restype##_sz, \
872 .p_statidx = NFSPROC_##proc, \
875 struct rpc_procinfo nfs_procedures
[] = {
876 PROC(GETATTR
, fhandle
, attrstat
, 1),
877 PROC(SETATTR
, sattrargs
, attrstat
, 0),
878 PROC(LOOKUP
, diropargs
, diropres
, 2),
879 PROC(READLINK
, readlinkargs
, readlinkres
, 3),
880 PROC(READ
, readargs
, readres
, 3),
881 PROC(WRITE
, writeargs
, writeres
, 4),
882 PROC(CREATE
, createargs
, diropres
, 0),
883 PROC(REMOVE
, removeargs
, stat
, 0),
884 PROC(RENAME
, renameargs
, stat
, 0),
885 PROC(LINK
, linkargs
, stat
, 0),
886 PROC(SYMLINK
, symlinkargs
, stat
, 0),
887 PROC(MKDIR
, createargs
, diropres
, 0),
888 PROC(RMDIR
, diropargs
, stat
, 0),
889 PROC(READDIR
, readdirargs
, readdirres
, 3),
890 PROC(STATFS
, fhandle
, statfsres
, 0),
893 struct rpc_version nfs_version2
= {
895 .nrprocs
= ARRAY_SIZE(nfs_procedures
),
896 .procs
= nfs_procedures