]> err.no Git - linux-2.6/blobdiff - fs/nfs/nfs4xdr.c
[PATCH] jffs/jffs2: remove wrong function prototypes
[linux-2.6] / fs / nfs / nfs4xdr.c
index 6f1c003ee33a0d928628594ce761d2874585c2f4..6c564ef9489ef833fb293eb776aee4ec75db1290 100644 (file)
@@ -372,6 +372,13 @@ static int nfs_stat_to_errno(int);
                                decode_putfh_maxsz + \
                                op_decode_hdr_maxsz + \
                                nfs4_fattr_bitmap_maxsz + 1)
+#define NFS4_enc_setacl_sz     (compound_encode_hdr_maxsz + \
+                               encode_putfh_maxsz + \
+                               op_encode_hdr_maxsz + 4 + \
+                               nfs4_fattr_bitmap_maxsz + 1)
+#define NFS4_dec_setacl_sz     (compound_decode_hdr_maxsz + \
+                               decode_putfh_maxsz + \
+                               op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
 
 static struct {
        unsigned int    mode;
@@ -471,7 +478,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
         * In the worst-case, this would be
         *   12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
         *          = 36 bytes, plus any contribution from variable-length fields
-        *            such as owner/group/acl's.
+        *            such as owner/group.
         */
        len = 16;
 
@@ -1007,6 +1014,10 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
 static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
+       uint32_t attrs[2] = {
+               FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
+               FATTR4_WORD1_MOUNTED_ON_FILEID,
+       };
        int replen;
        uint32_t *p;
 
@@ -1017,13 +1028,20 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
        WRITE32(readdir->count >> 1);  /* We're not doing readdirplus */
        WRITE32(readdir->count);
        WRITE32(2);
-       if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) {
-               WRITE32(0);
-               WRITE32(FATTR4_WORD1_MOUNTED_ON_FILEID);
-       } else {
-               WRITE32(FATTR4_WORD0_FILEID);
-               WRITE32(0);
-       }
+       /* Switch to mounted_on_fileid if the server supports it */
+       if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
+               attrs[0] &= ~FATTR4_WORD0_FILEID;
+       else
+               attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
+       WRITE32(attrs[0] & readdir->bitmask[0]);
+       WRITE32(attrs[1] & readdir->bitmask[1]);
+       dprintk("%s: cookie = %Lu, verifier = 0x%x%x, bitmap = 0x%x%x\n",
+                       __FUNCTION__,
+                       (unsigned long long)readdir->cookie,
+                       ((u32 *)readdir->verifier.data)[0],
+                       ((u32 *)readdir->verifier.data)[1],
+                       attrs[0] & readdir->bitmask[0],
+                       attrs[1] & readdir->bitmask[1]);
 
        /* set up reply kvec
         *    toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1032,6 +1050,9 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
        replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
        xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->pages,
                         readdir->pgbase, readdir->count);
+       dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
+                       __FUNCTION__, replen, readdir->pages,
+                       readdir->pgbase, readdir->count);
 
        return 0;
 }
@@ -1095,6 +1116,25 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client
        return 0;
 }
 
+static int
+encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
+{
+       uint32_t *p;
+
+       RESERVE_SPACE(4+sizeof(zero_stateid.data));
+       WRITE32(OP_SETATTR);
+       WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data));
+       RESERVE_SPACE(2*4);
+       WRITE32(1);
+       WRITE32(FATTR4_WORD0_ACL);
+       if (arg->acl_len % 4)
+               return -EINVAL;
+       RESERVE_SPACE(4);
+       WRITE32(arg->acl_len);
+       xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
+       return 0;
+}
+
 static int
 encode_savefh(struct xdr_stream *xdr)
 {
@@ -3036,6 +3076,11 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
                return status;
        READ_BUF(8);
        COPYMEM(readdir->verifier.data, 8);
+       dprintk("%s: verifier = 0x%x%x\n",
+                       __FUNCTION__,
+                       ((u32 *)readdir->verifier.data)[0],
+                       ((u32 *)readdir->verifier.data)[1]);
+
 
        hdrlen = (char *) p - (char *) iov->iov_base;
        recvd = rcvbuf->len - hdrlen;
@@ -3050,12 +3095,14 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        for (nr = 0; *p++; nr++) {
                if (p + 3 > end)
                        goto short_pkt;
+               dprintk("cookie = %Lu, ", *((unsigned long long *)p));
                p += 2;                 /* cookie */
                len = ntohl(*p++);      /* filename length */
                if (len > NFS4_MAXNAMLEN) {
                        printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len);
                        goto err_unmap;
                }
+               dprintk("filename = %*s\n", len, (char *)p);
                p += XDR_QUADLEN(len);
                if (p + 1 > end)
                        goto short_pkt;
@@ -3075,6 +3122,7 @@ out:
        kunmap_atomic(kaddr, KM_USER0);
        return 0;
 short_pkt:
+       dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr);
        entry[0] = entry[1] = 0;
        /* truncate listing ? */
        if (!nr) {
@@ -3492,6 +3540,48 @@ out:
 
 }
 
+/*
+ * Encode an SETACL request
+ */
+static int
+nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args)
+{
+        struct xdr_stream xdr;
+        struct compound_hdr hdr = {
+                .nops   = 2,
+        };
+        int status;
+
+        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+        encode_compound_hdr(&xdr, &hdr);
+        status = encode_putfh(&xdr, args->fh);
+        if (status)
+                goto out;
+        status = encode_setacl(&xdr, args);
+out:
+        return status;
+}
+/*
+ * Decode SETACL response
+ */
+static int
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr;
+       int status;
+
+       xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+       status = decode_compound_hdr(&xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_putfh(&xdr);
+       if (status)
+               goto out;
+       status = decode_setattr(&xdr, res);
+out:
+       return status;
+}
 
 /*
  * Decode GETACL response
@@ -3992,6 +4082,12 @@ uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
        }
        len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
        if (len > 0) {
+               if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) {
+                       bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
+                       /* Ignore the return value of rdattr_error for now */
+                       p++;
+                       len--;
+               }
                if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
                        xdr_decode_hyper(p, &entry->ino);
                else if (bitmap[0] == FATTR4_WORD0_FILEID)
@@ -4031,6 +4127,8 @@ static struct {
        { NFS4ERR_DQUOT,        EDQUOT          },
        { NFS4ERR_STALE,        ESTALE          },
        { NFS4ERR_BADHANDLE,    EBADHANDLE      },
+       { NFS4ERR_BADOWNER,     EINVAL          },
+       { NFS4ERR_BADNAME,      EINVAL          },
        { NFS4ERR_BAD_COOKIE,   EBADCOOKIE      },
        { NFS4ERR_NOTSUPP,      ENOTSUPP        },
        { NFS4ERR_TOOSMALL,     ETOOSMALL       },
@@ -4117,6 +4215,7 @@ struct rpc_procinfo       nfs4_procedures[] = {
   PROC(SERVER_CAPS,    enc_server_caps, dec_server_caps),
   PROC(DELEGRETURN,    enc_delegreturn, dec_delegreturn),
   PROC(GETACL,         enc_getacl,     dec_getacl),
+  PROC(SETACL,         enc_setacl,     dec_setacl),
 };
 
 struct rpc_version             nfs_version4 = {