[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <170873668950.1861398.18421058347092974314.stgit@frogsfrogsfrogs>
Date: Fri, 23 Feb 2024 17:14:47 -0800
From: "Darrick J. Wong" <djwong@...nel.org>
To: akpm@...ux-foundation.org, daniel@...o.nz, kent.overstreet@...ux.dev,
djwong@...nel.org
Cc: linux-xfs@...r.kernel.org, linux-bcachefs@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 04/10] bcachefs: thread_with_stdio: fix
bch2_stdio_redirect_readline()
From: Kent Overstreet <kent.overstreet@...ux.dev>
This fixes a bug where we'd return data without waiting for a newline,
if data was present but a newline was not.
Signed-off-by: Kent Overstreet <kent.overstreet@...ux.dev>
Reviewed-by: Darrick J. Wong <djwong@...nel.org>
Signed-off-by: Darrick J. Wong <djwong@...nel.org>
---
fs/bcachefs/thread_with_file.c | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/fs/bcachefs/thread_with_file.c b/fs/bcachefs/thread_with_file.c
index eb8ab4c47a94b..830efb06ef0be 100644
--- a/fs/bcachefs/thread_with_file.c
+++ b/fs/bcachefs/thread_with_file.c
@@ -277,25 +277,36 @@ int bch2_stdio_redirect_read(struct stdio_redirect *stdio, char *ubuf, size_t le
int bch2_stdio_redirect_readline(struct stdio_redirect *stdio, char *ubuf, size_t len)
{
struct stdio_buf *buf = &stdio->input;
-
+ size_t copied = 0;
+ ssize_t ret = 0;
+again:
wait_event(buf->wait, stdio_redirect_has_input(stdio));
- if (stdio->done)
- return -1;
+ if (stdio->done) {
+ ret = -1;
+ goto out;
+ }
spin_lock(&buf->lock);
- int ret = min(len, buf->buf.nr);
- char *n = memchr(buf->buf.data, '\n', ret);
- if (!n)
- ret = min(ret, n + 1 - buf->buf.data);
- buf->buf.nr -= ret;
- memcpy(ubuf, buf->buf.data, ret);
+ size_t b = min(len, buf->buf.nr);
+ char *n = memchr(buf->buf.data, '\n', b);
+ if (n)
+ b = min_t(size_t, b, n + 1 - buf->buf.data);
+ buf->buf.nr -= b;
+ memcpy(ubuf, buf->buf.data, b);
memmove(buf->buf.data,
- buf->buf.data + ret,
+ buf->buf.data + b,
buf->buf.nr);
+ ubuf += b;
+ len -= b;
+ copied += b;
spin_unlock(&buf->lock);
wake_up(&buf->wait);
- return ret;
+
+ if (!n && len)
+ goto again;
+out:
+ return copied ?: ret;
}
__printf(3, 0)
Powered by blists - more mailing lists