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; |