VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / nfs / nfs3xdr.c
index 98de023..ebfc607 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
+#include <linux/vserver/xid.h>
 
 #define NFSDBG_FACILITY                NFSDBG_XDR
 
@@ -177,7 +178,7 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
 }
 
 static inline u32 *
-xdr_encode_sattr(u32 *p, struct iattr *attr)
+xdr_encode_sattr(u32 *p, struct iattr *attr, int tagxid)
 {
        if (attr->ia_valid & ATTR_MODE) {
                *p++ = xdr_one;
@@ -185,15 +186,17 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
        } else {
                *p++ = xdr_zero;
        }
-       if (attr->ia_valid & ATTR_UID) {
+       if (attr->ia_valid & ATTR_UID ||
+               (tagxid && (attr->ia_valid & ATTR_XID))) {
                *p++ = xdr_one;
-               *p++ = htonl(attr->ia_uid);
+               *p++ = htonl(XIDINO_UID(tagxid, attr->ia_uid, attr->ia_xid));
        } else {
                *p++ = xdr_zero;
        }
-       if (attr->ia_valid & ATTR_GID) {
+       if (attr->ia_valid & ATTR_GID ||
+               (tagxid && (attr->ia_valid & ATTR_XID))) {
                *p++ = xdr_one;
-               *p++ = htonl(attr->ia_gid);
+               *p++ = htonl(XIDINO_GID(tagxid, attr->ia_gid, attr->ia_xid));
        } else {
                *p++ = xdr_zero;
        }
@@ -278,7 +281,8 @@ static int
 nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
-       p = xdr_encode_sattr(p, args->sattr);
+       p = xdr_encode_sattr(p, args->sattr,
+               req->rq_task->tk_client->cl_tagxid);
        *p++ = htonl(args->guard);
        if (args->guard)
                p = xdr_encode_time3(p, &args->guardtime);
@@ -369,7 +373,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs3_createargs *args)
                *p++ = args->verifier[0];
                *p++ = args->verifier[1];
        } else
-               p = xdr_encode_sattr(p, args->sattr);
+               p = xdr_encode_sattr(p, args->sattr,
+                       req->rq_task->tk_client->cl_tagxid);
 
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
        return 0;
@@ -383,7 +388,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_mkdirargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
-       p = xdr_encode_sattr(p, args->sattr);
+       p = xdr_encode_sattr(p, args->sattr,
+               req->rq_task->tk_client->cl_tagxid);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
        return 0;
 }
@@ -396,7 +402,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
-       p = xdr_encode_sattr(p, args->sattr);
+       p = xdr_encode_sattr(p, args->sattr,
+               req->rq_task->tk_client->cl_tagxid);
        p = xdr_encode_array(p, args->topath, args->tolen);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
        return 0;
@@ -411,7 +418,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, u32 *p, struct nfs3_mknodargs *args)
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
        *p++ = htonl(args->type);
-       p = xdr_encode_sattr(p, args->sattr);
+       p = xdr_encode_sattr(p, args->sattr,
+               req->rq_task->tk_client->cl_tagxid);
        if (args->type == NF3CHR || args->type == NF3BLK) {
                *p++ = htonl(MAJOR(args->rdev));
                *p++ = htonl(MINOR(args->rdev));
@@ -484,7 +492,7 @@ static int
 nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
-       struct iovec *iov = rcvbuf->head;
+       struct kvec *iov = rcvbuf->head;
        struct page **page;
        int hdrlen, recvd;
        int status, nr;
@@ -702,8 +710,8 @@ static int
 nfs3_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_readlinkargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
+       unsigned int count = args->count - 5;
        unsigned int replen;
-       u32 count = args->count - 4;
 
        p = xdr_encode_fhandle(p, args->fh);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
@@ -721,7 +729,7 @@ static int
 nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
-       struct iovec *iov = rcvbuf->head;
+       struct kvec *iov = rcvbuf->head;
        unsigned int hdrlen;
        u32     *strlen, len;
        char    *string;
@@ -742,12 +750,15 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
        strlen = (u32*)kmap_atomic(rcvbuf->pages[0], KM_USER0);
        /* Convert length of symlink */
        len = ntohl(*strlen);
-       if (len > rcvbuf->page_len)
-               len = rcvbuf->page_len;
+       if (len > rcvbuf->page_len) {
+               dprintk(KERN_WARNING "nfs: server returned giant symlink!\n");
+               kunmap_atomic(strlen, KM_USER0);
+               return -ENAMETOOLONG;
+       }
        *strlen = len;
        /* NULL terminate the string we got */
        string = (char *)(strlen + 1);
-       string[len] = 0;
+       string[len] = '\0';
        kunmap_atomic(strlen, KM_USER0);
        return 0;
 }
@@ -758,7 +769,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
 static int
 nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
 {
-       struct iovec *iov = req->rq_rcv_buf.head;
+       struct kvec *iov = req->rq_rcv_buf.head;
        int     status, count, ocount, recvd, hdrlen;
 
        status = ntohl(*p++);