From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Even if we're not able to cache all the entries in the readdir buffer, let's ensure that we do prime the dcache. Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> --- fs/nfs/dir.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 71f61565c72c..5e9c25a562bf 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -789,7 +789,7 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, struct xdr_stream stream; struct xdr_buf buf; struct page *scratch, *new, *page = *arrays; - int status; + int err, status = 0; scratch = alloc_page(GFP_KERNEL); if (scratch == NULL) @@ -802,25 +802,32 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, if (entry->fattr->label) entry->fattr->label->len = NFS4_MAXLABELLEN; - status = xdr_decode(desc, entry, &stream); - if (status != 0) + err = xdr_decode(desc, entry, &stream); + if (err != 0) { + if (!status) + status = err; break; + } - if (desc->plus) + if (desc->plus) { nfs_prime_dcache(file_dentry(desc->file), entry, - desc->dir_verifier); + desc->dir_verifier); + if (status == -ENOSPC) + continue; + } status = nfs_readdir_add_to_array(entry, page); if (status != -ENOSPC) continue; if (page->mapping != mapping) { - if (!--narrays) - break; + if (narrays <= 1) + continue; new = nfs_readdir_page_array_alloc(entry->prev_cookie, GFP_KERNEL); if (!new) - break; + continue; + narrays--; arrays++; *arrays = page = new; } else { @@ -829,14 +836,14 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, change_attr, desc->clear_cache); if (!new) - break; + continue; if (page != *arrays) nfs_readdir_page_unlock_and_put(page); page = new; } desc->page_index_max++; status = nfs_readdir_add_to_array(entry, page); - } while (!status && !entry->eof); + } while ((!status || (status == -ENOSPC && desc->plus)) && !entry->eof); switch (status) { case -EBADCOOKIE: -- 2.35.1