return size;
 }
 
+/*
+ * Define how much of the log buffer we could take at maximum. The value
+ * must be greater than two. Note that only half of the buffer is available
+ * when the index points to the middle.
+ */
+#define MAX_LOG_TAKE_PART 4
+static const char trunc_msg[] = "<truncated>";
+
+static u32 truncate_msg(u16 *text_len, u16 *trunc_msg_len,
+                       u16 *dict_len, u32 *pad_len)
+{
+       /*
+        * The message should not take the whole buffer. Otherwise, it might
+        * get removed too soon.
+        */
+       u32 max_text_len = log_buf_len / MAX_LOG_TAKE_PART;
+       if (*text_len > max_text_len)
+               *text_len = max_text_len;
+       /* enable the warning message */
+       *trunc_msg_len = strlen(trunc_msg);
+       /* disable the "dict" completely */
+       *dict_len = 0;
+       /* compute the size again, count also the warning message */
+       return msg_used_size(*text_len + *trunc_msg_len, 0, pad_len);
+}
+
 /* insert record into the buffer, discard old ones, update heads */
 static void log_store(int facility, int level,
                      enum log_flags flags, u64 ts_nsec,
 {
        struct printk_log *msg;
        u32 size, pad_len;
+       u16 trunc_msg_len = 0;
 
        /* number of '\0' padding bytes to next message */
        size = msg_used_size(text_len, dict_len, &pad_len);
 
-       /* if message does not fit empty log buffer, ignore it */
-       if (log_make_free_space(size))
-               return;
+       if (log_make_free_space(size)) {
+               /* truncate the message if it is too long for empty buffer */
+               size = truncate_msg(&text_len, &trunc_msg_len,
+                                   &dict_len, &pad_len);
+               /* survive when the log buffer is too small for trunc_msg */
+               if (log_make_free_space(size))
+                       return;
+       }
 
        if (log_next_idx + size + sizeof(struct printk_log) > log_buf_len) {
                /*
        msg = (struct printk_log *)(log_buf + log_next_idx);
        memcpy(log_text(msg), text, text_len);
        msg->text_len = text_len;
+       if (trunc_msg_len) {
+               memcpy(log_text(msg) + text_len, trunc_msg, trunc_msg_len);
+               msg->text_len += trunc_msg_len;
+       }
        memcpy(log_dict(msg), dict, dict_len);
        msg->dict_len = dict_len;
        msg->facility = facility;