Commit ee7b75fc authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Fix a readdir regression

Commit 7ebb9315 (NFS: use secinfo when crossing mountpoints) introduces
a regression when decoding an NFSv4 readdir entry that sets the
rdattr_error field.
By treating the resulting value as if it is a decoding error, the current
code may cause us to skip valid readdir entries.
Reported-by: default avatarAndy Adamson <andros@netapp.com>
Cc: stable@kernel.org [2.6.39]
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 9e2dfdb3
...@@ -3098,7 +3098,7 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint ...@@ -3098,7 +3098,7 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint
return -EIO; return -EIO;
} }
static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res)
{ {
__be32 *p; __be32 *p;
...@@ -3109,7 +3109,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) ...@@ -3109,7 +3109,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
if (unlikely(!p)) if (unlikely(!p))
goto out_overflow; goto out_overflow;
bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
return -be32_to_cpup(p); *res = -be32_to_cpup(p);
} }
return 0; return 0;
out_overflow: out_overflow:
...@@ -4070,6 +4070,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, ...@@ -4070,6 +4070,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
int status; int status;
umode_t fmode = 0; umode_t fmode = 0;
uint32_t type; uint32_t type;
int32_t err;
status = decode_attr_type(xdr, bitmap, &type); status = decode_attr_type(xdr, bitmap, &type);
if (status < 0) if (status < 0)
...@@ -4095,13 +4096,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, ...@@ -4095,13 +4096,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
goto xdr_error; goto xdr_error;
fattr->valid |= status; fattr->valid |= status;
status = decode_attr_error(xdr, bitmap); err = 0;
if (status == -NFS4ERR_WRONGSEC) { status = decode_attr_error(xdr, bitmap, &err);
nfs_fixup_secinfo_attributes(fattr, fh);
status = 0;
}
if (status < 0) if (status < 0)
goto xdr_error; goto xdr_error;
if (err == -NFS4ERR_WRONGSEC)
nfs_fixup_secinfo_attributes(fattr, fh);
status = decode_attr_filehandle(xdr, bitmap, fh); status = decode_attr_filehandle(xdr, bitmap, fh);
if (status < 0) if (status < 0)
......
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