summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2010-10-21 16:33:16 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-10-23 15:27:36 -0400
commit9942438089d5c0e3adecdcb7bc360b8fe0ce7e62 (patch)
tree6c6fa331811f6c8e5217193276602bd353613061 /fs/nfs
parent3c8a1aeed8fd7f89bd0400fad72cbc1ac3460217 (diff)
downloadlinux-9942438089d5c0e3adecdcb7bc360b8fe0ce7e62.tar.gz
linux-9942438089d5c0e3adecdcb7bc360b8fe0ce7e62.tar.bz2
linux-9942438089d5c0e3adecdcb7bc360b8fe0ce7e62.zip
NFS: check xdr_decode for errors
Check if the decoded entry has the eof bit set when returning from xdr_decode with an error. If it does, we should set the eof bits in the array before returning. This should keep us from looping when we expect more data but the server doesn't give us anything new. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7b8b7c59db9f..0cbb714a09d8 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -442,6 +442,8 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e
struct xdr_stream stream;
struct xdr_buf buf;
__be32 *ptr = xdr_page;
+ int status;
+ struct nfs_cache_array *array;
buf.head->iov_base = xdr_page;
buf.head->iov_len = buflen;
@@ -453,11 +455,23 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e
xdr_init_decode(&stream, &buf, ptr);
- while (xdr_decode(desc, entry, &stream) == 0) {
+
+ do {
+ status = xdr_decode(desc, entry, &stream);
+ if (status != 0)
+ break;
+
if (nfs_readdir_add_to_array(entry, page) == -1)
break;
if (desc->plus == 1)
nfs_prime_dcache(desc->file->f_path.dentry, entry);
+ } while (!entry->eof);
+
+ if (status == -EBADCOOKIE && entry->eof) {
+ array = nfs_readdir_get_array(page);
+ array->eof_index = array->size - 1;
+ status = 0;
+ nfs_readdir_release_array(page);
}
}