NFS: check xdr_decode for errors
authorBryan Schumaker <bjschuma@netapp.com>
Thu, 21 Oct 2010 20:33:16 +0000 (16:33 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Sat, 23 Oct 2010 19:27:36 +0000 (15:27 -0400)
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>
fs/nfs/dir.c

index 7b8b7c59db9f546515a60e8058f3e4c75d20c21c..0cbb714a09d8da13bb010765241158ccca3e42e8 100644 (file)
@@ -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);
        }
 }