Commit a1593520 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: in readdir, use MOUNTED_ON_FILEID, rather than true fileid

 Some servers return an error if the READDIR call attempts to read the
 fileid of a mountpoint.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 743d642c
...@@ -1720,6 +1720,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, ...@@ -1720,6 +1720,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
.pages = &page, .pages = &page,
.pgbase = 0, .pgbase = 0,
.count = count, .count = count,
.bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
}; };
struct nfs4_readdir_res res; struct nfs4_readdir_res res;
struct rpc_message msg = { struct rpc_message msg = {
......
...@@ -1010,8 +1010,13 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg ...@@ -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 >> 1); /* We're not doing readdirplus */
WRITE32(readdir->count); WRITE32(readdir->count);
WRITE32(2); WRITE32(2);
WRITE32(FATTR4_WORD0_FILEID); if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) {
WRITE32(0); WRITE32(0);
WRITE32(FATTR4_WORD1_MOUNTED_ON_FILEID);
} else {
WRITE32(FATTR4_WORD0_FILEID);
WRITE32(0);
}
/* set up reply kvec /* set up reply kvec
* toplevel_status + taglen + rescount + OP_PUTFH + status * toplevel_status + taglen + rescount + OP_PUTFH + status
...@@ -3857,7 +3862,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d ...@@ -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 *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; uint32_t len;
if (!*p++) { if (!*p++) {
...@@ -3881,13 +3886,18 @@ uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus) ...@@ -3881,13 +3886,18 @@ uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
entry->ino = 1; entry->ino = 1;
len = ntohl(*p++); /* bitmap length */ len = ntohl(*p++); /* bitmap length */
if (len > 0) { if (len-- > 0) {
bitmap[0] = ntohl(*p); bitmap[0] = ntohl(*p++);
p += len; if (len-- > 0) {
bitmap[1] = ntohl(*p++);
p += len;
}
} }
len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */ len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
if (len > 0) { 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); xdr_decode_hyper(p, &entry->ino);
p += len; p += len;
} }
......
...@@ -563,6 +563,7 @@ struct nfs4_readdir_arg { ...@@ -563,6 +563,7 @@ struct nfs4_readdir_arg {
u32 count; u32 count;
struct page ** pages; /* zero-copy data */ struct page ** pages; /* zero-copy data */
unsigned int pgbase; /* zero-copy data */ unsigned int pgbase; /* zero-copy data */
const u32 * bitmask;
}; };
struct nfs4_readdir_res { struct nfs4_readdir_res {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment