Commit 728dd0ab authored by Trond Myklebust's avatar Trond Myklebust

NFS: Don't re-read the entire page cache to find the next cookie

If the page cache entry that was last read gets invalidated for some
reason, then make sure we can re-create it on the next call to readdir.
This, combined with the cache page validation, allows us to reuse the
cached value of page-index on successive calls to nfs_readdir.

Credit is due to Benjamin Coddington for showing that the concept works,
and that it allows for improved cache sharing between processes even in
the case where pages are lost due to LRU or active invalidation.
Suggested-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent d09e673f
...@@ -1120,6 +1120,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1120,6 +1120,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
desc->dup_cookie = dir_ctx->dup_cookie; desc->dup_cookie = dir_ctx->dup_cookie;
desc->duped = dir_ctx->duped; desc->duped = dir_ctx->duped;
page_index = dir_ctx->page_index; page_index = dir_ctx->page_index;
desc->page_index = page_index;
desc->last_cookie = dir_ctx->last_cookie;
desc->attr_gencount = dir_ctx->attr_gencount; desc->attr_gencount = dir_ctx->attr_gencount;
desc->eof = dir_ctx->eof; desc->eof = dir_ctx->eof;
memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf)); memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf));
...@@ -1168,6 +1170,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1168,6 +1170,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
spin_lock(&file->f_lock); spin_lock(&file->f_lock);
dir_ctx->dir_cookie = desc->dir_cookie; dir_ctx->dir_cookie = desc->dir_cookie;
dir_ctx->dup_cookie = desc->dup_cookie; dir_ctx->dup_cookie = desc->dup_cookie;
dir_ctx->last_cookie = desc->last_cookie;
dir_ctx->duped = desc->duped; dir_ctx->duped = desc->duped;
dir_ctx->attr_gencount = desc->attr_gencount; dir_ctx->attr_gencount = desc->attr_gencount;
dir_ctx->page_index = desc->page_index; dir_ctx->page_index = desc->page_index;
...@@ -1209,10 +1212,11 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence) ...@@ -1209,10 +1212,11 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
} }
if (offset != filp->f_pos) { if (offset != filp->f_pos) {
filp->f_pos = offset; filp->f_pos = offset;
if (nfs_readdir_use_cookie(filp)) if (!nfs_readdir_use_cookie(filp)) {
dir_ctx->dir_cookie = offset;
else
dir_ctx->dir_cookie = 0; dir_ctx->dir_cookie = 0;
dir_ctx->page_index = 0;
} else
dir_ctx->dir_cookie = offset;
if (offset == 0) if (offset == 0)
memset(dir_ctx->verf, 0, sizeof(dir_ctx->verf)); memset(dir_ctx->verf, 0, sizeof(dir_ctx->verf));
dir_ctx->duped = 0; dir_ctx->duped = 0;
......
...@@ -105,6 +105,7 @@ struct nfs_open_dir_context { ...@@ -105,6 +105,7 @@ struct nfs_open_dir_context {
__be32 verf[NFS_DIR_VERIFIER_SIZE]; __be32 verf[NFS_DIR_VERIFIER_SIZE];
__u64 dir_cookie; __u64 dir_cookie;
__u64 dup_cookie; __u64 dup_cookie;
__u64 last_cookie;
pgoff_t page_index; pgoff_t page_index;
signed char duped; signed char duped;
bool eof; bool eof;
......
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