summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-05-30 02:37:39 +0200
committerKent Overstreet <kent.overstreet@linux.dev>2024-07-15 01:00:14 +0200
commitd37dd9b60487357cf831720383e335ee9baf5f25 (patch)
treefed5d723723c79d7803f1303a2ecb223b0482467 /fs
parentbcachefs: twf: convert bch2_stdio_redirect_readline() to darray (diff)
downloadlinux-d37dd9b60487357cf831720383e335ee9baf5f25.tar.xz
linux-d37dd9b60487357cf831720383e335ee9baf5f25.zip
bcachefs: bch2_stdio_redirect_readline_timeout()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/thread_with_file.c25
-rw-r--r--fs/bcachefs/thread_with_file.h1
2 files changed, 23 insertions, 3 deletions
diff --git a/fs/bcachefs/thread_with_file.c b/fs/bcachefs/thread_with_file.c
index 080afa7eff25..0807ce9b171a 100644
--- a/fs/bcachefs/thread_with_file.c
+++ b/fs/bcachefs/thread_with_file.c
@@ -364,13 +364,21 @@ int bch2_stdio_redirect_read(struct stdio_redirect *stdio, char *ubuf, size_t le
return ret;
}
-int bch2_stdio_redirect_readline(struct stdio_redirect *stdio, darray_char *line)
+int bch2_stdio_redirect_readline_timeout(struct stdio_redirect *stdio,
+ darray_char *line,
+ unsigned long timeout)
{
+ unsigned long until = jiffies + timeout, t;
struct stdio_buf *buf = &stdio->input;
size_t seen = 0;
again:
- wait_event_timeout(buf->wait, stdio_redirect_has_more_input(stdio, seen),
- sysctl_hung_task_timeout_secs * HZ / 2);
+ t = timeout != MAX_SCHEDULE_TIMEOUT
+ ? max_t(long, until - jiffies, 0)
+ : timeout;
+
+ t = min(t, sysctl_hung_task_timeout_secs * HZ / 2);
+
+ wait_event_timeout(buf->wait, stdio_redirect_has_more_input(stdio, seen), t);
if (stdio->done)
return -1;
@@ -378,6 +386,12 @@ again:
spin_lock(&buf->lock);
seen = buf->buf.nr;
char *n = memchr(buf->buf.data, '\n', seen);
+
+ if (!n && timeout != MAX_SCHEDULE_TIMEOUT && jiffies >= until) {
+ spin_unlock(&buf->lock);
+ return -ETIME;
+ }
+
if (!n) {
buf->waiting_for_line = true;
spin_unlock(&buf->lock);
@@ -408,6 +422,11 @@ again:
return 0;
}
+int bch2_stdio_redirect_readline(struct stdio_redirect *stdio, darray_char *line)
+{
+ return bch2_stdio_redirect_readline_timeout(stdio, line, MAX_SCHEDULE_TIMEOUT);
+}
+
__printf(3, 0)
static ssize_t bch2_darray_vprintf(darray_char *out, gfp_t gfp, const char *fmt, va_list args)
{
diff --git a/fs/bcachefs/thread_with_file.h b/fs/bcachefs/thread_with_file.h
index e415dc2e2fb1..72497b921911 100644
--- a/fs/bcachefs/thread_with_file.h
+++ b/fs/bcachefs/thread_with_file.h
@@ -72,6 +72,7 @@ int bch2_run_thread_with_stdout(struct thread_with_stdio *,
const struct thread_with_stdio_ops *);
int bch2_stdio_redirect_read(struct stdio_redirect *, char *, size_t);
+int bch2_stdio_redirect_readline_timeout(struct stdio_redirect *, darray_char *, unsigned long);
int bch2_stdio_redirect_readline(struct stdio_redirect *, darray_char *);
__printf(3, 0) ssize_t bch2_stdio_redirect_vprintf(struct stdio_redirect *, bool, const char *, va_list);