1 /* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU LGPLv2. 6 See the file COPYING.LIB 7 */ 8 9 #include "fuse.h" 10 #include "fuse_lowlevel.h" 11 12 struct mount_opts; 13 14 struct fuse_req { 15 struct fuse_session *se; 16 uint64_t unique; 17 int ctr; 18 pthread_mutex_t lock; 19 struct fuse_ctx ctx; 20 struct fuse_chan *ch; 21 int interrupted; 22 unsigned int ioctl_64bit : 1; 23 union { 24 struct { 25 uint64_t unique; 26 } i; 27 struct { 28 fuse_interrupt_func_t func; 29 void *data; 30 } ni; 31 } u; 32 struct fuse_req *next; 33 struct fuse_req *prev; 34 }; 35 36 struct fuse_notify_req { 37 uint64_t unique; 38 void (*reply)(struct fuse_notify_req *, fuse_req_t, fuse_ino_t, 39 const void *, const struct fuse_buf *); 40 struct fuse_notify_req *next; 41 struct fuse_notify_req *prev; 42 }; 43 44 struct fuse_session { 45 char *mountpoint; 46 volatile int exited; 47 int fd; 48 struct fuse_custom_io *io; 49 struct mount_opts *mo; 50 int debug; 51 int deny_others; 52 struct fuse_lowlevel_ops op; 53 int got_init; 54 struct cuse_data *cuse_data; 55 void *userdata; 56 uid_t owner; 57 struct fuse_conn_info conn; 58 struct fuse_req list; 59 struct fuse_req interrupts; 60 pthread_mutex_t lock; 61 int got_destroy; 62 pthread_key_t pipe_key; 63 int broken_splice_nonblock; 64 uint64_t notify_ctr; 65 struct fuse_notify_req notify_list; 66 size_t bufsize; 67 int error; 68 }; 69 70 struct fuse_chan { 71 pthread_mutex_t lock; 72 int ctr; 73 int fd; 74 }; 75 76 /** 77 * Filesystem module 78 * 79 * Filesystem modules are registered with the FUSE_REGISTER_MODULE() 80 * macro. 81 * 82 */ 83 struct fuse_module { 84 char *name; 85 fuse_module_factory_t factory; 86 struct fuse_module *next; 87 struct fusemod_so *so; 88 int ctr; 89 }; 90 91 /** 92 * Configuration parameters passed to fuse_session_loop_mt() and 93 * fuse_loop_mt(). 94 * 95 * Internal API to avoid exposing the plain data structure and 96 * causing compat issues after adding or removing struct members. 97 * 98 */ 99 #if FUSE_USE_VERSION >= FUSE_MAKE_VERSION(3, 12) 100 struct fuse_loop_config 101 { 102 /* verififier that a correct struct was was passed. This is especially 103 * needed, as versions below (3, 12) were using a public struct 104 * (now called fuse_loop_config_v1), which was hard to extend with 105 * additional parameters, without risking that file system implementations 106 * would not have noticed and might either pass uninitialized members 107 * or even too small structs. 108 * fuse_loop_config_v1 has clone_fd at this offset, which should be either 0 109 * or 1. v2 or even higher version just need to set a value here 110 * which not conflicting and very unlikely as having been set by 111 * file system implementation. 112 */ 113 int version_id; 114 115 /** 116 * whether to use separate device fds for each thread 117 * (may increase performance) 118 */ 119 int clone_fd; 120 /** 121 * The maximum number of available worker threads before they 122 * start to get deleted when they become idle. If not 123 * specified, the default is 10. 124 * 125 * Adjusting this has performance implications; a very small number 126 * of threads in the pool will cause a lot of thread creation and 127 * deletion overhead and performance may suffer. When set to 0, a new 128 * thread will be created to service every operation. 129 * The special value of -1 means that this parameter is disabled. 130 */ 131 int max_idle_threads; 132 133 /** 134 * max number of threads taking and processing kernel requests 135 * 136 * As of now threads are created dynamically 137 */ 138 unsigned int max_threads; 139 }; 140 #endif 141 142 /* ----------------------------------------------------------- * 143 * Channel interface (when using -o clone_fd) * 144 * ----------------------------------------------------------- */ 145 146 /** 147 * Obtain counted reference to the channel 148 * 149 * @param ch the channel 150 * @return the channel 151 */ 152 struct fuse_chan *fuse_chan_get(struct fuse_chan *ch); 153 154 /** 155 * Drop counted reference to a channel 156 * 157 * @param ch the channel 158 */ 159 void fuse_chan_put(struct fuse_chan *ch); 160 161 struct mount_opts *parse_mount_opts(struct fuse_args *args); 162 void destroy_mount_opts(struct mount_opts *mo); 163 void fuse_mount_version(void); 164 unsigned get_max_read(struct mount_opts *o); 165 void fuse_kern_unmount(const char *mountpoint, int fd); 166 int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo); 167 168 int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov, 169 int count); 170 void fuse_free_req(fuse_req_t req); 171 172 void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg); 173 174 int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg); 175 176 int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf, 177 struct fuse_chan *ch); 178 void fuse_session_process_buf_int(struct fuse_session *se, 179 const struct fuse_buf *buf, struct fuse_chan *ch); 180 181 struct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *op, 182 size_t op_size, void *private_data); 183 int fuse_loop_mt_312(struct fuse *f, struct fuse_loop_config *config); 184 int fuse_session_loop_mt_312(struct fuse_session *se, struct fuse_loop_config *config); 185 186 /** 187 * Internal verifier for the given config. 188 * 189 * @return negative standard error code or 0 on success 190 */ 191 int fuse_loop_cfg_verify(struct fuse_loop_config *config); 192 193 194 #define FUSE_MAX_MAX_PAGES 256 195 #define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32 196 197 /* room needed in buffer to accommodate header */ 198 #define FUSE_BUFFER_HEADER_SIZE 0x1000 199 200