fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / nfs / nfs2xdr.c
index 7fc0560..3be4e72 100644 (file)
 #include <linux/nfs.h>
 #include <linux/nfs2.h>
 #include <linux/nfs_fs.h>
+#include "internal.h"
 
 #define NFSDBG_FACILITY                NFSDBG_XDR
 /* #define NFS_PARANOIA 1 */
 
-extern int                     nfs_stat_to_errno(int stat);
-
 /* Mapping from NFS error code to "errno" error code. */
 #define errno_NFSERR_IO                EIO
 
@@ -52,7 +51,7 @@ extern int                    nfs_stat_to_errno(int stat);
 #define NFS_createargs_sz      (NFS_diropargs_sz+NFS_sattr_sz)
 #define NFS_renameargs_sz      (NFS_diropargs_sz+NFS_diropargs_sz)
 #define NFS_linkargs_sz                (NFS_fhandle_sz+NFS_diropargs_sz)
-#define NFS_symlinkargs_sz     (NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz)
+#define NFS_symlinkargs_sz     (NFS_diropargs_sz+1+NFS_sattr_sz)
 #define NFS_readdirargs_sz     (NFS_fhandle_sz+2)
 
 #define NFS_attrstat_sz                (1+NFS_fattr_sz)
@@ -67,15 +66,15 @@ extern int                  nfs_stat_to_errno(int stat);
 /*
  * Common NFS XDR functions as inlines
  */
-static inline u32 *
-xdr_encode_fhandle(u32 *p, struct nfs_fh *fhandle)
+static inline __be32 *
+xdr_encode_fhandle(__be32 *p, struct nfs_fh *fhandle)
 {
        memcpy(p, fhandle->data, NFS2_FHSIZE);
        return p + XDR_QUADLEN(NFS2_FHSIZE);
 }
 
-static inline u32 *
-xdr_decode_fhandle(u32 *p, struct nfs_fh *fhandle)
+static inline __be32 *
+xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
 {
        /* NFSv2 handles have a fixed length */
        fhandle->size = NFS2_FHSIZE;
@@ -83,8 +82,8 @@ xdr_decode_fhandle(u32 *p, struct nfs_fh *fhandle)
        return p + XDR_QUADLEN(NFS2_FHSIZE);
 }
 
-static inline u32*
-xdr_encode_time(u32 *p, struct timespec *timep)
+static inline __be32*
+xdr_encode_time(__be32 *p, struct timespec *timep)
 {
        *p++ = htonl(timep->tv_sec);
        /* Convert nanoseconds into microseconds */
@@ -92,8 +91,8 @@ xdr_encode_time(u32 *p, struct timespec *timep)
        return p;
 }
 
-static inline u32*
-xdr_encode_current_server_time(u32 *p, struct timespec *timep)
+static inline __be32*
+xdr_encode_current_server_time(__be32 *p, struct timespec *timep)
 {
        /*
         * Passing the invalid value useconds=1000000 is a
@@ -109,8 +108,8 @@ xdr_encode_current_server_time(u32 *p, struct timespec *timep)
        return p;
 }
 
-static inline u32*
-xdr_decode_time(u32 *p, struct timespec *timep)
+static inline __be32*
+xdr_decode_time(__be32 *p, struct timespec *timep)
 {
        timep->tv_sec = ntohl(*p++);
        /* Convert microseconds into nanoseconds */
@@ -118,8 +117,8 @@ xdr_decode_time(u32 *p, struct timespec *timep)
        return p;
 }
 
-static u32 *
-xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
+static __be32 *
+xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
 {
        u32 rdev;
        fattr->type = (enum nfs_ftype) ntohl(*p++);
@@ -131,7 +130,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
        fattr->du.nfs2.blocksize = ntohl(*p++);
        rdev = ntohl(*p++);
        fattr->du.nfs2.blocks = ntohl(*p++);
-       fattr->fsid_u.nfs3 = ntohl(*p++);
+       fattr->fsid.major = ntohl(*p++);
+       fattr->fsid.minor = 0;
        fattr->fileid = ntohl(*p++);
        p = xdr_decode_time(p, &fattr->atime);
        p = xdr_decode_time(p, &fattr->mtime);
@@ -146,10 +146,10 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
        return p;
 }
 
-static inline u32 *
-xdr_encode_sattr(u32 *p, struct iattr *attr)
+static inline __be32 *
+xdr_encode_sattr(__be32 *p, struct iattr *attr)
 {
-       const u32 not_set = __constant_htonl(0xFFFFFFFF);
+       const __be32 not_set = __constant_htonl(0xFFFFFFFF);
 
        *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
        *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
@@ -184,7 +184,7 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
  * GETATTR, READLINK, STATFS
  */
 static int
-nfs_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
+nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
 {
        p = xdr_encode_fhandle(p, fh);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
@@ -195,7 +195,7 @@ nfs_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
  * Encode SETATTR arguments
  */
 static int
-nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args)
+nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_sattr(p, args->sattr);
@@ -208,7 +208,7 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args)
  * LOOKUP, REMOVE, RMDIR
  */
 static int
-nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args)
+nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -222,7 +222,7 @@ nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args)
  * exactly to the page we want to fetch.
  */
 static int
-nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
+nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -246,7 +246,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
  * Decode READ reply
  */
 static int
-nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
+nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
 {
        struct kvec *iov = req->rq_rcv_buf.head;
        int     status, count, recvd, hdrlen;
@@ -286,7 +286,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
  * Write arguments. Splice the buffer to be written into the iovec.
  */
 static int
-nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
+nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 {
        struct xdr_buf *sndbuf = &req->rq_snd_buf;
        u32 offset = (u32)args->offset;
@@ -309,7 +309,7 @@ nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
  * CREATE, MKDIR
  */
 static int
-nfs_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs_createargs *args)
+nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -322,7 +322,7 @@ nfs_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs_createargs *args)
  * Encode RENAME arguments
  */
 static int
-nfs_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs_renameargs *args)
+nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
@@ -336,7 +336,7 @@ nfs_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs_renameargs *args)
  * Encode LINK arguments
  */
 static int
-nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args)
+nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_fhandle(p, args->tofh);
@@ -349,13 +349,28 @@ nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args)
  * Encode SYMLINK arguments
  */
 static int
-nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
+nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args)
 {
+       struct xdr_buf *sndbuf = &req->rq_snd_buf;
+       size_t pad;
+
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
-       p = xdr_encode_array(p, args->topath, args->tolen);
+       *p++ = htonl(args->pathlen);
+       sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
+
+       xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen);
+
+       /*
+        * xdr_encode_pages may have added a few bytes to ensure the
+        * pathname ends on a 4-byte boundary.  Start encoding the
+        * attributes after the pad bytes.
+        */
+       pad = sndbuf->tail->iov_len;
+       if (pad > 0)
+               p++;
        p = xdr_encode_sattr(p, args->sattr);
-       req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+       sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad;
        return 0;
 }
 
@@ -363,7 +378,7 @@ nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
  * Encode arguments to readdir call
  */
 static int
-nfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args)
+nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
 {
        struct rpc_task *task = req->rq_task;
        struct rpc_auth *auth = task->tk_auth;
@@ -389,7 +404,7 @@ nfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args)
  * from nfs_readdir for each entry.
  */
 static int
-nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
+nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
@@ -397,7 +412,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
        int hdrlen, recvd;
        int status, nr;
        unsigned int len, pglen;
-       u32 *end, *entry, *kaddr;
+       __be32 *end, *entry, *kaddr;
 
        if ((status = ntohl(*p++)))
                return -nfs_stat_to_errno(status);
@@ -417,8 +432,8 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
        if (pglen > recvd)
                pglen = recvd;
        page = rcvbuf->pages;
-       kaddr = p = (u32 *)kmap_atomic(*page, KM_USER0);
-       end = (u32 *)((char *)p + pglen);
+       kaddr = p = kmap_atomic(*page, KM_USER0);
+       end = (__be32 *)((char *)p + pglen);
        entry = p;
        for (nr = 0; *p++; nr++) {
                if (p + 2 > end)
@@ -453,8 +468,8 @@ err_unmap:
        goto out;
 }
 
-u32 *
-nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
+__be32 *
+nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
 {
        if (!*p++) {
                if (!*p)
@@ -481,7 +496,7 @@ nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
  * Decode simple status reply
  */
 static int
-nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy)
+nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
 {
        int     status;
 
@@ -495,7 +510,7 @@ nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy)
  * GETATTR, SETATTR, WRITE
  */
 static int
-nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 {
        int     status;
 
@@ -510,7 +525,7 @@ nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
  * LOOKUP, CREATE, MKDIR
  */
 static int
-nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
+nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
 {
        int     status;
 
@@ -525,7 +540,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
  * Encode READLINK args
  */
 static int
-nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args)
+nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -543,7 +558,7 @@ nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args
  * Decode READLINK reply
  */
 static int
-nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy)
+nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
@@ -586,7 +601,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy)
  * Decode WRITE reply
  */
 static int
-nfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
+nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
 {
        res->verf->committed = NFS_FILE_SYNC;
        return nfs_xdr_attrstat(req, p, res->fattr);
@@ -596,7 +611,7 @@ nfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
  * Decode STATFS reply
  */
 static int
-nfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs2_fsstat *res)
+nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
 {
        int     status;
 
@@ -682,7 +697,9 @@ nfs_stat_to_errno(int stat)
        .p_encode   =  (kxdrproc_t) nfs_xdr_##argtype,                  \
        .p_decode   =  (kxdrproc_t) nfs_xdr_##restype,                  \
        .p_bufsiz   =  MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2, \
-       .p_timer    =  timer                                            \
+       .p_timer    =  timer,                                           \
+       .p_statidx  =  NFSPROC_##proc,                                  \
+       .p_name     =  #proc,                                           \
        }
 struct rpc_procinfo    nfs_procedures[] = {
     PROC(GETATTR,      fhandle,        attrstat, 1),
@@ -704,6 +721,6 @@ struct rpc_procinfo nfs_procedures[] = {
 
 struct rpc_version             nfs_version2 = {
        .number                 = 2,
-       .nrprocs                = sizeof(nfs_procedures)/sizeof(nfs_procedures[0]),
+       .nrprocs                = ARRAY_SIZE(nfs_procedures),
        .procs                  = nfs_procedures
 };