1 /* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2007 Miklos Szeredi <[email protected]> 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 /* This is useful if any kind of ABI incompatibility is found at 70 * a later version, to 'fix' it at run time. 71 */ 72 struct libfuse_version version; 73 }; 74 75 struct fuse_chan { 76 pthread_mutex_t lock; 77 int ctr; 78 int fd; 79 }; 80 81 /** 82 * Filesystem module 83 * 84 * Filesystem modules are registered with the FUSE_REGISTER_MODULE() 85 * macro. 86 * 87 */ 88 struct fuse_module { 89 char *name; 90 fuse_module_factory_t factory; 91 struct fuse_module *next; 92 struct fusemod_so *so; 93 int ctr; 94 }; 95 96 /** 97 * Configuration parameters passed to fuse_session_loop_mt() and 98 * fuse_loop_mt(). 99 * 100 * Internal API to avoid exposing the plain data structure and 101 * causing compat issues after adding or removing struct members. 102 * 103 */ 104 #if FUSE_USE_VERSION >= FUSE_MAKE_VERSION(3, 12) 105 struct fuse_loop_config 106 { 107 /* verififier that a correct struct was was passed. This is especially 108 * needed, as versions below (3, 12) were using a public struct 109 * (now called fuse_loop_config_v1), which was hard to extend with 110 * additional parameters, without risking that file system implementations 111 * would not have noticed and might either pass uninitialized members 112 * or even too small structs. 113 * fuse_loop_config_v1 has clone_fd at this offset, which should be either 0 114 * or 1. v2 or even higher version just need to set a value here 115 * which not conflicting and very unlikely as having been set by 116 * file system implementation. 117 */ 118 int version_id; 119 120 /** 121 * whether to use separate device fds for each thread 122 * (may increase performance) 123 */ 124 int clone_fd; 125 /** 126 * The maximum number of available worker threads before they 127 * start to get deleted when they become idle. If not 128 * specified, the default is 10. 129 * 130 * Adjusting this has performance implications; a very small number 131 * of threads in the pool will cause a lot of thread creation and 132 * deletion overhead and performance may suffer. When set to 0, a new 133 * thread will be created to service every operation. 134 * The special value of -1 means that this parameter is disabled. 135 */ 136 int max_idle_threads; 137 138 /** 139 * max number of threads taking and processing kernel requests 140 * 141 * As of now threads are created dynamically 142 */ 143 unsigned int max_threads; 144 }; 145 #endif 146 147 /* ----------------------------------------------------------- * 148 * Channel interface (when using -o clone_fd) * 149 * ----------------------------------------------------------- */ 150 151 /** 152 * Obtain counted reference to the channel 153 * 154 * @param ch the channel 155 * @return the channel 156 */ 157 struct fuse_chan *fuse_chan_get(struct fuse_chan *ch); 158 159 /** 160 * Drop counted reference to a channel 161 * 162 * @param ch the channel 163 */ 164 void fuse_chan_put(struct fuse_chan *ch); 165 166 struct mount_opts *parse_mount_opts(struct fuse_args *args); 167 void destroy_mount_opts(struct mount_opts *mo); 168 void fuse_mount_version(void); 169 unsigned get_max_read(struct mount_opts *o); 170 void fuse_kern_unmount(const char *mountpoint, int fd); 171 int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo); 172 173 int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov, 174 int count); 175 void fuse_free_req(fuse_req_t req); 176 177 void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg); 178 179 int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg); 180 181 int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf, 182 struct fuse_chan *ch); 183 void fuse_session_process_buf_int(struct fuse_session *se, 184 const struct fuse_buf *buf, struct fuse_chan *ch); 185 186 struct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *op, 187 size_t op_size, void *private_data); 188 int fuse_loop_mt_312(struct fuse *f, struct fuse_loop_config *config); 189 int fuse_session_loop_mt_312(struct fuse_session *se, struct fuse_loop_config *config); 190 191 /** 192 * Internal verifier for the given config. 193 * 194 * @return negative standard error code or 0 on success 195 */ 196 int fuse_loop_cfg_verify(struct fuse_loop_config *config); 197 198 199 #define FUSE_MAX_MAX_PAGES 256 200 #define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32 201 202 /* room needed in buffer to accommodate header */ 203 #define FUSE_BUFFER_HEADER_SIZE 0x1000 204 205