diff mbox series

[v4,5/5] NFS: Don't ask for readdirplus if files are being written to

Message ID 20220217223323.696173-6-trondmy@kernel.org (mailing list archive)
State New, archived
Headers show
Series Readdir improvements | expand

Commit Message

Trond Myklebust Feb. 17, 2022, 10:33 p.m. UTC
From: Trond Myklebust <trond.myklebust@hammerspace.com>

If a file is being written to, then readdirplus isn't going to help with
retrieving attributes, since we will have to flush out writes anyway in
order to sync the mtime/ctime.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
 fs/nfs/inode.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

Comments

Trond Myklebust Feb. 18, 2022, 11:40 a.m. UTC | #1
On Thu, 2022-02-17 at 17:33 -0500, trondmy@kernel.org wrote:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
> 
> If a file is being written to, then readdirplus isn't going to help
> with
> retrieving attributes, since we will have to flush out writes anyway
> in
> order to sync the mtime/ctime.
> 
> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
> ---
>  fs/nfs/inode.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> index 1bef81f5373a..00500c369c5f 100644
> --- a/fs/nfs/inode.c
> +++ b/fs/nfs/inode.c
> @@ -837,6 +837,7 @@ int nfs_getattr(struct user_namespace
> *mnt_userns, const struct path *path,
>         int err = 0;
>         bool force_sync = query_flags & AT_STATX_FORCE_SYNC;
>         bool do_update = false;
> +       bool record_cache = !nfs_have_writebacks(inode);

There is a second case where readdirplus won't help stat() performance:
if the user has specified 'noac' or has otherwise set values for the
acdirmax/acregmax that are too low, then caching breaks down.

Also fixed in the version committed to 'testing'.

>  
>         trace_nfs_getattr_enter(inode);
>  
> @@ -845,7 +846,8 @@ int nfs_getattr(struct user_namespace
> *mnt_userns, const struct path *path,
>                         STATX_INO | STATX_SIZE | STATX_BLOCKS;
>  
>         if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {
> -               nfs_readdirplus_parent_cache_hit(path->dentry);
> +               if (record_cache)
> +                       nfs_readdirplus_parent_cache_hit(path-
> >dentry);
>                 goto out_no_revalidate;
>         }
>  
> @@ -894,17 +896,18 @@ int nfs_getattr(struct user_namespace
> *mnt_userns, const struct path *path,
>         if (request_mask & STATX_BLOCKS)
>                 do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
>  
> -       if (do_update) {
> +       if (record_cache) {
>                 /* Update the attribute cache */
> -               if (!(server->flags & NFS_MOUNT_NOAC))
> +               if (do_update && !(server->flags & NFS_MOUNT_NOAC))
>                         nfs_readdirplus_parent_cache_miss(path-
> >dentry);
>                 else
>                         nfs_readdirplus_parent_cache_hit(path-
> >dentry);
> +       }
> +       if (do_update) {
>                 err = __nfs_revalidate_inode(server, inode);
>                 if (err)
>                         goto out;
> -       } else
> -               nfs_readdirplus_parent_cache_hit(path->dentry);
> +       }
>  out_no_revalidate:
>         /* Only return attributes that were revalidated. */
>         stat->result_mask = nfs_get_valid_attrmask(inode) |
> request_mask;
diff mbox series

Patch

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 1bef81f5373a..00500c369c5f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -837,6 +837,7 @@  int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
 	int err = 0;
 	bool force_sync = query_flags & AT_STATX_FORCE_SYNC;
 	bool do_update = false;
+	bool record_cache = !nfs_have_writebacks(inode);
 
 	trace_nfs_getattr_enter(inode);
 
@@ -845,7 +846,8 @@  int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
 			STATX_INO | STATX_SIZE | STATX_BLOCKS;
 
 	if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {
-		nfs_readdirplus_parent_cache_hit(path->dentry);
+		if (record_cache)
+			nfs_readdirplus_parent_cache_hit(path->dentry);
 		goto out_no_revalidate;
 	}
 
@@ -894,17 +896,18 @@  int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
 	if (request_mask & STATX_BLOCKS)
 		do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
 
-	if (do_update) {
+	if (record_cache) {
 		/* Update the attribute cache */
-		if (!(server->flags & NFS_MOUNT_NOAC))
+		if (do_update && !(server->flags & NFS_MOUNT_NOAC))
 			nfs_readdirplus_parent_cache_miss(path->dentry);
 		else
 			nfs_readdirplus_parent_cache_hit(path->dentry);
+	}
+	if (do_update) {
 		err = __nfs_revalidate_inode(server, inode);
 		if (err)
 			goto out;
-	} else
-		nfs_readdirplus_parent_cache_hit(path->dentry);
+	}
 out_no_revalidate:
 	/* Only return attributes that were revalidated. */
 	stat->result_mask = nfs_get_valid_attrmask(inode) | request_mask;