NFSD: Add an nfsd_file_fsync tracepoint
authorChuck Lever <chuck.lever@oracle.com>
Thu, 3 Nov 2022 20:22:48 +0000 (16:22 -0400)
committerChuck Lever <cel@kernel.org>
Sat, 10 Dec 2022 16:00:04 +0000 (11:00 -0500)
Add a tracepoint to capture the number of filecache-triggered fsync
calls and which files needed it. Also, record when an fsync triggers
a write verifier reset.

Examples:

<...>-97    [007]   262.505611: nfsd_file_free:       inode=0xffff888171e08140 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d2400
<...>-97    [007]   262.505612: nfsd_file_fsync:      inode=0xffff888171e08140 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d2400 ret=0
<...>-97    [007]   262.505623: nfsd_file_free:       inode=0xffff888171e08dc0 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d1e00
<...>-97    [007]   262.505624: nfsd_file_fsync:      inode=0xffff888171e08dc0 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d1e00 ret=0

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
fs/nfsd/filecache.c
fs/nfsd/trace.h

index da7c9cb..1998b4d 100644 (file)
@@ -336,10 +336,13 @@ static void
 nfsd_file_fsync(struct nfsd_file *nf)
 {
        struct file *file = nf->nf_file;
+       int ret;
 
        if (!file || !(file->f_mode & FMODE_WRITE))
                return;
-       if (vfs_fsync(file, 1) != 0)
+       ret = vfs_fsync(file, 1);
+       trace_nfsd_file_fsync(nf, ret);
+       if (ret)
                nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
 }
 
index 0177cfa..33567b8 100644 (file)
@@ -1238,6 +1238,37 @@ DEFINE_EVENT(nfsd_file_lruwalk_class, name,                              \
 DEFINE_NFSD_FILE_LRUWALK_EVENT(nfsd_file_gc_removed);
 DEFINE_NFSD_FILE_LRUWALK_EVENT(nfsd_file_shrinker_removed);
 
+TRACE_EVENT(nfsd_file_fsync,
+       TP_PROTO(
+               const struct nfsd_file *nf,
+               int ret
+       ),
+       TP_ARGS(nf, ret),
+       TP_STRUCT__entry(
+               __field(void *, nf_inode)
+               __field(int, nf_ref)
+               __field(int, ret)
+               __field(unsigned long, nf_flags)
+               __field(unsigned char, nf_may)
+               __field(struct file *, nf_file)
+       ),
+       TP_fast_assign(
+               __entry->nf_inode = nf->nf_inode;
+               __entry->nf_ref = refcount_read(&nf->nf_ref);
+               __entry->ret = ret;
+               __entry->nf_flags = nf->nf_flags;
+               __entry->nf_may = nf->nf_may;
+               __entry->nf_file = nf->nf_file;
+       ),
+       TP_printk("inode=%p ref=%d flags=%s may=%s nf_file=%p ret=%d",
+               __entry->nf_inode,
+               __entry->nf_ref,
+               show_nf_flags(__entry->nf_flags),
+               show_nfsd_may_flags(__entry->nf_may),
+               __entry->nf_file, __entry->ret
+       )
+);
+
 #include "cache.h"
 
 TRACE_DEFINE_ENUM(RC_DROPIT);