[PATCH] better output

From: Petr Mladek
Date: Fri Feb 12 2021 - 12:43:54 EST


---
fs/seq_file.c | 21 +++++++++++++++++++++
include/linux/seq_file.h | 1 +
kernel/printk/printk.c | 20 ++++++++++++++------
3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 03a369ccd28c..364587eff9d2 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -376,6 +376,27 @@ void seq_escape(struct seq_file *m, const char *s, const char *esc)
}
EXPORT_SYMBOL(seq_escape);

+/**
+ * seq_escape+printf_format - print string into buffer, escaping
+ * characters that are escaped in printf format,
+ * @m: target buffer
+ * @s: string
+ *
+ * Puts string into buffer and escape characters that are
+ * escaped in printf format.
+ * Use seq_has_overflowed() to check for errors.
+ */
+void seq_escape_printf_format(struct seq_file *m, const char *s)
+{
+ char *buf;
+ size_t size = seq_get_buf(m, &buf);
+ int ret;
+
+ ret = string_escape_str(s, buf, size, ESCAPE_SPACE | ESCAPE_SPECIAL, NULL);
+ seq_commit(m, ret < size ? ret : -1);
+}
+EXPORT_SYMBOL(seq_escape_printf_format);
+
void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz)
{
char *buf;
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index b83b3ae3c877..cfc504a30429 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -127,6 +127,7 @@ void seq_put_hex_ll(struct seq_file *m, const char *delimiter,
unsigned long long v, unsigned int width);

void seq_escape(struct seq_file *m, const char *s, const char *esc);
+void seq_escape_printf_format(struct seq_file *m, const char *s);
void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz);

void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index adf545ba9eb9..77a43b483b7b 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -783,6 +783,8 @@ static const char *ps_get_module_name(const struct printk_fmt_sec *ps)
}
#endif /* CONFIG_MODULES */

+static u16 parse_prefix(const char *text, int *level, enum log_flags *lflags);
+
static int debugfs_pf_show(struct seq_file *s, void *v)
{
struct module *mod = s->file->f_inode->i_private;
@@ -804,11 +806,17 @@ static int debugfs_pf_show(struct seq_file *s, void *v)
}

for (fptr = ps->start; fptr < ps->end; fptr++) {
- /* For callsites without KERN_SOH + level preamble. */
- if (unlikely(*fptr[0] != KERN_SOH_ASCII))
- seq_printf(s, "%c%d", KERN_SOH_ASCII,
- MESSAGE_LOGLEVEL_DEFAULT);
- seq_printf(s, "%s%c", *fptr, '\0');
+ int level;
+ u16 prefix_len;
+ const char *fmt;
+
+ level = LOGLEVEL_DEFAULT;
+ prefix_len = parse_prefix(fptr[0], &level, NULL);
+ fmt = fptr[0] + prefix_len;
+
+ seq_printf(s, "<%d> ", level);
+ seq_escape_printf_format(s, fmt);
+ seq_printf(s, "\n");
}

out_unlock:
@@ -2113,7 +2121,7 @@ static inline u32 printk_caller_id(void)
*
* Return: The length of the parsed level and control flags.
*/
-static u16 parse_prefix(char *text, int *level, enum log_flags *lflags)
+static u16 parse_prefix(const char *text, int *level, enum log_flags *lflags)
{
u16 prefix_len = 0;
int kern_level;
--
2.26.2