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