]> err.no Git - linux-2.6/blobdiff - fs/nfs/nfs4xdr.c
[PATCH] fix cramfs making duplicate entries in inode cache
[linux-2.6] / fs / nfs / nfs4xdr.c
index 325cd6d4f23ad4554a086ef37382330e5d5a4a50..6c564ef9489ef833fb293eb776aee4ec75db1290 100644 (file)
@@ -1014,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;
 
@@ -1024,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
@@ -1039,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;
 }
@@ -3062,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;
@@ -3076,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;
@@ -3101,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) {
@@ -4060,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)
@@ -4099,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       },