diff options
Diffstat (limited to 'sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch')
-rw-r--r-- | sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch | 610 |
1 files changed, 610 insertions, 0 deletions
diff --git a/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch b/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch new file mode 100644 index 000000000000..0c9b7cc97d3d --- /dev/null +++ b/sys-fs/ntfs3g/files/ntfs3g-2014.2.15-update-fuse-lite-to-support-ioctls.patch @@ -0,0 +1,610 @@ +diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_common.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_common.h +--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_common.h 2014-02-15 14:07:52.000000000 +0000 ++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_common.h 2014-07-31 13:47:17.401904166 +0100 +@@ -49,6 +49,22 @@ + #endif + + #define FUSE_CAP_BIG_WRITES (1 << 5) ++#define FUSE_CAP_IOCTL_DIR (1 << 11) ++ ++/** ++ * Ioctl flags ++ * ++ * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine ++ * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed ++ * FUSE_IOCTL_RETRY: retry with new iovecs ++ * FUSE_IOCTL_DIR: is a directory ++ */ ++#define FUSE_IOCTL_COMPAT (1 << 0) ++#define FUSE_IOCTL_UNRESTRICTED (1 << 1) ++#define FUSE_IOCTL_RETRY (1 << 2) ++#define FUSE_IOCTL_DIR (1 << 4) ++ ++#define FUSE_IOCTL_MAX_IOV 256 + + /** + * Information about open files +diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse.h +--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse.h 2014-02-15 14:07:52.000000000 +0000 ++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse.h 2014-07-31 13:47:17.401904166 +0100 +@@ -420,9 +420,27 @@ + * Introduced in version 2.6 + */ + int (*bmap) (const char *, size_t blocksize, uint64_t *idx); +- unsigned int flag_nullpath_ok : 1; + + /** ++ * Ioctl ++ * ++ * flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in ++ * 64bit environment. The size and direction of data is ++ * determined by _IOC_*() decoding of cmd. For _IOC_NONE, ++ * data will be NULL, for _IOC_WRITE data is out area, for ++ * _IOC_READ in area and if both are set in/out area. In all ++ * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes. ++ * ++ * Introduced in version 2.8 ++ */ ++ int (*ioctl) (const char *, int cmd, void *arg, ++ struct fuse_file_info *, unsigned int flags, void *data); ++ ++ /* ++ * The flags below have been discarded, they should not be used ++ */ ++ unsigned int flag_nullpath_ok : 1; ++ /** + * Reserved flags, don't set + */ + unsigned int flag_reserved : 30; +@@ -450,10 +468,8 @@ + /** Private filesystem data */ + void *private_data; + +-#ifdef POSIXACLS + /** Umask of the calling process (introduced in version 2.8) */ + mode_t umask; +-#endif + }; + + /* ----------------------------------------------------------- * +@@ -601,6 +617,8 @@ + const char *name); + int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, + uint64_t *idx); ++int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg, ++ struct fuse_file_info *fi, unsigned int flags, void *data); + void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn); + void fuse_fs_destroy(struct fuse_fs *fs); + +diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_kernel.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_kernel.h +--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_kernel.h 2014-02-15 14:07:52.000000000 +0000 ++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_kernel.h 2014-07-31 13:47:17.401904166 +0100 +@@ -48,13 +48,19 @@ + /** Version number of this interface */ + #define FUSE_KERNEL_VERSION 7 + +-/** Minor version number of this interface */ +-#ifdef POSIXACLS +-#define FUSE_KERNEL_MINOR_VERSION 12 ++/** Minor version number of this interface ++ * We introduce ourself as 7.18 (Posix ACLS : 7.12, IOCTL_DIR : 7.18) ++ * and we expect features features defined for 7.18, but not implemented ++ * here to not be triggered by ntfs-3g. ++ */ ++#define FUSE_KERNEL_MINOR_VERSION 18 ++ ++/* ++ * For binary compatibility with old kernels we accept falling back to 7.8 ++ */ ++ ++#define FUSE_KERNEL_MAJOR_FALLBACK 7 + #define FUSE_KERNEL_MINOR_FALLBACK 8 +-#else +-#define FUSE_KERNEL_MINOR_VERSION 8 +-#endif + + /** The node ID of the root inode */ + #define FUSE_ROOT_ID 1 +@@ -83,9 +89,7 @@ + __u32 uid; + __u32 gid; + __u32 rdev; +-#ifdef POSIXACLS + __u64 filling; /* JPA needed for minor >= 12, but meaning unknown */ +-#endif + }; + + struct fuse_kstatfs { +@@ -132,11 +136,13 @@ + * INIT request/reply flags + * FUSE_BIG_WRITES: allow big writes to be issued to the file system + * FUSE_DONT_MASK: don't apply umask to file mode on create operations ++ * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories + */ + #define FUSE_ASYNC_READ (1 << 0) + #define FUSE_POSIX_LOCKS (1 << 1) + #define FUSE_BIG_WRITES (1 << 5) + #define FUSE_DONT_MASK (1 << 6) ++#define FUSE_HAS_IOCTL_DIR (1 << 11) + + /** + * Release flags +@@ -180,6 +186,7 @@ + FUSE_INTERRUPT = 36, + FUSE_BMAP = 37, + FUSE_DESTROY = 38, ++ FUSE_IOCTL = 39, + }; + + /* The read buffer is required to be at least 8k, but may be much larger */ +@@ -215,10 +222,8 @@ + struct fuse_mknod_in { + __u32 mode; + __u32 rdev; +-#ifdef POSIXACLS + __u32 umask; + __u32 padding; +-#endif + }; + + struct fuse_mkdir_in { +@@ -255,20 +260,14 @@ + + struct fuse_open_in { + __u32 flags; +-#ifdef POSIXACLS +- __u32 unused; +-#else +- __u32 mode; +-#endif ++ __u32 mode; /* unused for protocol < 7.12 */ + }; + + struct fuse_create_in { + __u32 flags; + __u32 mode; +-#ifdef POSIXACLS + __u32 umask; + __u32 padding; +-#endif + }; + + struct fuse_open_out { +@@ -305,11 +304,9 @@ + __u64 offset; + __u32 size; + __u32 write_flags; +-#ifdef POSIXACLS + __u64 lock_owner; /* JPA */ + __u32 flags; /* JPA */ + __u32 padding; /* JPA */ +-#endif + }; + + struct fuse_write_out { +@@ -389,6 +386,27 @@ + __u64 block; + }; + ++struct fuse_ioctl_in { ++ __u64 fh; ++ __u32 flags; ++ __u32 cmd; ++ __u64 arg; ++ __u32 in_size; ++ __u32 out_size; ++}; ++ ++struct fuse_ioctl_iovec { ++ __u64 base; ++ __u64 len; ++}; ++ ++struct fuse_ioctl_out { ++ __s32 result; ++ __u32 flags; ++ __u32 in_iovs; ++ __u32 out_iovs; ++}; ++ + struct fuse_in_header { + __u32 len; + __u32 opcode; +diff -ur ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_lowlevel.h ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_lowlevel.h +--- ntfs-3g_ntfsprogs-2014.2.15/include/fuse-lite/fuse_lowlevel.h 2014-02-15 14:07:52.000000000 +0000 ++++ ntfs-3g_ntfsprogs-2014.2.15.new/include/fuse-lite/fuse_lowlevel.h 2014-07-31 13:47:17.402904167 +0100 +@@ -101,10 +101,8 @@ + /** Thread ID of the calling process */ + pid_t pid; + +-#ifdef POSIXACLS + /** Umask of the calling process (introduced in version 2.8) */ + mode_t umask; +-#endif + }; + + /* 'to_set' flags in setattr */ +@@ -805,6 +803,37 @@ + */ + void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize, + uint64_t idx); ++ /** ++ * Ioctl ++ * ++ * Note: For unrestricted ioctls (not allowed for FUSE ++ * servers), data in and out areas can be discovered by giving ++ * iovs and setting FUSE_IOCTL_RETRY in @flags. For ++ * restricted ioctls, kernel prepares in/out data area ++ * according to the information encoded in cmd. ++ * ++ * Introduced in version 2.8 ++ * ++ * Valid replies: ++ * fuse_reply_ioctl_retry ++ * fuse_reply_ioctl ++ * fuse_reply_ioctl_iov ++ * fuse_reply_err ++ * ++ * @param req request handle ++ * @param ino the inode number ++ * @param cmd ioctl command ++ * @param arg ioctl argument ++ * @param fi file information ++ * @param flags for FUSE_IOCTL_* flags ++ * @param in_buf data fetched from the caller ++ * @param in_bufsz number of fetched bytes ++ * @param out_bufsz maximum size of output data ++ */ ++ void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, ++ struct fuse_file_info *fi, unsigned flags, ++ const void *in_buf, size_t in_bufsz, size_t out_bufsz); ++ + }; + + /** +@@ -1022,6 +1051,20 @@ + const char *name, const struct stat *stbuf, + off_t off); + ++/** ++ * Reply to finish ioctl ++ * ++ * Possible requests: ++ * ioctl ++ * ++ * @param req request handle ++ * @param result result to be passed to the caller ++ * @param buf buffer containing output data ++ * @param size length of output data ++ */ ++int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size); ++ ++ + /* ----------------------------------------------------------- * + * Utility functions * + * ----------------------------------------------------------- */ +diff -ur ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse.c ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse.c +--- ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse.c 2014-02-15 14:07:52.000000000 +0000 ++++ ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse.c 2014-07-31 13:47:17.403904167 +0100 +@@ -1040,6 +1040,21 @@ + return -ENOSYS; + } + ++int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg, ++ struct fuse_file_info *fi, unsigned int flags, void *data) ++{ ++ fuse_get_context()->private_data = fs->user_data; ++ if (fs->op.ioctl) { ++/* ++ if (fs->debug) ++ fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n", ++ (unsigned long long) fi->fh, cmd, flags); ++*/ ++ return fs->op.ioctl(path, cmd, arg, fi, flags, data); ++ } else ++ return -ENOSYS; ++} ++ + static int is_open(struct fuse *f, fuse_ino_t dir, const char *name) + { + struct node *node; +@@ -2716,6 +2731,60 @@ + reply_err(req, err); + } + ++static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, ++ struct fuse_file_info *llfi, unsigned int flags, ++ const void *in_buf, size_t in_bufsz, ++ size_t out_bufsz) ++{ ++ struct fuse *f = req_fuse_prepare(req); ++ struct fuse_intr_data d; ++ struct fuse_file_info fi; ++ char *path, *out_buf = NULL; ++ int err; ++ ++ err = -EPERM; ++ if (flags & FUSE_IOCTL_UNRESTRICTED) ++ goto err; ++ ++ if (flags & FUSE_IOCTL_DIR) ++ get_dirhandle(llfi, &fi); ++ else ++ fi = *llfi; ++ ++ if (out_bufsz) { ++ err = -ENOMEM; ++ out_buf = malloc(out_bufsz); ++ if (!out_buf) ++ goto err; ++ } ++ ++ assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz); ++ if (out_buf) ++ memcpy(out_buf, in_buf, in_bufsz); ++ ++ path = get_path(f, ino); /* Should be get_path_nullok() */ ++ if (!path) { ++ err = ENOENT; ++ goto err; ++ } ++ ++ fuse_prepare_interrupt(f, req, &d); ++ ++ /* Note : const qualifier dropped */ ++ err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags, ++ out_buf ? (void*)out_buf : (void*)(uintptr_t)in_buf); ++ ++ fuse_finish_interrupt(f, req, &d); ++ free(path); ++ ++ fuse_reply_ioctl(req, err, out_buf, out_bufsz); ++ goto out; ++err: ++ reply_err(req, err); ++out: ++ free(out_buf); ++} ++ + static struct fuse_lowlevel_ops fuse_path_ops = { + .init = fuse_lib_init, + .destroy = fuse_lib_destroy, +@@ -2751,6 +2820,7 @@ + .getlk = fuse_lib_getlk, + .setlk = fuse_lib_setlk, + .bmap = fuse_lib_bmap, ++ .ioctl = fuse_lib_ioctl, + }; + + struct fuse_session *fuse_get_session(struct fuse *f) +diff -ur ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse_lowlevel.c ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse_lowlevel.c +--- ntfs-3g_ntfsprogs-2014.2.15/libfuse-lite/fuse_lowlevel.c 2014-02-15 14:07:52.000000000 +0000 ++++ ntfs-3g_ntfsprogs-2014.2.15.new/libfuse-lite/fuse_lowlevel.c 2014-07-31 13:47:17.403904167 +0100 +@@ -333,12 +333,8 @@ + + memset(&arg, 0, sizeof(arg)); + fill_entry(&arg, e); +-#ifdef POSIXACLS + return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12 + ? sizeof(arg) : FUSE_COMPAT_ENTRY_OUT_SIZE)); +-#else +- return send_reply_ok(req, &arg, sizeof(arg)); +-#endif + } + + int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, +@@ -351,7 +347,6 @@ + + memset(&arg, 0, sizeof(arg)); + fill_entry(&arg.e, e); +-#ifdef POSIXACLS + if (req->f->conn.proto_minor < 12) { + fill_open((struct fuse_open_out*) + ((char*)&arg + FUSE_COMPAT_ENTRY_OUT_SIZE), f); +@@ -361,10 +356,6 @@ + fill_open(&arg.o, f); + return send_reply_ok(req, &arg, sizeof(arg)); + } +-#else +- fill_open(&arg.o, f); +- return send_reply_ok(req, &arg, sizeof(arg)); +-#endif + } + + int fuse_reply_attr(fuse_req_t req, const struct stat *attr, +@@ -377,12 +368,8 @@ + arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout); + convert_stat(attr, &arg.attr); + +-#ifdef POSIXACLS + return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12 + ? sizeof(arg) : FUSE_COMPAT_FUSE_ATTR_OUT_SIZE)); +-#else +- return send_reply_ok(req, &arg, sizeof(arg)); +-#endif + } + + int fuse_reply_readlink(fuse_req_t req, const char *linkname) +@@ -462,6 +449,28 @@ + return send_reply_ok(req, &arg, sizeof(arg)); + } + ++int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size) ++{ ++ struct fuse_ioctl_out arg; ++ struct iovec iov[3]; ++ size_t count = 1; ++ ++ memset(&arg, 0, sizeof(arg)); ++ arg.result = result; ++ iov[count].iov_base = &arg; ++ iov[count].iov_len = sizeof(arg); ++ count++; ++ ++ if (size) { ++ /* Note : const qualifier dropped */ ++ iov[count].iov_base = (char *)(uintptr_t) buf; ++ iov[count].iov_len = size; ++ count++; ++ } ++ ++ return send_reply_iov(req, 0, iov, count); ++} ++ + static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) + { + const char *name = (const char *) inarg; +@@ -538,11 +547,9 @@ + const struct fuse_mknod_in *arg = (const struct fuse_mknod_in *) inarg; + const char *name = PARAM(arg); + +-#ifdef POSIXACLS + if (req->f->conn.proto_minor >= 12) + req->ctx.umask = arg->umask; + else +-#endif + name = (const char *) inarg + FUSE_COMPAT_MKNOD_IN_SIZE; + + if (req->f->op.mknod) +@@ -555,10 +562,8 @@ + { + const struct fuse_mkdir_in *arg = (const struct fuse_mkdir_in *) inarg; + +-#ifdef POSIXACLS + if (req->f->conn.proto_minor >= 12) + req->ctx.umask = arg->umask; +-#endif + + if (req->f->op.mkdir) + req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode); +@@ -630,11 +635,9 @@ + memset(&fi, 0, sizeof(fi)); + fi.flags = arg->flags; + +-#ifdef POSIXACLS + if (req->f->conn.proto_minor >= 12) + req->ctx.umask = arg->umask; + else +-#endif + name = (const char *) inarg + sizeof(struct fuse_open_in); + + req->f->op.create(req, nodeid, name, arg->mode, &fi); +@@ -682,7 +685,6 @@ + fi.writepage = arg->write_flags & 1; + + if (req->f->op.write) { +-#ifdef POSIXACLS + const char *buf; + + if (req->f->conn.proto_minor >= 12) +@@ -690,9 +692,6 @@ + else + buf = ((const char*)arg) + FUSE_COMPAT_WRITE_IN_SIZE; + req->f->op.write(req, nodeid, buf, arg->size, arg->offset, &fi); +-#else +- req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi); +-#endif + } else + fuse_reply_err(req, ENOSYS); + } +@@ -1011,6 +1010,39 @@ + fuse_reply_err(req, ENOSYS); + } + ++static void do_ioctl(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) ++{ ++ const struct fuse_ioctl_in *arg = (const struct fuse_ioctl_in *) inarg; ++ unsigned int flags = arg->flags; ++ const void *in_buf = arg->in_size ? PARAM(arg) : NULL; ++ struct fuse_file_info fi; ++ ++ if (flags & FUSE_IOCTL_DIR && ++ !(req->f->conn.want & FUSE_CAP_IOCTL_DIR)) { ++ fuse_reply_err(req, ENOTTY); ++ return; ++ } ++ ++ memset(&fi, 0, sizeof(fi)); ++ fi.fh = arg->fh; ++ ++/* TODO JPA (need req->ioctl_64bit in obscure fuse_req_t) ++// probably a 64 bit ioctl on a 32-bit cpu ++// this is to forward a request from the kernel ++ if (sizeof(void *) == 4 && req->f->conn.proto_minor >= 16 && ++ !(flags & FUSE_IOCTL_32BIT)) { ++ req->ioctl_64bit = 1; ++ } ++*/ ++ ++ if (req->f->op.ioctl) ++ req->f->op.ioctl(req, nodeid, arg->cmd, ++ (void *)(uintptr_t)arg->arg, &fi, flags, ++ in_buf, arg->in_size, arg->out_size); ++ else ++ fuse_reply_err(req, ENOSYS); ++} ++ + static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) + { + const struct fuse_init_in *arg = (const struct fuse_init_in *) inarg; +@@ -1047,6 +1079,8 @@ + #endif + if (arg->flags & FUSE_BIG_WRITES) + f->conn.capable |= FUSE_CAP_BIG_WRITES; ++ if (arg->flags & FUSE_HAS_IOCTL_DIR) ++ f->conn.capable |= FUSE_CAP_IOCTL_DIR; + } else { + f->conn.async_read = 0; + f->conn.max_readahead = 0; +@@ -1069,28 +1103,28 @@ + memset(&outarg, 0, sizeof(outarg)); + outarg.major = FUSE_KERNEL_VERSION; + /* +- * if POSIXACLS is not set, protocol 7.8 provides a good +- * compatibility with older kernel modules. +- * if POSIXACLS is set, we try to use protocol 7.12 supposed +- * to have the ability to process the umask conditionnally, +- * but, when using an older kernel module, we fallback to 7.8 ++ * Suggest using protocol 7.18 when available, and fallback ++ * to 7.8 when running on an old kernel. ++ * Protocol 7.12 has the ability to process the umask ++ * conditionnally (as needed if POSIXACLS is set) ++ * Protocol 7.18 has the ability to process the ioctls + */ +-#ifdef POSIXACLS +- if (arg->major > 7 || (arg->major == 7 && arg->minor >= 12)) ++ if (arg->major > 7 || (arg->major == 7 && arg->minor >= 18)) { + outarg.minor = FUSE_KERNEL_MINOR_VERSION; +- else +- outarg.minor = FUSE_KERNEL_MINOR_FALLBACK; +-#else +- outarg.minor = FUSE_KERNEL_MINOR_VERSION; ++ if (f->conn.want & FUSE_CAP_IOCTL_DIR) ++ outarg.flags |= FUSE_HAS_IOCTL_DIR; ++#ifdef POSIXACLS ++ if (f->conn.want & FUSE_CAP_DONT_MASK) ++ outarg.flags |= FUSE_DONT_MASK; + #endif ++ } else { ++ outarg.major = FUSE_KERNEL_MAJOR_FALLBACK; ++ outarg.minor = FUSE_KERNEL_MINOR_FALLBACK; ++ } + if (f->conn.async_read) + outarg.flags |= FUSE_ASYNC_READ; + if (f->op.getlk && f->op.setlk) + outarg.flags |= FUSE_POSIX_LOCKS; +-#ifdef POSIXACLS +- if (f->conn.want & FUSE_CAP_DONT_MASK) +- outarg.flags |= FUSE_DONT_MASK; +-#endif + if (f->conn.want & FUSE_CAP_BIG_WRITES) + outarg.flags |= FUSE_BIG_WRITES; + outarg.max_readahead = f->conn.max_readahead; +@@ -1191,6 +1225,7 @@ + [FUSE_CREATE] = { do_create, "CREATE" }, + [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" }, + [FUSE_BMAP] = { do_bmap, "BMAP" }, ++ [FUSE_IOCTL] = { do_ioctl, "IOCTL" }, + [FUSE_DESTROY] = { do_destroy, "DESTROY" }, + }; + |