From 572e0596e94f8c8692ef6f345b2aa28112972fb0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=81ukasz=20Stelmach?= Date: Thu, 16 Dec 2021 00:32:13 +0100 Subject: [PATCH] Import stdio handling code to logger_aio_write() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Copy the stdio handling code from logger_write_iter() Change-Id: I94be88c5db2e7482106ddd537d763726a89aad5a Signed-off-by: Łukasz Stelmach --- kernel/logger.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/kernel/logger.c b/kernel/logger.c index b5a8d2b..9dbe22a 100644 --- a/kernel/logger.c +++ b/kernel/logger.c @@ -623,6 +623,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, struct logger_entry header; struct timespec now; ssize_t ret = 0; + size_t count; bool from_stdio = false; if (writer->tag && writer->prio >= 2) @@ -646,7 +647,93 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, /* Prepend messages from STDOUT and STDERR with a tag and prio */ if (from_stdio) { - return 0; + char *p; + size_t chunk_len = 0, c = 0; + /* -2 : priority byte and tag terminating '\0' */ + size_t max_payload = LOGGER_ENTRY_MAX_PAYLOAD - writer->tag_len - 2; + + if (writer->owner != current->group_leader) { + struct file *nfile; + + nfile = make_new_file(file); + if (IS_ERR(nfile)) { + mutex_unlock(&log->mutex); + return PTR_ERR(nfile); + } + + file = nfile; + writer = file->private_data; + } + + /* Allocate STDIO line buffer */ + if (!writer->buffer) { + writer->buffer = kzalloc(LOGGER_ENTRY_MAX_PAYLOAD, GFP_KERNEL); + writer->b_off = 0; + + if (!writer->buffer) { + mutex_unlock(&log->mutex); + return -ENOMEM; + } + } + + /* flush message from a different thread */ + if (writer->b_owner != current && writer->b_off) + flush_thread_data(file); + + count = 0; + /* -1 : leave space for message terminating '\0' */ + c = min_t(size_t, iov_iter_count(from), + max_payload - writer->b_off - 1); + + do { + size_t i; + + if (copy_from_iter(writer->buffer + writer->b_off, c, from) != c) { + mutex_unlock(&log->mutex); + return -EFAULT; + } + count += c; + p = NULL; + for (i = 0; i < c; ++i) { + char *t = &writer->buffer[writer->b_off + i]; + if (*t == '\0') + *t = '\n'; + if (*t == '\n') + p = t; + } + if (p) { + *p++ = '\0'; + chunk_len = p - writer->buffer; + } else { + writer->buffer[writer->b_off + c++] = '\0'; + p = &writer->buffer[writer->b_off + c]; + chunk_len = p - writer->buffer; + + BUG_ON(chunk_len > max_payload); + if (chunk_len < max_payload ) { + writer->b_off = writer->b_off + c - 1; + continue; + } + + } + + header.len = chunk_len + writer->tag_len + 2; + fix_up_readers(log, sizeof(struct logger_entry) + header.len); + + write_log_data(log, &header, writer, chunk_len); + + /* move the remaining part of the message */ + memmove(writer->buffer, p, writer->b_off + c - chunk_len); + + /* new b_off points where the rimainder of the string ends */ + writer->b_off = writer->b_off + c - chunk_len; + writer->buffer[writer->b_off] = '\0'; + + } while ((c = min_t(size_t, iov_iter_count(from), max_payload - 1))); + + /* save for remaining unfinished line */ + writer->b_header = header; + writer->b_owner = current; } else { orig = log->w_off; -- 2.34.1