From e2ee3eaab72a059b29f079290b5773509df9524f Mon Sep 17 00:00:00 2001
From: Kent Overstreet <kent.overstreet@gmail.com>
Date: Wed, 6 Nov 2019 15:32:11 -0500
Subject: [PATCH] bcachefs: Add an option for fsck error ratelimiting

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
---
 fs/bcachefs/error.c | 13 +++++++++----
 fs/bcachefs/error.h |  1 +
 fs/bcachefs/opts.h  | 11 +++++++++++
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c
index 304ff92500be9..5a5cfee623e2d 100644
--- a/fs/bcachefs/error.c
+++ b/fs/bcachefs/error.c
@@ -64,7 +64,7 @@ void bch2_io_error(struct bch_dev *ca)
 enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags,
 				const char *fmt, ...)
 {
-	struct fsck_err_state *s;
+	struct fsck_err_state *s = NULL;
 	va_list args;
 	bool fix = false, print = true, suppressing = false;
 	char _buf[sizeof(s->buf)], *buf = _buf;
@@ -99,8 +99,13 @@ enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags,
 found:
 	list_move(&s->list, &c->fsck_errors);
 	s->nr++;
-	suppressing	= s->nr == FSCK_ERR_RATELIMIT_NR;
-	print		= s->nr <= FSCK_ERR_RATELIMIT_NR;
+	if (c->opts.ratelimit_errors &&
+	    s->nr >= FSCK_ERR_RATELIMIT_NR) {
+		if (s->nr == FSCK_ERR_RATELIMIT_NR)
+			suppressing = true;
+		else
+			print = false;
+	}
 	buf		= s->buf;
 print:
 	va_start(args, fmt);
@@ -156,7 +161,7 @@ void bch2_flush_fsck_errs(struct bch_fs *c)
 	mutex_lock(&c->fsck_error_lock);
 
 	list_for_each_entry_safe(s, n, &c->fsck_errors, list) {
-		if (s->nr > FSCK_ERR_RATELIMIT_NR)
+		if (s->ratelimited)
 			bch_err(c, "Saw %llu errors like:\n    %s", s->nr, s->buf);
 
 		list_del(&s->list);
diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h
index 2591e12305b71..7dcb0f6552fcc 100644
--- a/fs/bcachefs/error.h
+++ b/fs/bcachefs/error.h
@@ -114,6 +114,7 @@ struct fsck_err_state {
 	struct list_head	list;
 	const char		*fmt;
 	u64			nr;
+	bool			ratelimited;
 	char			buf[512];
 };
 
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index a6f1d3ec7b901..2bd8bce432695 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -68,6 +68,12 @@ enum opt_type {
  *  - helptext
  */
 
+#ifdef __KERNEL__
+#define RATELIMIT_ERRORS true
+#else
+#define RATELIMIT_ERRORS false
+#endif
+
 #define BCH_OPTS()							\
 	x(block_size,			u16,				\
 	  OPT_FORMAT,							\
@@ -227,6 +233,11 @@ enum opt_type {
 	  OPT_BOOL(),							\
 	  NO_SB_OPT,			false,				\
 	  NULL,		"Fix errors during fsck without asking")	\
+	x(ratelimit_errors,		u8,				\
+	  OPT_MOUNT,							\
+	  OPT_BOOL(),							\
+	  NO_SB_OPT,			RATELIMIT_ERRORS,		\
+	  NULL,		"Ratelimit error messages during fsck")		\
 	x(nochanges,			u8,				\
 	  OPT_MOUNT,							\
 	  OPT_BOOL(),							\
-- 
2.30.2