summaryrefslogtreecommitdiff
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 481cb039626f..5f4de05763c9 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1010,8 +1010,13 @@ 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);
- WRITE32(FATTR4_WORD0_FILEID);
- WRITE32(0);
+ if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) {
+ WRITE32(0);
+ WRITE32(FATTR4_WORD1_MOUNTED_ON_FILEID);
+ } else {
+ WRITE32(FATTR4_WORD0_FILEID);
+ WRITE32(0);
+ }
/* set up reply kvec
* toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -3175,7 +3180,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp)
READ_BUF(4);
READ32(len);
READ_BUF(len);
- return -EEXIST;
+ return -NFSERR_CLID_INUSE;
} else
return -nfs_stat_to_errno(nfserr);
@@ -3857,7 +3862,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d
uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
{
- uint32_t bitmap[1] = {0};
+ uint32_t bitmap[2] = {0};
uint32_t len;
if (!*p++) {
@@ -3881,13 +3886,18 @@ uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
entry->ino = 1;
len = ntohl(*p++); /* bitmap length */
- if (len > 0) {
- bitmap[0] = ntohl(*p);
- p += len;
+ if (len-- > 0) {
+ bitmap[0] = ntohl(*p++);
+ if (len-- > 0) {
+ bitmap[1] = ntohl(*p++);
+ p += len;
+ }
}
len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
if (len > 0) {
- if (bitmap[0] == FATTR4_WORD0_FILEID)
+ if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
+ xdr_decode_hyper(p, &entry->ino);
+ else if (bitmap[0] == FATTR4_WORD0_FILEID)
xdr_decode_hyper(p, &entry->ino);
p += len;
}