Commit 0dfdad1c authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Add tracepoints in nfsd_dispatch()



For troubleshooting purposes, record GARBAGE_ARGS and CANT_ENCODE
failures.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 788f7183
Loading
Loading
Loading
Loading
+5 −12
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@
#include "netns.h"
#include "filecache.h"

#include "trace.h"

#define NFSDDBG_FACILITY	NFSDDBG_SVC

bool inter_copy_offload_enable;
@@ -1009,11 +1011,8 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
	struct kvec *resv = &rqstp->rq_res.head[0];
	__be32 *p;

	dprintk("nfsd_dispatch: vers %d proc %d\n",
				rqstp->rq_vers, rqstp->rq_proc);

	if (nfs_request_too_big(rqstp, proc))
		goto out_too_large;
		goto out_decode_err;

	/*
	 * Give the xdr decoder a chance to change this if it wants
@@ -1052,24 +1051,18 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
out_cached_reply:
	return 1;

out_too_large:
	dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
	*statp = rpc_garbage_args;
	return 1;

out_decode_err:
	dprintk("nfsd: failed to decode arguments!\n");
	trace_nfsd_garbage_args_err(rqstp);
	*statp = rpc_garbage_args;
	return 1;

out_update_drop:
	dprintk("nfsd: Dropping request; may be revisited later\n");
	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
out_dropit:
	return 0;

out_encode_err:
	dprintk("nfsd: failed to encode result!\n");
	trace_nfsd_cant_encode_err(rqstp);
	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
	*statp = rpc_system_err;
	return 1;
+60 −0
Original line number Diff line number Diff line
@@ -12,6 +12,66 @@
#include "export.h"
#include "nfsfh.h"

#define NFSD_TRACE_PROC_ARG_FIELDS \
		__field(unsigned int, netns_ino) \
		__field(u32, xid) \
		__array(unsigned char, server, sizeof(struct sockaddr_in6)) \
		__array(unsigned char, client, sizeof(struct sockaddr_in6))

#define NFSD_TRACE_PROC_ARG_ASSIGNMENTS \
		do { \
			__entry->netns_ino = SVC_NET(rqstp)->ns.inum; \
			__entry->xid = be32_to_cpu(rqstp->rq_xid); \
			memcpy(__entry->server, &rqstp->rq_xprt->xpt_local, \
			       rqstp->rq_xprt->xpt_locallen); \
			memcpy(__entry->client, &rqstp->rq_xprt->xpt_remote, \
			       rqstp->rq_xprt->xpt_remotelen); \
		} while (0);

TRACE_EVENT(nfsd_garbage_args_err,
	TP_PROTO(
		const struct svc_rqst *rqstp
	),
	TP_ARGS(rqstp),
	TP_STRUCT__entry(
		NFSD_TRACE_PROC_ARG_FIELDS

		__field(u32, vers)
		__field(u32, proc)
	),
	TP_fast_assign(
		NFSD_TRACE_PROC_ARG_ASSIGNMENTS

		__entry->vers = rqstp->rq_vers;
		__entry->proc = rqstp->rq_proc;
	),
	TP_printk("xid=0x%08x vers=%u proc=%u",
		__entry->xid, __entry->vers, __entry->proc
	)
);

TRACE_EVENT(nfsd_cant_encode_err,
	TP_PROTO(
		const struct svc_rqst *rqstp
	),
	TP_ARGS(rqstp),
	TP_STRUCT__entry(
		NFSD_TRACE_PROC_ARG_FIELDS

		__field(u32, vers)
		__field(u32, proc)
	),
	TP_fast_assign(
		NFSD_TRACE_PROC_ARG_ASSIGNMENTS

		__entry->vers = rqstp->rq_vers;
		__entry->proc = rqstp->rq_proc;
	),
	TP_printk("xid=0x%08x vers=%u proc=%u",
		__entry->xid, __entry->vers, __entry->proc
	)
);

#define show_nfsd_may_flags(x)						\
	__print_flags(x, "|",						\
		{ NFSD_MAY_EXEC,		"EXEC" },		\