diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/printk.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index ff05361962e1..cdfba44fedf0 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -862,26 +862,49 @@ static int syslog_print(char __user *buf, int size) | |||
| 862 | { | 862 | { |
| 863 | char *text; | 863 | char *text; |
| 864 | struct log *msg; | 864 | struct log *msg; |
| 865 | int len; | 865 | int len = 0; |
| 866 | 866 | ||
| 867 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | 867 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); |
| 868 | if (!text) | 868 | if (!text) |
| 869 | return -ENOMEM; | 869 | return -ENOMEM; |
| 870 | 870 | ||
| 871 | raw_spin_lock_irq(&logbuf_lock); | 871 | while (size > 0) { |
| 872 | if (syslog_seq < log_first_seq) { | 872 | size_t n; |
| 873 | /* messages are gone, move to first one */ | 873 | |
| 874 | syslog_seq = log_first_seq; | 874 | raw_spin_lock_irq(&logbuf_lock); |
| 875 | syslog_idx = log_first_idx; | 875 | if (syslog_seq < log_first_seq) { |
| 876 | } | 876 | /* messages are gone, move to first one */ |
| 877 | msg = log_from_idx(syslog_idx); | 877 | syslog_seq = log_first_seq; |
| 878 | len = msg_print_text(msg, true, text, LOG_LINE_MAX); | 878 | syslog_idx = log_first_idx; |
| 879 | syslog_idx = log_next(syslog_idx); | 879 | } |
| 880 | syslog_seq++; | 880 | if (syslog_seq == log_next_seq) { |
| 881 | raw_spin_unlock_irq(&logbuf_lock); | 881 | raw_spin_unlock_irq(&logbuf_lock); |
| 882 | break; | ||
| 883 | } | ||
| 884 | msg = log_from_idx(syslog_idx); | ||
| 885 | n = msg_print_text(msg, true, text, LOG_LINE_MAX); | ||
| 886 | if (n <= size) { | ||
| 887 | syslog_idx = log_next(syslog_idx); | ||
| 888 | syslog_seq++; | ||
| 889 | } else | ||
| 890 | n = 0; | ||
| 891 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 892 | |||
| 893 | if (!n) | ||
| 894 | break; | ||
| 882 | 895 | ||
| 883 | if (len > 0 && copy_to_user(buf, text, len)) | 896 | len += n; |
| 884 | len = -EFAULT; | 897 | size -= n; |
| 898 | buf += n; | ||
| 899 | n = copy_to_user(buf - n, text, n); | ||
| 900 | |||
| 901 | if (n) { | ||
| 902 | len -= n; | ||
| 903 | if (!len) | ||
| 904 | len = -EFAULT; | ||
| 905 | break; | ||
| 906 | } | ||
| 907 | } | ||
| 885 | 908 | ||
| 886 | kfree(text); | 909 | kfree(text); |
| 887 | return len; | 910 | return len; |
