summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/super.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-12-04 20:15:23 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2024-01-01 11:47:40 -0500
commit2b41226d7f4b3b836a2a3e4ce08ab18ba03f0cd0 (patch)
treef8fcc85547c7c832cd757d423388abf4e1774118 /fs/bcachefs/super.c
parentbbefcd910d9f992db2d8ba4b8f96a77d8fb131d7 (diff)
downloadlinux-2b41226d7f4b3b836a2a3e4ce08ab18ba03f0cd0.tar.gz
linux-2b41226d7f4b3b836a2a3e4ce08ab18ba03f0cd0.tar.bz2
linux-2b41226d7f4b3b836a2a3e4ce08ab18ba03f0cd0.zip
bcachefs: Add ability to redirect log output
Upcoming patches are going to add two new ioctls for running fsck in the kernel, but pretending that we're running our normal userspace fsck. This patch adds some plumbing for redirecting our normal log messages away from the dmesg log to a thread_with_file file descriptor - via a struct log_output, which will be consumed by the fsck f_op's read method. The new ioctls will allow for running fsck in the kernel against an offline filesystem (without mounting it), and an online filesystem. For an offline filesystem we need a way to pass in a pointer to the log_output, which is done via a new hidden opts.h option. For online fsck, we can set c->output directly, but only want to redirect log messages from the thread running fsck - hence the new c->output_filter method. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/super.c')
-rw-r--r--fs/bcachefs/super.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 1ec66bb8a63f..83e5423fd005 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -86,6 +86,32 @@ const char * const bch2_fs_flag_strs[] = {
NULL
};
+void __bch2_print(struct bch_fs *c, const char *fmt, ...)
+{
+ struct log_output *output = c->output;
+ va_list args;
+
+ if (c->output_filter && c->output_filter != current)
+ output = NULL;
+
+ va_start(args, fmt);
+ if (likely(!output)) {
+ vprintk(fmt, args);
+ } else {
+ unsigned long flags;
+
+ if (fmt[0] == KERN_SOH[0])
+ fmt += 2;
+
+ spin_lock_irqsave(&output->lock, flags);
+ prt_vprintf(&output->buf, fmt, args);
+ spin_unlock_irqrestore(&output->lock, flags);
+
+ wake_up(&output->wait);
+ }
+ va_end(args);
+}
+
#define KTYPE(type) \
static const struct attribute_group type ## _group = { \
.attrs = type ## _files \
@@ -712,6 +738,8 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
goto out;
}
+ c->output = (void *)(unsigned long) opts.log_output;
+
__module_get(THIS_MODULE);
closure_init(&c->cl, NULL);