Capture especially the XID, file handle, and attr mask for troubleshooting. So for example: nfsd-1025 [002] 256.807363: nfsd_setattr: xid=0x12147d7a fh_hash=0x6085d6fb valid=MODE|ATIME|MTIME Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> --- fs/nfsd/trace.h | 24 ++++++++++++++++++++++++ fs/nfsd/vfs.c | 2 ++ include/trace/events/fs.h | 20 ++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 62bf57a8d03c..b4c773530aa8 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -9,6 +9,7 @@ #define _NFSD_TRACE_H #include <linux/tracepoint.h> +#include <trace/events/fs.h> #include "export.h" #include "nfsfh.h" @@ -29,6 +30,29 @@ { NFSD_MAY_READ_IF_EXEC, "READ_IF_EXEC" }, \ { NFSD_MAY_64BIT_COOKIE, "64BIT_COOKIE" }) +TRACE_EVENT(nfsd_setattr_args, + TP_PROTO( + const struct svc_rqst *rqstp, + const struct svc_fh *fhp, + unsigned int valid + ), + TP_ARGS(rqstp, fhp, valid), + TP_STRUCT__entry( + __field(u32, xid) + __field(u32, fh_hash) + __field(unsigned long, valid) + ), + TP_fast_assign( + __entry->xid = be32_to_cpu(rqstp->rq_xid); + __entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle); + __entry->valid = valid; + ), + TP_printk("xid=0x%08x fh_hash=0x%08x valid=%s", + __entry->xid, __entry->fh_hash, + show_attr_valid_flags(__entry->valid) + ) +); + TRACE_EVENT(nfsd_compound, TP_PROTO(const struct svc_rqst *rqst, u32 args_opcnt), diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 1ecaceebee13..a311593ac976 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -375,6 +375,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, bool get_write_count; bool size_change = (iap->ia_valid & ATTR_SIZE); + trace_nfsd_setattr_args(rqstp, fhp, iap->ia_valid); + if (iap->ia_valid & ATTR_SIZE) { accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE; ftype = S_IFREG; diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h index 8ea0e84e425a..2b185d81d9a5 100644 --- a/include/trace/events/fs.h +++ b/include/trace/events/fs.h @@ -145,3 +145,23 @@ { LOOKUP_NO_XDEV, "NO_XDEV" }, \ { LOOKUP_BENEATH, "BENEATH" }, \ { LOOKUP_IN_ROOT, "IN_ROOT" }) + +#define show_attr_valid_flags(x) \ + __print_flags(x, "|", \ + { ATTR_MODE, "MODE" }, \ + { ATTR_UID, "UID" }, \ + { ATTR_GID, "GID" }, \ + { ATTR_SIZE, "SIZE" }, \ + { ATTR_ATIME, "ATIME" }, \ + { ATTR_MTIME, "MTIME" }, \ + { ATTR_CTIME, "CTIME" }, \ + { ATTR_ATIME_SET, "ATIME_SET" }, \ + { ATTR_MTIME_SET, "MTIME_SET" }, \ + { ATTR_FORCE, "FORCE" }, \ + { ATTR_KILL_SUID, "KILL_SUID" }, \ + { ATTR_KILL_SGID, "KILL_SGID" }, \ + { ATTR_FILE, "FILE" }, \ + { ATTR_KILL_PRIV, "KILL_PRIV" }, \ + { ATTR_OPEN, "OPEN" }, \ + { ATTR_TIMES_SET, "TIMES_SET" }, \ + { ATTR_TOUCH, "TOUCH" })