Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 304113
b: refs/heads/master
c: c313af1
h: refs/heads/master
i:
  304111: aad3666
v: v3
  • Loading branch information
Kay Sievers authored and Greg Kroah-Hartman committed May 14, 2012
1 parent dc57476 commit 429e001
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 356c05d58af05d582e634b54b40050c73609617b
refs/heads/master: c313af145b9bc4fb8e8e0c83b8cfc10e1b894a50
105 changes: 61 additions & 44 deletions trunk/kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,13 +1264,13 @@ asmlinkage int vprintk_emit(int facility, int level,
const char *fmt, va_list args)
{
static int recursion_bug;
static char buf[LOG_LINE_MAX];
static size_t buflen;
static int buflevel;
static char cont_buf[LOG_LINE_MAX];
static size_t cont_len;
static int cont_level;
static struct task_struct *cont_task;
static char textbuf[LOG_LINE_MAX];
static struct task_struct *cont;
char *text = textbuf;
size_t textlen;
size_t text_len;
unsigned long flags;
int this_cpu;
bool newline = false;
Expand Down Expand Up @@ -1320,15 +1320,15 @@ asmlinkage int vprintk_emit(int facility, int level,
* The printf needs to come first; we need the syslog
* prefix which might be passed-in as a parameter.
*/
textlen = vscnprintf(text, sizeof(textbuf), fmt, args);
text_len = vscnprintf(text, sizeof(textbuf), fmt, args);

/* mark and strip a trailing newline */
if (textlen && text[textlen-1] == '\n') {
textlen--;
if (text_len && text[text_len-1] == '\n') {
text_len--;
newline = true;
}

/* strip syslog prefix and extract log level or flags */
/* strip syslog prefix and extract log level or control flags */
if (text[0] == '<' && text[1] && text[2] == '>') {
switch (text[1]) {
case '0' ... '7':
Expand All @@ -1338,49 +1338,67 @@ asmlinkage int vprintk_emit(int facility, int level,
prefix = true;
case 'c': /* KERN_CONT */
text += 3;
textlen -= 3;
text_len -= 3;
}
}

if (buflen && (prefix || dict || cont != current)) {
/* flush existing buffer */
log_store(facility, buflevel, NULL, 0, buf, buflen);
printed_len += buflen;
buflen = 0;
}
if (level == -1)
level = default_message_loglevel;

if (buflen == 0) {
/* remember level for first message in the buffer */
if (level == -1)
buflevel = default_message_loglevel;
else
buflevel = level;
if (dict) {
prefix = true;
newline = true;
}

if (buflen || !newline) {
/* append to existing buffer, or buffer until next message */
if (buflen + textlen > sizeof(buf))
textlen = sizeof(buf) - buflen;
memcpy(buf + buflen, text, textlen);
buflen += textlen;
}
if (!newline) {
if (cont_len && (prefix || cont_task != current)) {
/*
* Flush earlier buffer, which is either from a
* different thread, or when we got a new prefix.
*/
log_store(facility, cont_level, NULL, 0, cont_buf, cont_len);
cont_len = 0;
}

if (newline) {
/* end of line; flush buffer */
if (buflen) {
log_store(facility, buflevel,
dict, dictlen, buf, buflen);
printed_len += buflen;
buflen = 0;
} else {
log_store(facility, buflevel,
dict, dictlen, text, textlen);
printed_len += textlen;
if (!cont_len) {
cont_level = level;
cont_task = current;
}
cont = NULL;

/* buffer or append to earlier buffer from the same thread */
if (cont_len + text_len > sizeof(cont_buf))
text_len = sizeof(cont_buf) - cont_len;
memcpy(cont_buf + cont_len, text, text_len);
cont_len += text_len;
} else {
/* remember thread which filled the buffer */
cont = current;
if (cont_len && cont_task == current) {
if (prefix) {
/*
* New prefix from the same thread; flush. We
* either got no earlier newline, or we race
* with an interrupt.
*/
log_store(facility, cont_level,
NULL, 0, cont_buf, cont_len);
cont_len = 0;
}

/* append to the earlier buffer and flush */
if (cont_len + text_len > sizeof(cont_buf))
text_len = sizeof(cont_buf) - cont_len;
memcpy(cont_buf + cont_len, text, text_len);
cont_len += text_len;
log_store(facility, cont_level,
NULL, 0, cont_buf, cont_len);
cont_len = 0;
cont_task = NULL;
printed_len = cont_len;
} else {
/* ordinary single and terminated line */
log_store(facility, level,
dict, dictlen, text, text_len);
printed_len = text_len;
}
}

/*
Expand Down Expand Up @@ -1470,7 +1488,6 @@ EXPORT_SYMBOL(printk);
#define LOG_LINE_MAX 0
static struct log *log_from_idx(u32 idx) { return NULL; }
static u32 log_next(u32 idx) { return 0; }
static char *log_text(const struct log *msg) { return NULL; }
static void call_console_drivers(int level, const char *text, size_t len) {}
static size_t msg_print_text(const struct log *msg, bool syslog,
char *buf, size_t size) { return 0; }
Expand Down

0 comments on commit 429e001

Please sign in to comment.