1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _BCACHEFS_THREAD_WITH_FILE_H |
3 | #define _BCACHEFS_THREAD_WITH_FILE_H |
4 | |
5 | #include "thread_with_file_types.h" |
6 | |
7 | /* |
8 | * Thread with file: Run a kthread and connect it to a file descriptor, so that |
9 | * it can be interacted with via fd read/write methods and closing the file |
10 | * descriptor stops the kthread. |
11 | * |
12 | * We have two different APIs: |
13 | * |
14 | * thread_with_file, the low level version. |
15 | * You get to define the full file_operations, including your release function, |
16 | * which means that you must call bch2_thread_with_file_exit() from your |
17 | * .release method |
18 | * |
19 | * thread_with_stdio, the higher level version |
20 | * This implements full piping of input and output, including .poll. |
21 | * |
22 | * Notes on behaviour: |
23 | * - kthread shutdown behaves like writing or reading from a pipe that has been |
24 | * closed |
25 | * - Input and output buffers are 4096 bytes, although buffers may in some |
26 | * situations slightly exceed that limit so as to avoid chopping off a |
27 | * message in the middle in nonblocking mode. |
28 | * - Input/output buffers are lazily allocated, with GFP_NOWAIT allocations - |
29 | * should be fine but might change in future revisions. |
30 | * - Output buffer may grow past 4096 bytes to deal with messages that are |
31 | * bigger than 4096 bytes |
32 | * - Writing may be done blocking or nonblocking; in nonblocking mode, we only |
33 | * drop entire messages. |
34 | * |
35 | * To write, use stdio_redirect_printf() |
36 | * To read, use stdio_redirect_read() or stdio_redirect_readline() |
37 | */ |
38 | |
39 | struct task_struct; |
40 | |
41 | struct thread_with_file { |
42 | struct task_struct *task; |
43 | int ret; |
44 | bool done; |
45 | }; |
46 | |
47 | void bch2_thread_with_file_exit(struct thread_with_file *); |
48 | int bch2_run_thread_with_file(struct thread_with_file *, |
49 | const struct file_operations *, |
50 | int (*fn)(void *)); |
51 | |
52 | struct thread_with_stdio; |
53 | |
54 | struct thread_with_stdio_ops { |
55 | void (*exit)(struct thread_with_stdio *); |
56 | int (*fn)(struct thread_with_stdio *); |
57 | long (*unlocked_ioctl)(struct thread_with_stdio *, unsigned int, unsigned long); |
58 | }; |
59 | |
60 | struct thread_with_stdio { |
61 | struct thread_with_file thr; |
62 | struct stdio_redirect stdio; |
63 | const struct thread_with_stdio_ops *ops; |
64 | }; |
65 | |
66 | void bch2_thread_with_stdio_init(struct thread_with_stdio *, |
67 | const struct thread_with_stdio_ops *); |
68 | int __bch2_run_thread_with_stdio(struct thread_with_stdio *); |
69 | int bch2_run_thread_with_stdio(struct thread_with_stdio *, |
70 | const struct thread_with_stdio_ops *); |
71 | int bch2_run_thread_with_stdout(struct thread_with_stdio *, |
72 | const struct thread_with_stdio_ops *); |
73 | int bch2_stdio_redirect_read(struct stdio_redirect *, char *, size_t); |
74 | int bch2_stdio_redirect_readline(struct stdio_redirect *, char *, size_t); |
75 | |
76 | __printf(3, 0) ssize_t bch2_stdio_redirect_vprintf(struct stdio_redirect *, bool, const char *, va_list); |
77 | __printf(3, 4) ssize_t bch2_stdio_redirect_printf(struct stdio_redirect *, bool, const char *, ...); |
78 | |
79 | #endif /* _BCACHEFS_THREAD_WITH_FILE_H */ |
80 | |