2022-02-25 18:49:11

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH v8 24/24] NFS: Cache all entries in the readdirplus reply

From: Trond Myklebust <[email protected]>

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 <[email protected]>
---
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