aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2024-02-07 11:43:32 -0800
committerKent Overstreet <kent.overstreet@linux.dev>2024-03-13 21:22:08 -0400
commitfcb1620edd4d59eff4b3466be1d61263cea958a8 (patch)
treec8c59c73272624d0eba47576bdc956b697ffeedb
parenta5a650d6472f238191d98d8aba7536a9fb3d9f99 (diff)
downloadvfs-fcb1620edd4d59eff4b3466be1d61263cea958a8.tar.gz
bcachefs: thread_with_file: allow creation of readonly files
Create a new run_thread_with_stdout function that opens a file in O_RDONLY mode so that the kernel can write things to userspace but userspace cannot write to the kernel. This will be used to convey xfs health event information to userspace. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/thread_with_file.c36
-rw-r--r--fs/bcachefs/thread_with_file.h3
2 files changed, 39 insertions, 0 deletions
diff --git a/fs/bcachefs/thread_with_file.c b/fs/bcachefs/thread_with_file.c
index 96ac2b2c60e122..d1cd5f4ab06ede 100644
--- a/fs/bcachefs/thread_with_file.c
+++ b/fs/bcachefs/thread_with_file.c
@@ -231,6 +231,22 @@ static __poll_t thread_with_stdio_poll(struct file *file, struct poll_table_stru
return mask;
}
+static __poll_t thread_with_stdout_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct thread_with_stdio *thr =
+ container_of(file->private_data, struct thread_with_stdio, thr);
+
+ poll_wait(file, &thr->stdio.output.wait, wait);
+
+ __poll_t mask = 0;
+
+ if (stdio_redirect_has_output(&thr->stdio))
+ mask |= EPOLLIN;
+ if (thr->thr.done)
+ mask |= EPOLLHUP|EPOLLERR;
+ return mask;
+}
+
static const struct file_operations thread_with_stdio_fops = {
.llseek = no_llseek,
.read = thread_with_stdio_read,
@@ -239,6 +255,13 @@ static const struct file_operations thread_with_stdio_fops = {
.release = thread_with_stdio_release,
};
+static const struct file_operations thread_with_stdout_fops = {
+ .llseek = no_llseek,
+ .read = thread_with_stdio_read,
+ .poll = thread_with_stdout_poll,
+ .release = thread_with_stdio_release,
+};
+
static int thread_with_stdio_fn(void *arg)
{
struct thread_with_stdio *thr = arg;
@@ -261,6 +284,19 @@ int bch2_run_thread_with_stdio(struct thread_with_stdio *thr,
return bch2_run_thread_with_file(&thr->thr, &thread_with_stdio_fops, thread_with_stdio_fn);
}
+int bch2_run_thread_with_stdout(struct thread_with_stdio *thr,
+ void (*exit)(struct thread_with_stdio *),
+ void (*fn)(struct thread_with_stdio *))
+{
+ stdio_buf_init(&thr->stdio.input);
+ stdio_buf_init(&thr->stdio.output);
+ thr->exit = exit;
+ thr->fn = fn;
+
+ return bch2_run_thread_with_file(&thr->thr, &thread_with_stdout_fops, thread_with_stdio_fn);
+}
+EXPORT_SYMBOL_GPL(bch2_run_thread_with_stdout);
+
int bch2_stdio_redirect_read(struct stdio_redirect *stdio, char *ubuf, size_t len)
{
struct stdio_buf *buf = &stdio->input;
diff --git a/fs/bcachefs/thread_with_file.h b/fs/bcachefs/thread_with_file.h
index f06f8ff19a790a..2b687723d6b9b7 100644
--- a/fs/bcachefs/thread_with_file.h
+++ b/fs/bcachefs/thread_with_file.h
@@ -59,6 +59,9 @@ struct thread_with_stdio {
int bch2_run_thread_with_stdio(struct thread_with_stdio *,
void (*exit)(struct thread_with_stdio *),
void (*fn)(struct thread_with_stdio *));
+int bch2_run_thread_with_stdout(struct thread_with_stdio *,
+ void (*exit)(struct thread_with_stdio *),
+ void (*fn)(struct thread_with_stdio *));
int bch2_stdio_redirect_read(struct stdio_redirect *, char *, size_t);
int bch2_stdio_redirect_readline(struct stdio_redirect *, char *, size_t);