]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
NFS: Add trace events to report non-zero NFS status codes
authorChuck Lever <chuck.lever@oracle.com>
Mon, 11 Feb 2019 16:24:26 +0000 (11:24 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 13 Feb 2019 17:03:21 +0000 (12:03 -0500)
These can help field troubleshooting without needing the overhead
of a full network capture (ie, tcpdump).

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/nfs2xdr.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4trace.h
fs/nfs/nfs4xdr.c
fs/nfs/nfstrace.c
fs/nfs/nfstrace.h

index 76614311f9571b42eb291ecc4edbf4b45395ac1f..bac3a4e2cb5dbb8a6180447444b818db22146f8e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/nfs.h>
 #include <linux/nfs2.h>
 #include <linux/nfs_fs.h>
+#include "nfstrace.h"
 #include "internal.h"
 
 #define NFSDBG_FACILITY                NFSDBG_XDR
@@ -145,7 +146,13 @@ static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(!p))
                return -EIO;
+       if (unlikely(*p != cpu_to_be32(NFS_OK)))
+               goto out_status;
+       *status = 0;
+       return 0;
+out_status:
        *status = be32_to_cpup(p);
+       trace_nfs_xdr_status((int)*status);
        return 0;
 }
 
index e5619803a4f66075e01db8a174a380d1766a7cde..4aa3ffe1800e086b321a84367185698063eb4262 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfsacl.h>
+#include "nfstrace.h"
 #include "internal.h"
 
 #define NFSDBG_FACILITY                NFSDBG_XDR
@@ -337,7 +338,13 @@ static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(!p))
                return -EIO;
+       if (unlikely(*p != cpu_to_be32(NFS3_OK)))
+               goto out_status;
+       *status = 0;
+       return 0;
+out_status:
        *status = be32_to_cpup(p);
+       trace_nfs_xdr_status((int)*status);
        return 0;
 }
 
index b4557cf685fbb965b4571bf35414649dd4503a58..cd1a5c08da9ad85f3298919389296349d409a0a8 100644 (file)
@@ -524,6 +524,31 @@ TRACE_EVENT(nfs4_setup_sequence,
                )
 );
 
+TRACE_EVENT(nfs4_xdr_status,
+               TP_PROTO(
+                       u32 op,
+                       int error
+               ),
+
+               TP_ARGS(op, error),
+
+               TP_STRUCT__entry(
+                       __field(u32, op)
+                       __field(int, error)
+               ),
+
+               TP_fast_assign(
+                       __entry->op = op;
+                       __entry->error = -error;
+               ),
+
+               TP_printk(
+                       "operation %d: nfs status %d (%s)",
+                       __entry->op,
+                       __entry->error, show_nfsv4_errors(__entry->error)
+               )
+);
+
 DECLARE_EVENT_CLASS(nfs4_open_event,
                TP_PROTO(
                        const struct nfs_open_context *ctx,
index 24e6a45a572675f9f33e088c8f0d299d296f1a98..38a4cbc18657829a7e52a945a4087715fb8c075a 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/nfs_fs.h>
 
 #include "nfs4_fs.h"
+#include "nfs4trace.h"
 #include "internal.h"
 #include "nfs4idmap.h"
 #include "nfs4session.h"
@@ -3188,11 +3189,14 @@ static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected,
        opnum = be32_to_cpup(p++);
        if (unlikely(opnum != expected))
                goto out_bad_operation;
+       if (unlikely(*p != cpu_to_be32(NFS_OK)))
+               goto out_status;
+       *nfs_retval = 0;
+       return true;
+out_status:
        nfserr = be32_to_cpup(p);
-       if (nfserr == NFS_OK)
-               *nfs_retval = 0;
-       else
-               *nfs_retval = nfs4_stat_to_errno(nfserr);
+       trace_nfs4_xdr_status(opnum, nfserr);
+       *nfs_retval = nfs4_stat_to_errno(nfserr);
        return true;
 out_bad_operation:
        dprintk("nfs: Server returned operation"
index b60d5fbd7727507009dff6e15110ea20d54ed24f..a90b363500c22f76c6865d22c2db513ecbb9523f 100644 (file)
@@ -11,3 +11,4 @@
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_enter);
 EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_exit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_xdr_status);
index bd60f8d1e18102b04c37241eb31e0993cb16c348..a0d6910aa03a47b702f4c94f6c73e1b11c47c25c 100644 (file)
@@ -969,6 +969,91 @@ TRACE_EVENT(nfs_commit_done,
                )
 );
 
+TRACE_DEFINE_ENUM(NFS_OK);
+TRACE_DEFINE_ENUM(NFSERR_PERM);
+TRACE_DEFINE_ENUM(NFSERR_NOENT);
+TRACE_DEFINE_ENUM(NFSERR_IO);
+TRACE_DEFINE_ENUM(NFSERR_NXIO);
+TRACE_DEFINE_ENUM(NFSERR_ACCES);
+TRACE_DEFINE_ENUM(NFSERR_EXIST);
+TRACE_DEFINE_ENUM(NFSERR_XDEV);
+TRACE_DEFINE_ENUM(NFSERR_NODEV);
+TRACE_DEFINE_ENUM(NFSERR_NOTDIR);
+TRACE_DEFINE_ENUM(NFSERR_ISDIR);
+TRACE_DEFINE_ENUM(NFSERR_INVAL);
+TRACE_DEFINE_ENUM(NFSERR_FBIG);
+TRACE_DEFINE_ENUM(NFSERR_NOSPC);
+TRACE_DEFINE_ENUM(NFSERR_ROFS);
+TRACE_DEFINE_ENUM(NFSERR_MLINK);
+TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
+TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
+TRACE_DEFINE_ENUM(NFSERR_DQUOT);
+TRACE_DEFINE_ENUM(NFSERR_STALE);
+TRACE_DEFINE_ENUM(NFSERR_REMOTE);
+TRACE_DEFINE_ENUM(NFSERR_WFLUSH);
+TRACE_DEFINE_ENUM(NFSERR_BADHANDLE);
+TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC);
+TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE);
+TRACE_DEFINE_ENUM(NFSERR_NOTSUPP);
+TRACE_DEFINE_ENUM(NFSERR_TOOSMALL);
+TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT);
+TRACE_DEFINE_ENUM(NFSERR_BADTYPE);
+TRACE_DEFINE_ENUM(NFSERR_JUKEBOX);
+
+#define nfs_show_status(x) \
+       __print_symbolic(x, \
+                       { NFS_OK, "OK" }, \
+                       { NFSERR_PERM, "PERM" }, \
+                       { NFSERR_NOENT, "NOENT" }, \
+                       { NFSERR_IO, "IO" }, \
+                       { NFSERR_NXIO, "NXIO" }, \
+                       { NFSERR_ACCES, "ACCES" }, \
+                       { NFSERR_EXIST, "EXIST" }, \
+                       { NFSERR_XDEV, "XDEV" }, \
+                       { NFSERR_NODEV, "NODEV" }, \
+                       { NFSERR_NOTDIR, "NOTDIR" }, \
+                       { NFSERR_ISDIR, "ISDIR" }, \
+                       { NFSERR_INVAL, "INVAL" }, \
+                       { NFSERR_FBIG, "FBIG" }, \
+                       { NFSERR_NOSPC, "NOSPC" }, \
+                       { NFSERR_ROFS, "ROFS" }, \
+                       { NFSERR_MLINK, "MLINK" }, \
+                       { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \
+                       { NFSERR_NOTEMPTY, "NOTEMPTY" }, \
+                       { NFSERR_DQUOT, "DQUOT" }, \
+                       { NFSERR_STALE, "STALE" }, \
+                       { NFSERR_REMOTE, "REMOTE" }, \
+                       { NFSERR_WFLUSH, "WFLUSH" }, \
+                       { NFSERR_BADHANDLE, "BADHANDLE" }, \
+                       { NFSERR_NOT_SYNC, "NOTSYNC" }, \
+                       { NFSERR_BAD_COOKIE, "BADCOOKIE" }, \
+                       { NFSERR_NOTSUPP, "NOTSUPP" }, \
+                       { NFSERR_TOOSMALL, "TOOSMALL" }, \
+                       { NFSERR_SERVERFAULT, "REMOTEIO" }, \
+                       { NFSERR_BADTYPE, "BADTYPE" }, \
+                       { NFSERR_JUKEBOX, "JUKEBOX" })
+
+TRACE_EVENT(nfs_xdr_status,
+               TP_PROTO(
+                       int error
+               ),
+
+               TP_ARGS(error),
+
+               TP_STRUCT__entry(
+                       __field(int, error)
+               ),
+
+               TP_fast_assign(
+                       __entry->error = error;
+               ),
+
+               TP_printk(
+                       "error=%d (%s)",
+                       __entry->error, nfs_show_status(__entry->error)
+               )
+);
+
 #endif /* _TRACE_NFS_H */
 
 #undef TRACE_INCLUDE_PATH