| /* 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_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); | |
| __printf(3, 4) ssize_t bch2_stdio_redirect_printf(struct stdio_redirect *, bool, const char *, ...); | |
| #endif /* _BCACHEFS_THREAD_WITH_FILE_H */ |