NFS: Add basic readdir tracing
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sun, 20 Feb 2022 00:24:38 +0000 (19:24 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 2 Mar 2022 13:43:39 +0000 (08:43 -0500)
Add tracing to track how often the client goes to the server for updated
readdir information.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/dir.c
fs/nfs/nfstrace.h

index cf7974642a19909d979d6f73413dad2873db0765..d591d20f753467d9f0fc39a14d7f32c20bdc9ee1 100644 (file)
@@ -984,10 +984,14 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
                if (desc->page_index == desc->page_index_max)
                        nfs_grow_dtsize(desc);
                desc->page_index_max = desc->page_index;
+               trace_nfs_readdir_cache_fill(desc->file, nfsi->cookieverf,
+                                            desc->last_cookie,
+                                            desc->page->index, desc->dtsize);
                res = nfs_readdir_xdr_to_array(desc, nfsi->cookieverf, verf,
                                               &desc->page, 1);
                if (res < 0) {
                        nfs_readdir_page_unlock_and_put_cached(desc);
+                       trace_nfs_readdir_cache_fill_done(inode, res);
                        if (res == -EBADCOOKIE || res == -ENOTSYNC) {
                                invalidate_inode_pages2(desc->file->f_mapping);
                                desc->page_index = 0;
@@ -1108,7 +1112,14 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
        desc->duped = 0;
        desc->page_index_max = 0;
 
+       trace_nfs_readdir_uncached(desc->file, desc->verf, desc->last_cookie,
+                                  -1, desc->dtsize);
+
        status = nfs_readdir_xdr_to_array(desc, desc->verf, verf, arrays, sz);
+       if (status < 0) {
+               trace_nfs_readdir_uncached_done(file_inode(desc->file), status);
+               goto out_free;
+       }
 
        for (i = 0; !desc->eob && i < sz && arrays[i]; i++) {
                desc->page = arrays[i];
@@ -1127,7 +1138,7 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
                         i < (desc->page_index_max >> 1))
                        nfs_shrink_dtsize(desc);
        }
-
+out_free:
        for (i = 0; i < sz && arrays[i]; i++)
                nfs_readdir_page_array_free(arrays[i]);
 out:
index 3672f6703ee70119979dc8c78e9a149e4028823a..c2d0543ecb2d73c646c8ccbedad4ceb464e28444 100644 (file)
@@ -160,6 +160,8 @@ DEFINE_NFS_INODE_EVENT(nfs_fsync_enter);
 DEFINE_NFS_INODE_EVENT_DONE(nfs_fsync_exit);
 DEFINE_NFS_INODE_EVENT(nfs_access_enter);
 DEFINE_NFS_INODE_EVENT_DONE(nfs_set_cache_invalid);
+DEFINE_NFS_INODE_EVENT_DONE(nfs_readdir_cache_fill_done);
+DEFINE_NFS_INODE_EVENT_DONE(nfs_readdir_uncached_done);
 
 TRACE_EVENT(nfs_access_exit,
                TP_PROTO(
@@ -271,6 +273,72 @@ DEFINE_NFS_UPDATE_SIZE_EVENT(wcc);
 DEFINE_NFS_UPDATE_SIZE_EVENT(update);
 DEFINE_NFS_UPDATE_SIZE_EVENT(grow);
 
+DECLARE_EVENT_CLASS(nfs_readdir_event,
+               TP_PROTO(
+                       const struct file *file,
+                       const __be32 *verifier,
+                       u64 cookie,
+                       pgoff_t page_index,
+                       unsigned int dtsize
+               ),
+
+               TP_ARGS(file, verifier, cookie, page_index, dtsize),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __array(char, verifier, NFS4_VERIFIER_SIZE)
+                       __field(u64, cookie)
+                       __field(pgoff_t, index)
+                       __field(unsigned int, dtsize)
+               ),
+
+               TP_fast_assign(
+                       const struct inode *dir = file_inode(file);
+                       const struct nfs_inode *nfsi = NFS_I(dir);
+
+                       __entry->dev = dir->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->version = inode_peek_iversion_raw(dir);
+                       if (cookie != 0)
+                               memcpy(__entry->verifier, verifier,
+                                      NFS4_VERIFIER_SIZE);
+                       else
+                               memset(__entry->verifier, 0,
+                                      NFS4_VERIFIER_SIZE);
+                       __entry->cookie = cookie;
+                       __entry->index = page_index;
+                       __entry->dtsize = dtsize;
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu "
+                       "cookie=%s:0x%llx cache_index=%lu dtsize=%u",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid, __entry->fhandle,
+                       __entry->version, show_nfs4_verifier(__entry->verifier),
+                       (unsigned long long)__entry->cookie, __entry->index,
+                       __entry->dtsize
+               )
+);
+
+#define DEFINE_NFS_READDIR_EVENT(name) \
+       DEFINE_EVENT(nfs_readdir_event, name, \
+                       TP_PROTO( \
+                               const struct file *file, \
+                               const __be32 *verifier, \
+                               u64 cookie, \
+                               pgoff_t page_index, \
+                               unsigned int dtsize \
+                               ), \
+                       TP_ARGS(file, verifier, cookie, page_index, dtsize))
+
+DEFINE_NFS_READDIR_EVENT(nfs_readdir_cache_fill);
+DEFINE_NFS_READDIR_EVENT(nfs_readdir_uncached);
+
 DECLARE_EVENT_CLASS(nfs_lookup_event,
                TP_PROTO(
                        const struct inode *dir,