This patch add a simple functional test for the "about" file in fusectlfs (/sys/fs/fuse/connections/ID/about).
A simple fuse daemon is added for testing.
Related discussion can be found in the link below.
Link: https://lore.kernel.org/all/CAOQ4uxjKFXOKQxPpxtS6G_nR0tpw95w0GiO68UcWg_OBhmS... Cc: Amir Goldstein amir73il@gmail.com Signed-off-by: Chen Linxuan chenlinxuan@uniontech.com --- MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + .../selftests/filesystems/fusectl/.gitignore | 3 + .../selftests/filesystems/fusectl/Makefile | 21 +++ .../selftests/filesystems/fusectl/fuse_mnt.c | 146 ++++++++++++++++++ .../filesystems/fusectl/fusectl_test.c | 115 ++++++++++++++ 6 files changed, 287 insertions(+) create mode 100644 tools/testing/selftests/filesystems/fusectl/.gitignore create mode 100644 tools/testing/selftests/filesystems/fusectl/Makefile create mode 100644 tools/testing/selftests/filesystems/fusectl/fuse_mnt.c create mode 100644 tools/testing/selftests/filesystems/fusectl/fusectl_test.c
diff --git a/MAINTAINERS b/MAINTAINERS index f21f1dabb5fe1..efc6c89113b95 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9740,6 +9740,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git F: Documentation/filesystems/fuse.rst F: fs/fuse/ F: include/uapi/linux/fuse.h +F: tools/testing/selftests/filesystems/fusectl
FUTEX SUBSYSTEM M: Thomas Gleixner tglx@linutronix.de diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 80fb84fa3cfcb..a9bfefa961889 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -36,6 +36,7 @@ TARGETS += filesystems/fat TARGETS += filesystems/overlayfs TARGETS += filesystems/statmount TARGETS += filesystems/mount-notify +TARGETS += filesystems/fusectl TARGETS += firmware TARGETS += fpu TARGETS += ftrace diff --git a/tools/testing/selftests/filesystems/fusectl/.gitignore b/tools/testing/selftests/filesystems/fusectl/.gitignore new file mode 100644 index 0000000000000..3e72e742d08e8 --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +fuse_mnt +fusectl_test diff --git a/tools/testing/selftests/filesystems/fusectl/Makefile b/tools/testing/selftests/filesystems/fusectl/Makefile new file mode 100644 index 0000000000000..612aad69a93aa --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/Makefile @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +CFLAGS += -Wall -O2 -g $(KHDR_INCLUDES) + +TEST_GEN_PROGS := fusectl_test +TEST_GEN_FILES := fuse_mnt + +include ../../lib.mk + +VAR_CFLAGS := $(shell pkg-config fuse --cflags 2>/dev/null) +ifeq ($(VAR_CFLAGS),) +VAR_CFLAGS := -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse +endif + +VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) +ifeq ($(VAR_LDLIBS),) +VAR_LDLIBS := -lfuse -pthread +endif + +$(OUTPUT)/fuse_mnt: CFLAGS += $(VAR_CFLAGS) +$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) diff --git a/tools/testing/selftests/filesystems/fusectl/fuse_mnt.c b/tools/testing/selftests/filesystems/fusectl/fuse_mnt.c new file mode 100644 index 0000000000000..d12b17f30fadc --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/fuse_mnt.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * fusectl test file-system + * Creates a simple FUSE filesystem with a single read-write file (/test) + */ + +#define FUSE_USE_VERSION 26 + +#include <fuse.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +static char *content; +static size_t content_size = 0; +static const char test_path[] = "/test"; + +static int test_getattr(const char *path, struct stat *st) +{ + memset(st, 0, sizeof(*st)); + + if (!strcmp(path, "/")) { + st->st_mode = S_IFDIR | 0755; + st->st_nlink = 2; + return 0; + } + + if (!strcmp(path, test_path)) { + st->st_mode = S_IFREG | 0664; + st->st_nlink = 1; + st->st_size = content_size; + return 0; + } + + return -ENOENT; +} + +static int test_readdir(const char *path, void *buf, fuse_fill_dir_t filler, + off_t offset, struct fuse_file_info *fi) +{ + if (strcmp(path, "/")) + return -ENOENT; + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + filler(buf, test_path + 1, NULL, 0); + + return 0; +} + +static int test_open(const char *path, struct fuse_file_info *fi) +{ + if (strcmp(path, test_path)) + return -ENOENT; + + return 0; +} + +static int test_read(const char *path, char *buf, size_t size, off_t offset, + struct fuse_file_info *fi) +{ + if (strcmp(path, test_path) != 0) + return -ENOENT; + + if (!content || content_size == 0) + return 0; + + if (offset >= content_size) + return 0; + + if (offset + size > content_size) + size = content_size - offset; + + memcpy(buf, content + offset, size); + + return size; +} + +static int test_write(const char *path, const char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) +{ + size_t new_size; + + if (strcmp(path, test_path) != 0) + return -ENOENT; + + if(offset > content_size) + return -EINVAL; + + new_size = MAX(offset + size, content_size); + + if (new_size > content_size) + content = realloc(content, new_size); + + content_size = new_size; + + if (!content) + return -ENOMEM; + + memcpy(content + offset, buf, size); + + return size; +} + +static int test_truncate(const char *path, off_t size) +{ + if (strcmp(path, test_path) != 0) + return -ENOENT; + + if (size == 0) { + free(content); + content = NULL; + content_size = 0; + return 0; + } + + content = realloc(content, size); + + if (!content) + return -ENOMEM; + + if (size > content_size) + memset(content + content_size, 0, size - content_size); + + content_size = size; + return 0; +} + +static struct fuse_operations memfd_ops = { + .getattr = test_getattr, + .readdir = test_readdir, + .open = test_open, + .read = test_read, + .write = test_write, + .truncate = test_truncate, +}; + +int main(int argc, char *argv[]) +{ + return fuse_main(argc, argv, &memfd_ops, NULL); +} diff --git a/tools/testing/selftests/filesystems/fusectl/fusectl_test.c b/tools/testing/selftests/filesystems/fusectl/fusectl_test.c new file mode 100644 index 0000000000000..8ff130ae43122 --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/fusectl_test.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (c) 2025 Chen Linxuan chenlinxuan@uniontech.com + +#define _GNU_SOURCE + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <dirent.h> +#include <linux/limits.h> + +#include "../../kselftest_harness.h" + +#define FUSECTL_MOUNTPOINT "/sys/fs/fuse/connections" +#define FUSE_MOUNTPOINT "/tmp/fuse_mnt_XXXXXX" +#define FUSE_DEVICE "/dev/fuse" +#define FUSECTL_TEST_VALUE "1" + +FIXTURE(fusectl){ + char fuse_mountpoint[sizeof(FUSE_MOUNTPOINT)]; + int connection; +}; + +FIXTURE_SETUP(fusectl) +{ + const char *fuse_mnt_prog = "./fuse_mnt"; + int status, pid; + struct stat statbuf; + + strcpy(self->fuse_mountpoint, FUSE_MOUNTPOINT); + + if (!mkdtemp(self->fuse_mountpoint)) + SKIP(return, + "Failed to create FUSE mountpoint %s", + strerror(errno)); + + if (access(FUSECTL_MOUNTPOINT, F_OK)) + SKIP(return, + "FUSE control filesystem not mounted"); + + pid = fork(); + if (pid < 0) + SKIP(return, + "Failed to fork FUSE daemon process: %s", + strerror(errno)); + + if (pid == 0) { + execlp(fuse_mnt_prog, fuse_mnt_prog, self->fuse_mountpoint, NULL); + exit(errno); + } + + waitpid(pid, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + SKIP(return, + "Failed to start FUSE daemon %s", + strerror(WEXITSTATUS(status))); + } + + if (stat(self->fuse_mountpoint, &statbuf)) + SKIP(return, + "Failed to stat FUSE mountpoint %s", + strerror(errno)); + + self->connection = statbuf.st_dev; +} + +FIXTURE_TEARDOWN(fusectl) +{ + umount(self->fuse_mountpoint); + rmdir(self->fuse_mountpoint); +} + +TEST_F(fusectl, abort) +{ + char path_buf[PATH_MAX]; + int abort_fd, test_fd, ret; + + sprintf(path_buf, "/sys/fs/fuse/connections/%d/abort", self->connection); + + ASSERT_EQ(0, access(path_buf, F_OK)); + + abort_fd = open(path_buf, O_WRONLY); + ASSERT_GE(abort_fd, 0); + + sprintf(path_buf, "%s/test", self->fuse_mountpoint); + + test_fd = open(path_buf, O_RDWR); + ASSERT_GE(test_fd, 0); + + ret = read(test_fd, path_buf, sizeof(path_buf)); + ASSERT_EQ(ret, 0); + + ret = write(test_fd, "test", sizeof("test")); + ASSERT_EQ(ret, sizeof("test")); + + ret = lseek(test_fd, 0, SEEK_SET); + ASSERT_GE(ret, 0); + + ret = write(abort_fd, FUSECTL_TEST_VALUE, sizeof(FUSECTL_TEST_VALUE)); + ASSERT_GT(ret, 0); + + close(abort_fd); + + ret = read(test_fd, path_buf, sizeof(path_buf)); + ASSERT_LT(ret, 0); +} + +TEST_HARNESS_MAIN
On Thu, May 15, 2025 at 3:35 PM Chen Linxuan chenlinxuan@uniontech.com wrote:
This patch add a simple functional test for the "about" file
Sorry for the typo, it should be "abort".
On Thu, May 15, 2025 at 9:35 AM Chen Linxuan chenlinxuan@uniontech.com wrote:
This patch add a simple functional test for the "about" file in fusectlfs (/sys/fs/fuse/connections/ID/about).
A simple fuse daemon is added for testing.
Related discussion can be found in the link below.
Link: https://lore.kernel.org/all/CAOQ4uxjKFXOKQxPpxtS6G_nR0tpw95w0GiO68UcWg_OBhmS... Cc: Amir Goldstein amir73il@gmail.com Signed-off-by: Chen Linxuan chenlinxuan@uniontech.com
MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + .../selftests/filesystems/fusectl/.gitignore | 3 + .../selftests/filesystems/fusectl/Makefile | 21 +++ .../selftests/filesystems/fusectl/fuse_mnt.c | 146 ++++++++++++++++++ .../filesystems/fusectl/fusectl_test.c | 115 ++++++++++++++ 6 files changed, 287 insertions(+) create mode 100644 tools/testing/selftests/filesystems/fusectl/.gitignore create mode 100644 tools/testing/selftests/filesystems/fusectl/Makefile create mode 100644 tools/testing/selftests/filesystems/fusectl/fuse_mnt.c create mode 100644 tools/testing/selftests/filesystems/fusectl/fusectl_test.c
diff --git a/MAINTAINERS b/MAINTAINERS index f21f1dabb5fe1..efc6c89113b95 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9740,6 +9740,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git F: Documentation/filesystems/fuse.rst F: fs/fuse/ F: include/uapi/linux/fuse.h +F: tools/testing/selftests/filesystems/fusectl
FUTEX SUBSYSTEM M: Thomas Gleixner tglx@linutronix.de diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 80fb84fa3cfcb..a9bfefa961889 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -36,6 +36,7 @@ TARGETS += filesystems/fat TARGETS += filesystems/overlayfs TARGETS += filesystems/statmount TARGETS += filesystems/mount-notify +TARGETS += filesystems/fusectl TARGETS += firmware TARGETS += fpu TARGETS += ftrace diff --git a/tools/testing/selftests/filesystems/fusectl/.gitignore b/tools/testing/selftests/filesystems/fusectl/.gitignore new file mode 100644 index 0000000000000..3e72e742d08e8 --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +fuse_mnt +fusectl_test diff --git a/tools/testing/selftests/filesystems/fusectl/Makefile b/tools/testing/selftests/filesystems/fusectl/Makefile new file mode 100644 index 0000000000000..612aad69a93aa --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/Makefile @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later
+CFLAGS += -Wall -O2 -g $(KHDR_INCLUDES)
+TEST_GEN_PROGS := fusectl_test +TEST_GEN_FILES := fuse_mnt
+include ../../lib.mk
+VAR_CFLAGS := $(shell pkg-config fuse --cflags 2>/dev/null) +ifeq ($(VAR_CFLAGS),) +VAR_CFLAGS := -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse +endif
+VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) +ifeq ($(VAR_LDLIBS),) +VAR_LDLIBS := -lfuse -pthread +endif
+$(OUTPUT)/fuse_mnt: CFLAGS += $(VAR_CFLAGS) +$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) diff --git a/tools/testing/selftests/filesystems/fusectl/fuse_mnt.c b/tools/testing/selftests/filesystems/fusectl/fuse_mnt.c new file mode 100644 index 0000000000000..d12b17f30fadc --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/fuse_mnt.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- fusectl test file-system
- Creates a simple FUSE filesystem with a single read-write file (/test)
- */
+#define FUSE_USE_VERSION 26
+#include <fuse.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h>
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+static char *content; +static size_t content_size = 0; +static const char test_path[] = "/test";
+static int test_getattr(const char *path, struct stat *st) +{
memset(st, 0, sizeof(*st));
if (!strcmp(path, "/")) {
st->st_mode = S_IFDIR | 0755;
st->st_nlink = 2;
return 0;
}
if (!strcmp(path, test_path)) {
st->st_mode = S_IFREG | 0664;
st->st_nlink = 1;
st->st_size = content_size;
return 0;
}
return -ENOENT;
+}
+static int test_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
+{
if (strcmp(path, "/"))
return -ENOENT;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, test_path + 1, NULL, 0);
return 0;
+}
+static int test_open(const char *path, struct fuse_file_info *fi) +{
if (strcmp(path, test_path))
return -ENOENT;
return 0;
+}
+static int test_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
+{
if (strcmp(path, test_path) != 0)
return -ENOENT;
if (!content || content_size == 0)
return 0;
if (offset >= content_size)
return 0;
if (offset + size > content_size)
size = content_size - offset;
memcpy(buf, content + offset, size);
return size;
+}
+static int test_write(const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
+{
size_t new_size;
if (strcmp(path, test_path) != 0)
return -ENOENT;
if(offset > content_size)
return -EINVAL;
new_size = MAX(offset + size, content_size);
if (new_size > content_size)
content = realloc(content, new_size);
content_size = new_size;
if (!content)
return -ENOMEM;
memcpy(content + offset, buf, size);
return size;
+}
+static int test_truncate(const char *path, off_t size) +{
if (strcmp(path, test_path) != 0)
return -ENOENT;
if (size == 0) {
free(content);
content = NULL;
content_size = 0;
return 0;
}
content = realloc(content, size);
if (!content)
return -ENOMEM;
if (size > content_size)
memset(content + content_size, 0, size - content_size);
content_size = size;
return 0;
+}
+static struct fuse_operations memfd_ops = {
.getattr = test_getattr,
.readdir = test_readdir,
.open = test_open,
.read = test_read,
.write = test_write,
.truncate = test_truncate,
+};
+int main(int argc, char *argv[]) +{
return fuse_main(argc, argv, &memfd_ops, NULL);
+} diff --git a/tools/testing/selftests/filesystems/fusectl/fusectl_test.c b/tools/testing/selftests/filesystems/fusectl/fusectl_test.c new file mode 100644 index 0000000000000..8ff130ae43122 --- /dev/null +++ b/tools/testing/selftests/filesystems/fusectl/fusectl_test.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (c) 2025 Chen Linxuan chenlinxuan@uniontech.com
+#define _GNU_SOURCE
+#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <dirent.h> +#include <linux/limits.h>
+#include "../../kselftest_harness.h"
+#define FUSECTL_MOUNTPOINT "/sys/fs/fuse/connections" +#define FUSE_MOUNTPOINT "/tmp/fuse_mnt_XXXXXX" +#define FUSE_DEVICE "/dev/fuse" +#define FUSECTL_TEST_VALUE "1"
+FIXTURE(fusectl){
char fuse_mountpoint[sizeof(FUSE_MOUNTPOINT)];
int connection;
+};
+FIXTURE_SETUP(fusectl) +{
const char *fuse_mnt_prog = "./fuse_mnt";
int status, pid;
struct stat statbuf;
strcpy(self->fuse_mountpoint, FUSE_MOUNTPOINT);
if (!mkdtemp(self->fuse_mountpoint))
SKIP(return,
"Failed to create FUSE mountpoint %s",
strerror(errno));
if (access(FUSECTL_MOUNTPOINT, F_OK))
SKIP(return,
"FUSE control filesystem not mounted");
pid = fork();
if (pid < 0)
SKIP(return,
"Failed to fork FUSE daemon process: %s",
strerror(errno));
if (pid == 0) {
execlp(fuse_mnt_prog, fuse_mnt_prog, self->fuse_mountpoint, NULL);
exit(errno);
}
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
SKIP(return,
"Failed to start FUSE daemon %s",
strerror(WEXITSTATUS(status)));
}
if (stat(self->fuse_mountpoint, &statbuf))
SKIP(return,
"Failed to stat FUSE mountpoint %s",
strerror(errno));
self->connection = statbuf.st_dev;
+}
+FIXTURE_TEARDOWN(fusectl) +{
umount(self->fuse_mountpoint);
rmdir(self->fuse_mountpoint);
+}
+TEST_F(fusectl, abort) +{
char path_buf[PATH_MAX];
int abort_fd, test_fd, ret;
sprintf(path_buf, "/sys/fs/fuse/connections/%d/abort", self->connection);
ASSERT_EQ(0, access(path_buf, F_OK));
abort_fd = open(path_buf, O_WRONLY);
ASSERT_GE(abort_fd, 0);
sprintf(path_buf, "%s/test", self->fuse_mountpoint);
test_fd = open(path_buf, O_RDWR);
ASSERT_GE(test_fd, 0);
ret = read(test_fd, path_buf, sizeof(path_buf));
ASSERT_EQ(ret, 0);
ret = write(test_fd, "test", sizeof("test"));
ASSERT_EQ(ret, sizeof("test"));
ret = lseek(test_fd, 0, SEEK_SET);
ASSERT_GE(ret, 0);
ret = write(abort_fd, FUSECTL_TEST_VALUE, sizeof(FUSECTL_TEST_VALUE));
ASSERT_GT(ret, 0);
close(abort_fd);
ret = read(test_fd, path_buf, sizeof(path_buf));
ASSERT_LT(ret, 0);
Nice! I guess you could also verify errno == ENOTCONN or whatever it is in this case.
Thanks, Amir.
On Thu, May 15, 2025 at 6:27 PM Amir Goldstein amir73il@gmail.com wrote:
On Thu, May 15, 2025 at 9:35 AM Chen Linxuan chenlinxuan@uniontech.com wrote:
ret = read(test_fd, path_buf, sizeof(path_buf));
ASSERT_LT(ret, 0);
Nice! I guess you could also verify errno == ENOTCONN or whatever it is in this case.
I am currently facing two issues:
1. I am not sure about the exact functions of max_background and congestion_threshold. I have prepared a patch that adds documentation for these two fields, which can be found here: https://lore.kernel.org/all/20250514061703.483505-2-chenlinxuan@uniontech.co...
2. How should I test the "waiting" file? My current idea is to have my FUSE daemon stay in a state where it does not respond to requests, and then use some form of inter-process communication (maybe a Unix socket?) to make it resume working. I am not sure if there is a better approach.
Thanks, Chen Linxuan.
On Mon, May 19, 2025 at 7:58 AM Chen Linxuan chenlinxuan@uniontech.com wrote:
On Thu, May 15, 2025 at 6:27 PM Amir Goldstein amir73il@gmail.com wrote:
On Thu, May 15, 2025 at 9:35 AM Chen Linxuan chenlinxuan@uniontech.com wrote:
ret = read(test_fd, path_buf, sizeof(path_buf));
ASSERT_LT(ret, 0);
Nice! I guess you could also verify errno == ENOTCONN or whatever it is in this case.
I am currently facing two issues:
- I am not sure about the exact functions of max_background and
congestion_threshold. I have prepared a patch that adds documentation for these two fields, which can be found here: https://lore.kernel.org/all/20250514061703.483505-2-chenlinxuan@uniontech.co...
It may be a bit challenging to design a test that does deterministic readahead, because there is usually no contract for readahead, so not sure.
- How should I test the "waiting" file? My current idea is to have my
FUSE daemon stay in a state where it does not respond to requests, and then use some form of inter-process communication (maybe a Unix socket?) to make it resume working. I am not sure if there is a better approach.
This is a good approach that several selftests use.
Looking at the bigger picture, your work to improve documentation and selftest coverage for fuse is very welcome! so I will add some wider context comments.
One small nit: please rename the test subdir to filesystems/fuse rather than filesystems/fusectl, so that more fuse selftests could be added later.
For the long run, I would consider a very minimal single threaded fuse server implementation that does not rely on libfuse for fuse selftests, because the selftest should not rely on the libfuse version installed on the development system and also testing low level protocol issues would require this anyway. But this is not a requirement for this first test.
Thanks, Amir.
linux-kselftest-mirror@lists.linaro.org