diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-05-30 02:37:39 +0200 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-07-15 01:00:14 +0200 |
commit | d37dd9b60487357cf831720383e335ee9baf5f25 (patch) | |
tree | fed5d723723c79d7803f1303a2ecb223b0482467 /fs | |
parent | bcachefs: twf: convert bch2_stdio_redirect_readline() to darray (diff) | |
download | linux-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.c | 25 | ||||
-rw-r--r-- | fs/bcachefs/thread_with_file.h | 1 |
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); |