printk: add generic functions to find KERN_<LEVEL> headers
authorJoe Perches <joe@perches.com>
Mon, 30 Jul 2012 21:40:09 +0000 (14:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Jul 2012 00:25:13 +0000 (17:25 -0700)
The current form of a KERN_<LEVEL> is "<.>".

Add printk_get_level and printk_skip_level functions to handle these
formats.

These functions centralize tests of KERN_<LEVEL> so a future modification
can change the KERN_<LEVEL> style and shorten the number of bytes consumed
by these headers.

[akpm@linux-foundation.org: fix build error and warning]
Signed-off-by: Joe Perches <joe@perches.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Wu Fengguang <wfg@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/printk.h
kernel/printk.c

index 1bec2f7a2d4236488af252d138188fa7c29e8369..6e12e1f09047654e313289d3390585b77582df89 100644 (file)
@@ -24,6 +24,32 @@ extern const char linux_proc_banner[];
  */
 #define KERN_CONT      "<c>"
 
+static inline int printk_get_level(const char *buffer)
+{
+       if (buffer[0] == '<' && buffer[1] && buffer[2] == '>') {
+               switch (buffer[1]) {
+               case '0' ... '7':
+               case 'd':       /* KERN_DEFAULT */
+               case 'c':       /* KERN_CONT */
+                       return buffer[1];
+               }
+       }
+       return 0;
+}
+
+static inline const char *printk_skip_level(const char *buffer)
+{
+       if (printk_get_level(buffer)) {
+               switch (buffer[1]) {
+               case '0' ... '7':
+               case 'd':       /* KERN_DEFAULT */
+               case 'c':       /* KERN_CONT */
+                       return buffer + 3;
+               }
+       }
+       return buffer;
+}
+
 extern int console_printk[];
 
 #define console_loglevel (console_printk[0])
index 852269adad25afc878c3f10e7a3bf059d086cca9..0d882a2f231ea24bd64f6c4f24882a1c6dad1374 100644 (file)
@@ -1487,6 +1487,7 @@ asmlinkage int vprintk_emit(int facility, int level,
        size_t text_len;
        enum log_flags lflags = 0;
        unsigned long flags;
+       int kern_level;
        int this_cpu;
        int printed_len = 0;
 
@@ -1543,17 +1544,20 @@ asmlinkage int vprintk_emit(int facility, int level,
        }
 
        /* strip syslog prefix and extract log level or control flags */
-       if (text[0] == '<' && text[1] && text[2] == '>') {
-               switch (text[1]) {
+       kern_level = printk_get_level(text);
+       if (kern_level) {
+               const char *end_of_header = printk_skip_level(text);
+               switch (kern_level) {
                case '0' ... '7':
                        if (level == -1)
-                               level = text[1] - '0';
+                               level = kern_level - '0';
                case 'd':       /* KERN_DEFAULT */
                        lflags |= LOG_PREFIX;
                case 'c':       /* KERN_CONT */
-                       text += 3;
-                       text_len -= 3;
+                       break;
                }
+               text_len -= end_of_header - text;
+               text = (char *)end_of_header;
        }
 
        if (level == -1)