Commit 6019ce07 authored by Chuck Lever's avatar Chuck Lever

NFSD: Add a tracepoint to record directory entry encoding

Enable watching the progress of directory encoding to capture the
timing of any issues with reading or encoding a directory. The
new tracepoint captures dirent encoding for all NFS versions.

For example, here's what a few NFSv4 directory entries might look
like:

nfsd-989   [002]   468.596265: nfsd_dirent:          fh_hash=0x5d162594 ino=2 name=.
nfsd-989   [002]   468.596267: nfsd_dirent:          fh_hash=0x5d162594 ino=1 name=..
nfsd-989   [002]   468.596299: nfsd_dirent:          fh_hash=0x5d162594 ino=3827 name=zlib.c
nfsd-989   [002]   468.596325: nfsd_dirent:          fh_hash=0x5d162594 ino=3811 name=xdiff
nfsd-989   [002]   468.596351: nfsd_dirent:          fh_hash=0x5d162594 ino=3810 name=xdiff-interface.h
nfsd-989   [002]   468.596377: nfsd_dirent:          fh_hash=0x5d162594 ino=3809 name=xdiff-interface.c
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 1416f435
...@@ -391,6 +391,30 @@ DEFINE_EVENT(nfsd_err_class, nfsd_##name, \ ...@@ -391,6 +391,30 @@ DEFINE_EVENT(nfsd_err_class, nfsd_##name, \
DEFINE_NFSD_ERR_EVENT(read_err); DEFINE_NFSD_ERR_EVENT(read_err);
DEFINE_NFSD_ERR_EVENT(write_err); DEFINE_NFSD_ERR_EVENT(write_err);
TRACE_EVENT(nfsd_dirent,
TP_PROTO(struct svc_fh *fhp,
u64 ino,
const char *name,
int namlen),
TP_ARGS(fhp, ino, name, namlen),
TP_STRUCT__entry(
__field(u32, fh_hash)
__field(u64, ino)
__field(int, len)
__dynamic_array(unsigned char, name, namlen)
),
TP_fast_assign(
__entry->fh_hash = fhp ? knfsd_fh_hash(&fhp->fh_handle) : 0;
__entry->ino = ino;
__entry->len = namlen;
memcpy(__get_str(name), name, namlen);
__assign_str(name, name);
),
TP_printk("fh_hash=0x%08x ino=%llu name=%.*s",
__entry->fh_hash, __entry->ino,
__entry->len, __get_str(name))
)
#include "state.h" #include "state.h"
#include "filecache.h" #include "filecache.h"
#include "vfs.h" #include "vfs.h"
......
...@@ -1968,8 +1968,9 @@ static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name, ...@@ -1968,8 +1968,9 @@ static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
return 0; return 0;
} }
static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func, static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
struct readdir_cd *cdp, loff_t *offsetp) nfsd_filldir_t func, struct readdir_cd *cdp,
loff_t *offsetp)
{ {
struct buffered_dirent *de; struct buffered_dirent *de;
int host_err; int host_err;
...@@ -2015,6 +2016,8 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func, ...@@ -2015,6 +2016,8 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
if (cdp->err != nfs_ok) if (cdp->err != nfs_ok)
break; break;
trace_nfsd_dirent(fhp, de->ino, de->name, de->namlen);
reclen = ALIGN(sizeof(*de) + de->namlen, reclen = ALIGN(sizeof(*de) + de->namlen,
sizeof(u64)); sizeof(u64));
size -= reclen; size -= reclen;
...@@ -2062,7 +2065,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, ...@@ -2062,7 +2065,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
goto out_close; goto out_close;
} }
err = nfsd_buffered_readdir(file, func, cdp, offsetp); err = nfsd_buffered_readdir(file, fhp, func, cdp, offsetp);
if (err == nfserr_eof || err == nfserr_toosmall) if (err == nfserr_eof || err == nfserr_toosmall)
err = nfs_ok; /* can still be found in ->err */ err = nfs_ok; /* can still be found in ->err */
......
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