Hi Ross,

----- Original Message -----
> Do you have any suggestions for tracking down the root cause?

Attached is the starting point for a generic "debug" kernel trace point,
complete with examples of how it's used. It's always associated with a
particular glock. You might find it helpful, but again, it's old, so
it'll probably need to be tweaked for an upstream kernel.

Regards,

Bob Peterson
Red Hat File Systems
From 68ad040adc255be9d662fcf0d24820c9e7408187 Mon Sep 17 00:00:00 2001
From: Bob Peterson <rpete...@redhat.com>
Date: Fri, 16 Feb 2018 06:34:43 -0700
Subject: [PATCH] GFS2: Beginning of a debug trace point

This patch introduces a new debug trace point for GFS2 and uses it
to track a few fundamental things, like when the file system is
switched from RO to RW and back, and when files are switched from
ordinary to jdata and back.

Signed-off-by: Bob Peterson <rpete...@redhat.com>
---
 fs/gfs2/super.c      |  8 ++++++++
 fs/gfs2/trace_gfs2.h | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 03cebdef00bd3..23cb03624aff4 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -38,6 +38,7 @@
 #include "recovery.h"
 #include "rgrp.h"
 #include "super.h"
+#include "trace_gfs2.h"
 #include "trans.h"
 #include "util.h"
 #include "sys.h"
@@ -422,6 +423,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
 	struct gfs2_log_header_host head;
 	int error;
 
+	trace_gfs2_debug(sdp->sd_trans_gl, 0, "gfs2_make_fs_rw start");
 	error = init_threads(sdp);
 	if (error)
 		return error;
@@ -464,6 +466,7 @@ fail_threads:
 	sdp->sd_quotad_process = NULL;
 	kthread_stop(sdp->sd_logd_process);
 	sdp->sd_logd_process = NULL;
+	trace_gfs2_debug(sdp->sd_trans_gl, 0, "gfs2_make_fs_rw finished");
 	return error;
 }
 
@@ -853,6 +856,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 	struct gfs2_holder t_gh;
 	int error;
 
+	trace_gfs2_debug(sdp->sd_trans_gl, 0, "gfs2_make_fs_ro start");
 	if (sdp->sd_quotad_process) {
 		kthread_stop(sdp->sd_quotad_process);
 		sdp->sd_quotad_process = NULL;
@@ -881,6 +885,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 		gfs2_glock_dq_uninit(&t_gh);
 
 	gfs2_quota_cleanup(sdp);
+	trace_gfs2_debug(sdp->sd_trans_gl, 0, "gfs2_make_fs_ro finished.");
 	return 0;
 }
 
@@ -896,6 +901,7 @@ static void gfs2_put_super(struct super_block *sb)
 	int error;
 	struct gfs2_jdesc *jd;
 
+	trace_gfs2_debug(sdp->sd_trans_gl, 0, "put_super begin");
 	/* No more recovery requests */
 	set_bit(SDF_NORECOVERY, &sdp->sd_flags);
 	smp_mb();
@@ -914,6 +920,7 @@ restart:
 	spin_unlock(&sdp->sd_jindex_spin);
 
 	if (!(sb->s_flags & MS_RDONLY)) {
+		trace_gfs2_debug(sdp->sd_trans_gl, 0, "put_super rw");
 		error = gfs2_make_fs_ro(sdp);
 		if (error)
 			gfs2_io_error(sdp);
@@ -1228,6 +1235,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
 		*flags |= MS_RDONLY;
 
 	if ((sb->s_flags ^ *flags) & MS_RDONLY) {
+		trace_gfs2_debug(sdp->sd_trans_gl, 0, "remount fs");
 		if (*flags & MS_RDONLY)
 			error = gfs2_make_fs_ro(sdp);
 		else
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h
index d1de2edc27050..9095ed8479fb4 100644
--- a/fs/gfs2/trace_gfs2.h
+++ b/fs/gfs2/trace_gfs2.h
@@ -613,6 +613,38 @@ TRACE_EVENT(gfs2_rs,
 		  rs_func_name(__entry->func), (unsigned long)__entry->free)
 );
 
+/* Generic debug messages */
+TRACE_EVENT(gfs2_debug,
+
+	TP_PROTO(struct gfs2_glock *gl, int ret, const char *msg),
+
+	TP_ARGS(gl, ret, msg),
+
+	TP_STRUCT__entry(
+		__field(        dev_t,  dev                     )
+		__field(	u64,	glnum			)
+		__field(	u32,	gltype			)
+		__field(	int,	ret			)
+		__field(	int,	nrpages			)
+		__string(	msg,	msg			)
+	),
+
+	TP_fast_assign(
+		__entry->dev	= gl ? gl->gl_name.ln_sbd->sd_vfs->s_dev : 0;
+		__entry->glnum	= gl ? gl->gl_name.ln_number : 0;
+		__entry->gltype	= gl ? gl->gl_name.ln_type : 0;
+		__entry->ret = ret;
+		__entry->nrpages = gl ? (gfs2_glock2aspace(gl) ?
+					 gfs2_glock2aspace(gl)->nrpages : 0) : 0;
+		__assign_str(msg, msg);
+	),
+
+	TP_printk("%u,%u %u:%llx rc:%d pgs: %d %s",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->gltype,
+		  (unsigned long long)__entry->glnum, __entry->ret,
+		  __entry->nrpages, __get_str(msg))
+);
+
 #endif /* _TRACE_GFS2_H */
 
 /* This part must be outside protection */

Reply via email to