82 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			3.0 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_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 */
 |