sys/vfs/fuse/fuse.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | /*- * Copyright (c) 2019 Tomohiro Kusumi <tkusumi@netbsd.org> * Copyright (c) 2019 The DragonFly Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef FUSE_FUSE_H #define FUSE_FUSE_H #ifndef INVARIANTS #define INVARIANTS #endif #include <sys/types.h> #include <sys/stat.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/malloc.h> #include <sys/objcache.h> #include <sys/proc.h> #include <sys/thread.h> #include <sys/mutex.h> #include <sys/mutex2.h> #include <sys/refcount.h> #include <sys/event.h> #include <sys/mount.h> #include <sys/vnode.h> #include <sys/file.h> #include <sys/ucred.h> #include <sys/unistd.h> #include <sys/sysctl.h> #include <sys/errno.h> #include <sys/queue.h> #include <sys/tree.h> #include <sys/lockf.h> #include <machine/atomic.h> #include "fuse_debug.h" #include "fuse_mount.h" #include "fuse_abi.h" #define VFSTOFUSE(mp) ((struct fuse_mount*)((mp)->mnt_data)) #define VTOI(vp) ((struct fuse_node*)((vp)->v_data)) #define FUSE_MAXFILESIZE 0x7FFFFFFFFFFFFFFFLL #define FUSE_BLKSIZE PAGE_SIZE #define FUSE_BLKMASK (FUSE_BLKSIZE - 1) #define FUSE_BLKMASK64 ((off_t)(FUSE_BLKSIZE - 1)) SYSCTL_DECL(_vfs_fuse); extern int fuse_debug; extern struct vop_ops fuse_vnode_vops; extern struct vop_ops fuse_spec_vops; struct fuse_node; RB_HEAD(fuse_node_tree, fuse_node); struct fuse_mount { struct mount *mp; struct vnode *devvp; struct ucred *cred; struct kqinfo kq; struct fuse_node *rfnp; struct mtx mnt_lock; struct mtx ipc_lock; struct mtx ino_lock; struct thread *helper_td; // helper thread struct spinlock helper_spin; // protect bioq TAILQ_HEAD(, bio) bioq; // bioq for strategy I/Os TAILQ_HEAD(,fuse_ipc) request_head; TAILQ_HEAD(,fuse_ipc) reply_head; struct fuse_node_tree node_head; // inode index unsigned int refcnt; unsigned long unique; int dead; uint64_t nosys; uint32_t abi_major; uint32_t abi_minor; uint32_t max_write; }; struct fuse_node { RB_ENTRY(fuse_node) node_entry; // inode index entry struct vnode *vp; struct vattr attr; struct fuse_mount *fmp; struct fuse_node *pfnp; struct mtx node_lock; struct lockf advlock; uint64_t ino; enum vtype type; size_t size; uint64_t nlookup; uint64_t fh; bool closed; /* XXX associated with closed fh */ int modified : 1; /* file modified */ int changed : 1; /* file inode changed */ int accessed : 1; /* file accessed */ int attrgood : 1; /* have valid attributes */ int sizeoverride : 1; /* override attr size with fnp->size */ }; struct fuse_buf { void *buf; size_t len; }; struct fuse_ipc { struct fuse_mount *fmp; struct fuse_buf request; struct fuse_buf reply; TAILQ_ENTRY(fuse_ipc) request_entry; TAILQ_ENTRY(fuse_ipc) reply_entry; unsigned int refcnt; uint64_t unique; int sent; int done; }; int fuse_cmp_version(struct fuse_mount*, uint32_t, uint32_t); int fuse_mount_kill(struct fuse_mount*); int fuse_mount_free(struct fuse_mount*); int fuse_device_init(void); void fuse_device_cleanup(void); void fuse_node_new(struct fuse_mount*, uint64_t, enum vtype, struct fuse_node**); void fuse_node_free(struct fuse_mount *, struct fuse_node *); int fuse_alloc_node(struct fuse_mount *, struct fuse_node *, uint64_t, enum vtype, struct vnode **); int fuse_node_vn(struct fuse_node*, struct vnode**); int fuse_node_truncate(struct fuse_node*, size_t, size_t); void fuse_node_init(void); void fuse_node_cleanup(void); void fuse_buf_alloc(struct fuse_buf*, size_t); void fuse_buf_free(struct fuse_buf*); struct fuse_ipc *fuse_ipc_get(struct fuse_mount*, size_t); void fuse_ipc_put(struct fuse_ipc*); void *fuse_ipc_fill(struct fuse_ipc*, int, uint64_t, struct ucred*); int fuse_ipc_tx(struct fuse_ipc*); int fuse_ipc_tx_noreply(struct fuse_ipc*); void fuse_ipc_init(void); void fuse_ipc_cleanup(void); int fuse_read(struct vop_read_args*); int fuse_write(struct vop_write_args*); int fuse_dio_write(struct vop_write_args*); void fuse_hexdump(const char*, size_t); void fuse_fill_in_header(struct fuse_in_header*, uint32_t, uint32_t, uint64_t, uint64_t, uint32_t, uint32_t, uint32_t); int fuse_forget_node(struct fuse_mount*, uint64_t, uint64_t, struct ucred*); int fuse_audit_length(struct fuse_in_header*, struct fuse_out_header*); const char *fuse_get_ops(int); void fuse_io_thread(void *arg); static __inline int fuse_test_dead(struct fuse_mount *fmp) { return atomic_load_acq_int(&fmp->dead); } static __inline void fuse_set_dead(struct fuse_mount *fmp) { atomic_store_rel_int(&fmp->dead, 1); } static __inline int fuse_test_nosys(struct fuse_mount *fmp, int op) { return atomic_load_acq_64(&fmp->nosys) & (1 << op); } static __inline void fuse_set_nosys(struct fuse_mount *fmp, int op) { atomic_set_64(&fmp->nosys, 1 << op); } static __inline int fuse_ipc_test_replied(struct fuse_ipc *fip) { return atomic_load_acq_int(&fip->done); } static __inline void fuse_ipc_set_replied(struct fuse_ipc *fip) { atomic_store_rel_int(&fip->done, 1); } static __inline int fuse_ipc_test_and_set_replied(struct fuse_ipc *fip) { return atomic_cmpset_int(&fip->done, 0, 1); } static __inline void* fuse_in(struct fuse_ipc *fip) { return fip->request.buf; } static __inline size_t fuse_in_size(struct fuse_ipc *fip) { return fip->request.len; } static __inline void* fuse_in_data(struct fuse_ipc *fip) { return (struct fuse_in_header*)fuse_in(fip) + 1; } static __inline size_t fuse_in_data_size(struct fuse_ipc *fip) { return fuse_in_size(fip) - sizeof(struct fuse_in_header); } static __inline void* fuse_out(struct fuse_ipc *fip) { return fip->reply.buf; } static __inline size_t fuse_out_size(struct fuse_ipc *fip) { return fip->reply.len; } static __inline void* fuse_out_data(struct fuse_ipc *fip) { return (struct fuse_out_header*)fuse_out(fip) + 1; } static __inline size_t fuse_out_data_size(struct fuse_ipc *fip) { return fuse_out_size(fip) - sizeof(struct fuse_out_header); } static __inline void fuse_knote(struct vnode *vp, int flags) { if (flags) KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, flags); } #endif /* FUSE_FUSE_H */ |