summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@redhat.com>2020-10-15 23:31:08 +0200
committerXavi Hernandez <xhernandez@users.noreply.github.com>2020-12-15 12:01:36 +0100
commit68987b050cc1a0fcf088ab981acbe6a2d1b22972 (patch)
treeeebcc68af760d1b9576f1af3821f1f4f875d8ea5
parent9c2bd7cbf6c00604d12a42de463e09739f6a84bc (diff)
downloadglusterfs-68987b050cc1a0fcf088ab981acbe6a2d1b22972.tar.gz
glusterfs-68987b050cc1a0fcf088ab981acbe6a2d1b22972.tar.xz
glusterfs-68987b050cc1a0fcf088ab981acbe6a2d1b22972.zip
fuse: sanitize FUSE_OP_HIGH
The idea behind FUSE_OP_HIGH was that it should be the upper limit for the opcodes we can ever get from kernel (maximum opcode that can occur plus one). The problem with this idea is that this depends on the FUSE protocol version; and since the fuse proto header does not export this value, it has to be retroactively defined considering the particular opcode values in the protocol header. That is, not just the value, but the definition itself depends on the FUSE protocol version. So we ended up maintaining -- or indeed, not even maintaining, just living with -- a mess of conditional defines for FUSE_OP_HIGH. Now we change the meaning of it: FUSE_OP_HIGH will simply be upper limit of the opcodes for which we define a handler (the highest such opcode plus one, which is the same as the size of the fuse optable). The practical implication of this change is as follows. Potentially there is a gap between the new and the old value of FUSE_OP_HIGH: those opcodes which might occur in requests but are higher than any opcode we handle. With the old definition of FUSE_OP_HIGH we could statically dispatch these opcodes to fuse_enosys() (a function that sends a FUSE response with error ENOSYS). With the new definition we don't know the upper limit of this gap, so we need to dispatch the opcodes of the gap to fuse_enosys() dynamically (perform a runtime check if the opcode is greater-or-equal than the new FUSE_OP_HIGH, and if yes, then call fuse_enosys()). Change-Id: I8cd26ead538de8ce36c91feaf938e4c5dc59c88c Updates: #1000 Signed-off-by: Csaba Henk <csaba@redhat.com>
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c135
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h30
2 files changed, 70 insertions, 95 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 042f1c6c4c..d1b8795c8b 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -5959,6 +5959,72 @@ fuse_get_mount_status(xlator_t *this)
return kid_status;
}
+static fuse_handler_t *fuse_std_ops[] = {
+ [FUSE_LOOKUP] = fuse_lookup,
+ [FUSE_FORGET] = fuse_forget,
+ [FUSE_GETATTR] = fuse_getattr,
+ [FUSE_SETATTR] = fuse_setattr,
+ [FUSE_READLINK] = fuse_readlink,
+ [FUSE_SYMLINK] = fuse_symlink,
+ [FUSE_MKNOD] = fuse_mknod,
+ [FUSE_MKDIR] = fuse_mkdir,
+ [FUSE_UNLINK] = fuse_unlink,
+ [FUSE_RMDIR] = fuse_rmdir,
+ [FUSE_RENAME] = fuse_rename,
+ [FUSE_LINK] = fuse_link,
+ [FUSE_OPEN] = fuse_open,
+ [FUSE_READ] = fuse_readv,
+ [FUSE_WRITE] = fuse_write,
+ [FUSE_STATFS] = fuse_statfs,
+ [FUSE_RELEASE] = fuse_release,
+ [FUSE_FSYNC] = fuse_fsync,
+ [FUSE_SETXATTR] = fuse_setxattr,
+ [FUSE_GETXATTR] = fuse_getxattr,
+ [FUSE_LISTXATTR] = fuse_listxattr,
+ [FUSE_REMOVEXATTR] = fuse_removexattr,
+ [FUSE_FLUSH] = fuse_flush,
+ [FUSE_INIT] = fuse_init,
+ [FUSE_OPENDIR] = fuse_opendir,
+ [FUSE_READDIR] = fuse_readdir,
+ [FUSE_RELEASEDIR] = fuse_releasedir,
+ [FUSE_FSYNCDIR] = fuse_fsyncdir,
+ [FUSE_GETLK] = fuse_getlk,
+ [FUSE_SETLK] = fuse_setlk,
+ [FUSE_SETLKW] = fuse_setlk,
+ [FUSE_ACCESS] = fuse_access,
+ [FUSE_CREATE] = fuse_create,
+ [FUSE_INTERRUPT] = fuse_interrupt,
+ /* [FUSE_BMAP] */
+ [FUSE_DESTROY] = fuse_destroy,
+/* [FUSE_IOCTL] */
+/* [FUSE_POLL] */
+/* [FUSE_NOTIFY_REPLY] */
+
+#if FUSE_KERNEL_MINOR_VERSION >= 16
+ [FUSE_BATCH_FORGET] = fuse_batch_forget,
+#endif
+
+#if FUSE_KERNEL_MINOR_VERSION >= 19
+#ifdef FALLOC_FL_KEEP_SIZE
+ [FUSE_FALLOCATE] = fuse_fallocate,
+#endif /* FALLOC_FL_KEEP_SIZE */
+#endif
+
+#if FUSE_KERNEL_MINOR_VERSION >= 21
+ [FUSE_READDIRPLUS] = fuse_readdirp,
+#endif
+
+#if FUSE_KERNEL_MINOR_VERSION >= 24 && HAVE_SEEK_HOLE
+ [FUSE_LSEEK] = fuse_lseek,
+#endif
+
+#if FUSE_KERNEL_MINOR_VERSION >= 28
+ [FUSE_COPY_FILE_RANGE] = fuse_copy_file_range,
+#endif
+};
+
+#define FUSE_OP_HIGH (sizeof(fuse_std_ops) / sizeof(*fuse_std_ops))
+
static void
fuse_dispatch(xlator_t *xl, gf_async_t *async)
{
@@ -5972,7 +6038,10 @@ fuse_dispatch(xlator_t *xl, gf_async_t *async)
finh = fasync->finh;
iobuf = fasync->iobuf;
- priv->fuse_ops[finh->opcode](xl, finh, fasync->msg, iobuf);
+ if (finh->opcode >= FUSE_OP_HIGH)
+ fuse_enosys(xl, finh, NULL, NULL);
+ else
+ priv->fuse_ops[finh->opcode](xl, finh, fasync->msg, iobuf);
iobuf_unref(iobuf);
}
@@ -6536,70 +6605,6 @@ mem_acct_init(xlator_t *this)
return ret;
}
-static fuse_handler_t *fuse_std_ops[FUSE_OP_HIGH] = {
- [FUSE_LOOKUP] = fuse_lookup,
- [FUSE_FORGET] = fuse_forget,
- [FUSE_GETATTR] = fuse_getattr,
- [FUSE_SETATTR] = fuse_setattr,
- [FUSE_READLINK] = fuse_readlink,
- [FUSE_SYMLINK] = fuse_symlink,
- [FUSE_MKNOD] = fuse_mknod,
- [FUSE_MKDIR] = fuse_mkdir,
- [FUSE_UNLINK] = fuse_unlink,
- [FUSE_RMDIR] = fuse_rmdir,
- [FUSE_RENAME] = fuse_rename,
- [FUSE_LINK] = fuse_link,
- [FUSE_OPEN] = fuse_open,
- [FUSE_READ] = fuse_readv,
- [FUSE_WRITE] = fuse_write,
- [FUSE_STATFS] = fuse_statfs,
- [FUSE_RELEASE] = fuse_release,
- [FUSE_FSYNC] = fuse_fsync,
- [FUSE_SETXATTR] = fuse_setxattr,
- [FUSE_GETXATTR] = fuse_getxattr,
- [FUSE_LISTXATTR] = fuse_listxattr,
- [FUSE_REMOVEXATTR] = fuse_removexattr,
- [FUSE_FLUSH] = fuse_flush,
- [FUSE_INIT] = fuse_init,
- [FUSE_OPENDIR] = fuse_opendir,
- [FUSE_READDIR] = fuse_readdir,
- [FUSE_RELEASEDIR] = fuse_releasedir,
- [FUSE_FSYNCDIR] = fuse_fsyncdir,
- [FUSE_GETLK] = fuse_getlk,
- [FUSE_SETLK] = fuse_setlk,
- [FUSE_SETLKW] = fuse_setlk,
- [FUSE_ACCESS] = fuse_access,
- [FUSE_CREATE] = fuse_create,
- [FUSE_INTERRUPT] = fuse_interrupt,
- /* [FUSE_BMAP] */
- [FUSE_DESTROY] = fuse_destroy,
-/* [FUSE_IOCTL] */
-/* [FUSE_POLL] */
-/* [FUSE_NOTIFY_REPLY] */
-
-#if FUSE_KERNEL_MINOR_VERSION >= 16
- [FUSE_BATCH_FORGET] = fuse_batch_forget,
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 19
-#ifdef FALLOC_FL_KEEP_SIZE
- [FUSE_FALLOCATE] = fuse_fallocate,
-#endif /* FALLOC_FL_KEEP_SIZE */
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 21
- [FUSE_READDIRPLUS] = fuse_readdirp,
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 24 && HAVE_SEEK_HOLE
- [FUSE_LSEEK] = fuse_lseek,
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 28
- [FUSE_COPY_FILE_RANGE] = fuse_copy_file_range,
-#endif
-};
-
static fuse_handler_t *fuse_dump_ops[FUSE_OP_HIGH];
static void
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index 4cb94c23ca..f40b79b9d4 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -40,36 +40,6 @@
#include <glusterfs/syncop.h>
#include <glusterfs/gidcache.h>
-#if defined(GF_LINUX_HOST_OS) || defined(__FreeBSD__) || defined(__NetBSD__)
-
-/*
- * TODO:
- * So, with the addition of copy_file_range support, it might
- * require a bump up of fuse kernel minor version (like it was
- * done when support for lseek fop was added. But, as of now,
- * the copy_file_range support has just landed in upstream
- * kernel fuse module. So, until, there is a release of that
- * fuse as part of a kernel, the FUSE_KERNEL_MINOR_VERSION
- * from fuse_kernel.h in the contrib might not be changed.
- * If so, then the highest op available should be based on
- * the current minor version (which is 24). So, selectively
- * determine. When, the minor version is changed to 28 in
- * fuse_kernel.h from contrib (because in upstream linux
- * kernel source tree, the kernel minor version which
- * contains support for copy_file_range is 28), then remove
- * the reference to FUSE_LSEEK below and just determine
- * FUSE_OP_HIGH based on copy_file_range.
- */
-#if FUSE_KERNEL_MINOR_VERSION >= 28
-#define FUSE_OP_HIGH (FUSE_COPY_FILE_RANGE + 1)
-#else
-#define FUSE_OP_HIGH (FUSE_LSEEK + 1)
-#endif
-
-#endif
-#ifdef GF_DARWIN_HOST_OS
-#define FUSE_OP_HIGH (FUSE_DESTROY + 1)
-#endif
#define GLUSTERFS_XATTR_LEN_MAX 65536
#define MAX_FUSE_PROC_DELAY 1