16881f68fSopenharmony_ci/*
26881f68fSopenharmony_ci  FUSE: Filesystem in Userspace
36881f68fSopenharmony_ci  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
46881f68fSopenharmony_ci
56881f68fSopenharmony_ci  This program can be distributed under the terms of the GNU LGPLv2.
66881f68fSopenharmony_ci  See the file COPYING.LIB
76881f68fSopenharmony_ci*/
86881f68fSopenharmony_ci
96881f68fSopenharmony_ci#include "fuse.h"
106881f68fSopenharmony_ci#include "fuse_lowlevel.h"
116881f68fSopenharmony_ci
126881f68fSopenharmony_cistruct mount_opts;
136881f68fSopenharmony_ci
146881f68fSopenharmony_cistruct fuse_req {
156881f68fSopenharmony_ci	struct fuse_session *se;
166881f68fSopenharmony_ci	uint64_t unique;
176881f68fSopenharmony_ci	int ctr;
186881f68fSopenharmony_ci	pthread_mutex_t lock;
196881f68fSopenharmony_ci	struct fuse_ctx ctx;
206881f68fSopenharmony_ci	struct fuse_chan *ch;
216881f68fSopenharmony_ci	int interrupted;
226881f68fSopenharmony_ci	unsigned int ioctl_64bit : 1;
236881f68fSopenharmony_ci	union {
246881f68fSopenharmony_ci		struct {
256881f68fSopenharmony_ci			uint64_t unique;
266881f68fSopenharmony_ci		} i;
276881f68fSopenharmony_ci		struct {
286881f68fSopenharmony_ci			fuse_interrupt_func_t func;
296881f68fSopenharmony_ci			void *data;
306881f68fSopenharmony_ci		} ni;
316881f68fSopenharmony_ci	} u;
326881f68fSopenharmony_ci	struct fuse_req *next;
336881f68fSopenharmony_ci	struct fuse_req *prev;
346881f68fSopenharmony_ci};
356881f68fSopenharmony_ci
366881f68fSopenharmony_cistruct fuse_notify_req {
376881f68fSopenharmony_ci	uint64_t unique;
386881f68fSopenharmony_ci	void (*reply)(struct fuse_notify_req *, fuse_req_t, fuse_ino_t,
396881f68fSopenharmony_ci		      const void *, const struct fuse_buf *);
406881f68fSopenharmony_ci	struct fuse_notify_req *next;
416881f68fSopenharmony_ci	struct fuse_notify_req *prev;
426881f68fSopenharmony_ci};
436881f68fSopenharmony_ci
446881f68fSopenharmony_cistruct fuse_session {
456881f68fSopenharmony_ci	char *mountpoint;
466881f68fSopenharmony_ci	volatile int exited;
476881f68fSopenharmony_ci	int fd;
486881f68fSopenharmony_ci	struct fuse_custom_io *io;
496881f68fSopenharmony_ci	struct mount_opts *mo;
506881f68fSopenharmony_ci	int debug;
516881f68fSopenharmony_ci	int deny_others;
526881f68fSopenharmony_ci	struct fuse_lowlevel_ops op;
536881f68fSopenharmony_ci	int got_init;
546881f68fSopenharmony_ci	struct cuse_data *cuse_data;
556881f68fSopenharmony_ci	void *userdata;
566881f68fSopenharmony_ci	uid_t owner;
576881f68fSopenharmony_ci	struct fuse_conn_info conn;
586881f68fSopenharmony_ci	struct fuse_req list;
596881f68fSopenharmony_ci	struct fuse_req interrupts;
606881f68fSopenharmony_ci	pthread_mutex_t lock;
616881f68fSopenharmony_ci	int got_destroy;
626881f68fSopenharmony_ci	pthread_key_t pipe_key;
636881f68fSopenharmony_ci	int broken_splice_nonblock;
646881f68fSopenharmony_ci	uint64_t notify_ctr;
656881f68fSopenharmony_ci	struct fuse_notify_req notify_list;
666881f68fSopenharmony_ci	size_t bufsize;
676881f68fSopenharmony_ci	int error;
686881f68fSopenharmony_ci};
696881f68fSopenharmony_ci
706881f68fSopenharmony_cistruct fuse_chan {
716881f68fSopenharmony_ci	pthread_mutex_t lock;
726881f68fSopenharmony_ci	int ctr;
736881f68fSopenharmony_ci	int fd;
746881f68fSopenharmony_ci};
756881f68fSopenharmony_ci
766881f68fSopenharmony_ci/**
776881f68fSopenharmony_ci * Filesystem module
786881f68fSopenharmony_ci *
796881f68fSopenharmony_ci * Filesystem modules are registered with the FUSE_REGISTER_MODULE()
806881f68fSopenharmony_ci * macro.
816881f68fSopenharmony_ci *
826881f68fSopenharmony_ci */
836881f68fSopenharmony_cistruct fuse_module {
846881f68fSopenharmony_ci	char *name;
856881f68fSopenharmony_ci	fuse_module_factory_t factory;
866881f68fSopenharmony_ci	struct fuse_module *next;
876881f68fSopenharmony_ci	struct fusemod_so *so;
886881f68fSopenharmony_ci	int ctr;
896881f68fSopenharmony_ci};
906881f68fSopenharmony_ci
916881f68fSopenharmony_ci/**
926881f68fSopenharmony_ci * Configuration parameters passed to fuse_session_loop_mt() and
936881f68fSopenharmony_ci * fuse_loop_mt().
946881f68fSopenharmony_ci *
956881f68fSopenharmony_ci * Internal API to avoid exposing the plain data structure and
966881f68fSopenharmony_ci * causing compat issues after adding or removing struct members.
976881f68fSopenharmony_ci *
986881f68fSopenharmony_ci */
996881f68fSopenharmony_ci#if FUSE_USE_VERSION >= FUSE_MAKE_VERSION(3, 12)
1006881f68fSopenharmony_cistruct fuse_loop_config
1016881f68fSopenharmony_ci{
1026881f68fSopenharmony_ci	/* verififier that a correct struct was was passed. This is especially
1036881f68fSopenharmony_ci	 * needed, as versions below (3, 12) were using a public struct
1046881f68fSopenharmony_ci	 * (now called  fuse_loop_config_v1), which was hard to extend with
1056881f68fSopenharmony_ci	 * additional parameters, without risking that file system implementations
1066881f68fSopenharmony_ci	 * would not have noticed and might either pass uninitialized members
1076881f68fSopenharmony_ci	 * or even too small structs.
1086881f68fSopenharmony_ci	 * fuse_loop_config_v1 has clone_fd at this offset, which should be either 0
1096881f68fSopenharmony_ci	 * or 1. v2 or even higher version just need to set a value here
1106881f68fSopenharmony_ci	 * which not conflicting and very unlikely as having been set by
1116881f68fSopenharmony_ci	 * file system implementation.
1126881f68fSopenharmony_ci	 */
1136881f68fSopenharmony_ci	int version_id;
1146881f68fSopenharmony_ci
1156881f68fSopenharmony_ci	/**
1166881f68fSopenharmony_ci	 * whether to use separate device fds for each thread
1176881f68fSopenharmony_ci	 * (may increase performance)
1186881f68fSopenharmony_ci	 */
1196881f68fSopenharmony_ci	int clone_fd;
1206881f68fSopenharmony_ci	/**
1216881f68fSopenharmony_ci	 * The maximum number of available worker threads before they
1226881f68fSopenharmony_ci	 * start to get deleted when they become idle. If not
1236881f68fSopenharmony_ci	 * specified, the default is 10.
1246881f68fSopenharmony_ci	 *
1256881f68fSopenharmony_ci	 * Adjusting this has performance implications; a very small number
1266881f68fSopenharmony_ci	 * of threads in the pool will cause a lot of thread creation and
1276881f68fSopenharmony_ci	 * deletion overhead and performance may suffer. When set to 0, a new
1286881f68fSopenharmony_ci	 * thread will be created to service every operation.
1296881f68fSopenharmony_ci	 * The special value of -1 means that this parameter is disabled.
1306881f68fSopenharmony_ci	 */
1316881f68fSopenharmony_ci	int max_idle_threads;
1326881f68fSopenharmony_ci
1336881f68fSopenharmony_ci	/**
1346881f68fSopenharmony_ci	 *  max number of threads taking and processing kernel requests
1356881f68fSopenharmony_ci	 *
1366881f68fSopenharmony_ci	 *  As of now threads are created dynamically
1376881f68fSopenharmony_ci	 */
1386881f68fSopenharmony_ci	unsigned int max_threads;
1396881f68fSopenharmony_ci};
1406881f68fSopenharmony_ci#endif
1416881f68fSopenharmony_ci
1426881f68fSopenharmony_ci/* ----------------------------------------------------------- *
1436881f68fSopenharmony_ci * Channel interface (when using -o clone_fd)		       *
1446881f68fSopenharmony_ci * ----------------------------------------------------------- */
1456881f68fSopenharmony_ci
1466881f68fSopenharmony_ci/**
1476881f68fSopenharmony_ci * Obtain counted reference to the channel
1486881f68fSopenharmony_ci *
1496881f68fSopenharmony_ci * @param ch the channel
1506881f68fSopenharmony_ci * @return the channel
1516881f68fSopenharmony_ci */
1526881f68fSopenharmony_cistruct fuse_chan *fuse_chan_get(struct fuse_chan *ch);
1536881f68fSopenharmony_ci
1546881f68fSopenharmony_ci/**
1556881f68fSopenharmony_ci * Drop counted reference to a channel
1566881f68fSopenharmony_ci *
1576881f68fSopenharmony_ci * @param ch the channel
1586881f68fSopenharmony_ci */
1596881f68fSopenharmony_civoid fuse_chan_put(struct fuse_chan *ch);
1606881f68fSopenharmony_ci
1616881f68fSopenharmony_cistruct mount_opts *parse_mount_opts(struct fuse_args *args);
1626881f68fSopenharmony_civoid destroy_mount_opts(struct mount_opts *mo);
1636881f68fSopenharmony_civoid fuse_mount_version(void);
1646881f68fSopenharmony_ciunsigned get_max_read(struct mount_opts *o);
1656881f68fSopenharmony_civoid fuse_kern_unmount(const char *mountpoint, int fd);
1666881f68fSopenharmony_ciint fuse_kern_mount(const char *mountpoint, struct mount_opts *mo);
1676881f68fSopenharmony_ci
1686881f68fSopenharmony_ciint fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
1696881f68fSopenharmony_ci			       int count);
1706881f68fSopenharmony_civoid fuse_free_req(fuse_req_t req);
1716881f68fSopenharmony_ci
1726881f68fSopenharmony_civoid cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg);
1736881f68fSopenharmony_ci
1746881f68fSopenharmony_ciint fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
1756881f68fSopenharmony_ci
1766881f68fSopenharmony_ciint fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf,
1776881f68fSopenharmony_ci				 struct fuse_chan *ch);
1786881f68fSopenharmony_civoid fuse_session_process_buf_int(struct fuse_session *se,
1796881f68fSopenharmony_ci				  const struct fuse_buf *buf, struct fuse_chan *ch);
1806881f68fSopenharmony_ci
1816881f68fSopenharmony_cistruct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *op,
1826881f68fSopenharmony_ci		      size_t op_size, void *private_data);
1836881f68fSopenharmony_ciint fuse_loop_mt_312(struct fuse *f, struct fuse_loop_config *config);
1846881f68fSopenharmony_ciint fuse_session_loop_mt_312(struct fuse_session *se, struct fuse_loop_config *config);
1856881f68fSopenharmony_ci
1866881f68fSopenharmony_ci/**
1876881f68fSopenharmony_ci * Internal verifier for the given config.
1886881f68fSopenharmony_ci *
1896881f68fSopenharmony_ci * @return negative standard error code or 0 on success
1906881f68fSopenharmony_ci */
1916881f68fSopenharmony_ciint fuse_loop_cfg_verify(struct fuse_loop_config *config);
1926881f68fSopenharmony_ci
1936881f68fSopenharmony_ci
1946881f68fSopenharmony_ci#define FUSE_MAX_MAX_PAGES 256
1956881f68fSopenharmony_ci#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
1966881f68fSopenharmony_ci
1976881f68fSopenharmony_ci/* room needed in buffer to accommodate header */
1986881f68fSopenharmony_ci#define FUSE_BUFFER_HEADER_SIZE 0x1000
1996881f68fSopenharmony_ci
200