02bed83d59
We need to initialize the stdio redirects before they're used. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
80 lines
2.9 KiB
C
80 lines
2.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _BCACHEFS_THREAD_WITH_FILE_H
|
|
#define _BCACHEFS_THREAD_WITH_FILE_H
|
|
|
|
#include "thread_with_file_types.h"
|
|
|
|
/*
|
|
* Thread with file: Run a kthread and connect it to a file descriptor, so that
|
|
* it can be interacted with via fd read/write methods and closing the file
|
|
* descriptor stops the kthread.
|
|
*
|
|
* We have two different APIs:
|
|
*
|
|
* thread_with_file, the low level version.
|
|
* You get to define the full file_operations, including your release function,
|
|
* which means that you must call bch2_thread_with_file_exit() from your
|
|
* .release method
|
|
*
|
|
* thread_with_stdio, the higher level version
|
|
* This implements full piping of input and output, including .poll.
|
|
*
|
|
* Notes on behaviour:
|
|
* - kthread shutdown behaves like writing or reading from a pipe that has been
|
|
* closed
|
|
* - Input and output buffers are 4096 bytes, although buffers may in some
|
|
* situations slightly exceed that limit so as to avoid chopping off a
|
|
* message in the middle in nonblocking mode.
|
|
* - Input/output buffers are lazily allocated, with GFP_NOWAIT allocations -
|
|
* should be fine but might change in future revisions.
|
|
* - Output buffer may grow past 4096 bytes to deal with messages that are
|
|
* bigger than 4096 bytes
|
|
* - Writing may be done blocking or nonblocking; in nonblocking mode, we only
|
|
* drop entire messages.
|
|
*
|
|
* To write, use stdio_redirect_printf()
|
|
* To read, use stdio_redirect_read() or stdio_redirect_readline()
|
|
*/
|
|
|
|
struct task_struct;
|
|
|
|
struct thread_with_file {
|
|
struct task_struct *task;
|
|
int ret;
|
|
bool done;
|
|
};
|
|
|
|
void bch2_thread_with_file_exit(struct thread_with_file *);
|
|
int bch2_run_thread_with_file(struct thread_with_file *,
|
|
const struct file_operations *,
|
|
int (*fn)(void *));
|
|
|
|
struct thread_with_stdio;
|
|
|
|
struct thread_with_stdio_ops {
|
|
void (*exit)(struct thread_with_stdio *);
|
|
int (*fn)(struct thread_with_stdio *);
|
|
long (*unlocked_ioctl)(struct thread_with_stdio *, unsigned int, unsigned long);
|
|
};
|
|
|
|
struct thread_with_stdio {
|
|
struct thread_with_file thr;
|
|
struct stdio_redirect stdio;
|
|
const struct thread_with_stdio_ops *ops;
|
|
};
|
|
|
|
void bch2_thread_with_stdio_init(struct thread_with_stdio *,
|
|
const struct thread_with_stdio_ops *);
|
|
int __bch2_run_thread_with_stdio(struct thread_with_stdio *);
|
|
int bch2_run_thread_with_stdio(struct thread_with_stdio *,
|
|
const struct thread_with_stdio_ops *);
|
|
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(struct stdio_redirect *, char *, size_t);
|
|
|
|
__printf(3, 0) ssize_t bch2_stdio_redirect_vprintf(struct stdio_redirect *, bool, const char *, va_list);
|
|
__printf(3, 4) ssize_t bch2_stdio_redirect_printf(struct stdio_redirect *, bool, const char *, ...);
|
|
|
|
#endif /* _BCACHEFS_THREAD_WITH_FILE_H */
|