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 75 int bch2_stdio_redirect_readline_timeout(struct stdio_redirect *, darray_char *, unsigned long); 76 int bch2_stdio_redirect_readline(struct stdio_redirect *, darray_char *); 77 78 __printf(3, 0) ssize_t bch2_stdio_redirect_vprintf(struct stdio_redirect *, bool, const char *, va_list); 79 __printf(3, 4) ssize_t bch2_stdio_redirect_printf(struct stdio_redirect *, bool, const char *, ...); 80 81 #endif /* _BCACHEFS_THREAD_WITH_FILE_H */ 82