NFSD: Instrument fh_verify()
authorChuck Lever <chuck.lever@oracle.com>
Tue, 21 Jun 2022 14:06:23 +0000 (10:06 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Sat, 30 Jul 2022 00:08:56 +0000 (20:08 -0400)
Capture file handles and how they map to local inodes. In particular,
NFSv4 PUTFH uses fh_verify() so we can now observe which file handles
are the target of OPEN, LOOKUP, RENAME, and so on.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfsfh.c
fs/nfsd/trace.h

index c29baa0..5e2ed4b 100644 (file)
@@ -331,8 +331,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
        struct dentry   *dentry;
        __be32          error;
 
-       dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
-
        if (!fhp->fh_dentry) {
                error = nfsd_set_fh_dentry(rqstp, fhp);
                if (error)
@@ -340,6 +338,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
        }
        dentry = fhp->fh_dentry;
        exp = fhp->fh_export;
+
+       trace_nfsd_fh_verify(rqstp, fhp, type, access);
+
        /*
         * We still have to do all these permission checks, even when
         * fh_dentry is already set:
index 081179f..d23ecf7 100644 (file)
@@ -171,6 +171,52 @@ TRACE_EVENT(nfsd_compound_encode_err,
                __entry->opnum, __entry->status)
 );
 
+#define show_fs_file_type(x) \
+       __print_symbolic(x, \
+               { S_IFLNK,              "LNK" }, \
+               { S_IFREG,              "REG" }, \
+               { S_IFDIR,              "DIR" }, \
+               { S_IFCHR,              "CHR" }, \
+               { S_IFBLK,              "BLK" }, \
+               { S_IFIFO,              "FIFO" }, \
+               { S_IFSOCK,             "SOCK" })
+
+TRACE_EVENT(nfsd_fh_verify,
+       TP_PROTO(
+               const struct svc_rqst *rqstp,
+               const struct svc_fh *fhp,
+               umode_t type,
+               int access
+       ),
+       TP_ARGS(rqstp, fhp, type, access),
+       TP_STRUCT__entry(
+               __field(unsigned int, netns_ino)
+               __sockaddr(server, rqstp->rq_xprt->xpt_remotelen)
+               __sockaddr(client, rqstp->rq_xprt->xpt_remotelen)
+               __field(u32, xid)
+               __field(u32, fh_hash)
+               __field(void *, inode)
+               __field(unsigned long, type)
+               __field(unsigned long, access)
+       ),
+       TP_fast_assign(
+               __entry->netns_ino = SVC_NET(rqstp)->ns.inum;
+               __assign_sockaddr(server, &rqstp->rq_xprt->xpt_local,
+                      rqstp->rq_xprt->xpt_locallen);
+               __assign_sockaddr(client, &rqstp->rq_xprt->xpt_remote,
+                                 rqstp->rq_xprt->xpt_remotelen);
+               __entry->xid = be32_to_cpu(rqstp->rq_xid);
+               __entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle);
+               __entry->inode = d_inode(fhp->fh_dentry);
+               __entry->type = type;
+               __entry->access = access;
+       ),
+       TP_printk("xid=0x%08x fh_hash=0x%08x inode=%p type=%s access=%s",
+               __entry->xid, __entry->fh_hash, __entry->inode,
+               show_fs_file_type(__entry->type),
+               show_nfsd_may_flags(__entry->access)
+       )
+);
 
 DECLARE_EVENT_CLASS(nfsd_fh_err_class,
        TP_PROTO(struct svc_rqst *rqstp,