git: 039609b04d63 - stable/13 - fusefs: ignore FUSE_NO_OPEN(DIR)_SUPPORT flags
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 20 Jan 2025 22:36:12 UTC
The branch stable/13 has been updated by asomers:
URL: https://cgit.FreeBSD.org/src/commit/?id=039609b04d63f2e597d70fec66915a766834e81c
commit 039609b04d63f2e597d70fec66915a766834e81c
Author: CismonX <admin@cismon.net>
AuthorDate: 2024-11-02 20:19:15 +0000
Commit: Alan Somers <asomers@FreeBSD.org>
CommitDate: 2025-01-20 22:34:18 +0000
fusefs: ignore FUSE_NO_OPEN(DIR)_SUPPORT flags
The FUSE_NO_OPEN_SUPPORT and FUSE_NO_OPENDIR_SUPPORT flags
are only meant to indicate kernel features, and should be ignored
if they appear in the FUSE_INIT reply flags.
Also fix the corresponding test cases.
Reviewed by: Alan Somers <asomers@FreeBSD.org>
Signed-off-by: CismonX <admin@cismon.net>
Pull Request: https://github.com/freebsd/freebsd-src/pull/1509
(cherry picked from commit f0f596bd955e5b48c55db502e79fc652ac8970d3)
---
sys/fs/fuse/fuse_file.c | 9 +++------
sys/fs/fuse/fuse_internal.c | 4 ----
sys/fs/fuse/fuse_ipc.h | 2 --
sys/fs/fuse/fuse_vnops.c | 17 ++++++++---------
tests/sys/fs/fusefs/open.cc | 38 ++------------------------------------
tests/sys/fs/fusefs/opendir.cc | 27 ++-------------------------
6 files changed, 15 insertions(+), 82 deletions(-)
diff --git a/sys/fs/fuse/fuse_file.c b/sys/fs/fuse/fuse_file.c
index ecaa641a9261..22fc283e263c 100644
--- a/sys/fs/fuse/fuse_file.c
+++ b/sys/fs/fuse/fuse_file.c
@@ -123,7 +123,6 @@ fuse_filehandle_open(struct vnode *vp, int a_mode,
struct fuse_filehandle **fufhp, struct thread *td, struct ucred *cred)
{
struct mount *mp = vnode_mount(vp);
- struct fuse_data *data = fuse_get_mpdata(mp);
struct fuse_dispatcher fdi;
const struct fuse_open_out default_foo = {
.fh = 0,
@@ -133,12 +132,10 @@ fuse_filehandle_open(struct vnode *vp, int a_mode,
struct fuse_open_in *foi = NULL;
const struct fuse_open_out *foo;
fufh_type_t fufh_type;
- int dataflags = data->dataflags;
int err = 0;
int oflags = 0;
int op = FUSE_OPEN;
int relop = FUSE_RELEASE;
- int fsess_no_op_support = FSESS_NO_OPEN_SUPPORT;
fufh_type = fflags_2_fufh_type(a_mode);
oflags = fufh_type_2_fflags(fufh_type);
@@ -146,12 +143,11 @@ fuse_filehandle_open(struct vnode *vp, int a_mode,
if (vnode_isdir(vp)) {
op = FUSE_OPENDIR;
relop = FUSE_RELEASEDIR;
- fsess_no_op_support = FSESS_NO_OPENDIR_SUPPORT;
/* vn_open_vnode already rejects FWRITE on directories */
MPASS(fufh_type == FUFH_RDONLY || fufh_type == FUFH_EXEC);
}
fdisp_init(&fdi, sizeof(*foi));
- if (fsess_not_impl(mp, op) && dataflags & fsess_no_op_support) {
+ if (fsess_not_impl(mp, op)) {
/* The operation implicitly succeeds */
foo = &default_foo;
} else {
@@ -161,7 +157,7 @@ fuse_filehandle_open(struct vnode *vp, int a_mode,
foi->flags = oflags;
err = fdisp_wait_answ(&fdi);
- if (err == ENOSYS && dataflags & fsess_no_op_support) {
+ if (err == ENOSYS) {
/* The operation implicitly succeeds */
foo = &default_foo;
fsess_set_notimpl(mp, op);
@@ -175,6 +171,7 @@ fuse_filehandle_open(struct vnode *vp, int a_mode,
goto out;
} else {
foo = fdi.answ;
+ fsess_set_impl(mp, op);
}
}
diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c
index adf84d30e801..9f47d960d050 100644
--- a/sys/fs/fuse/fuse_internal.c
+++ b/sys/fs/fuse/fuse_internal.c
@@ -1012,10 +1012,6 @@ fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio)
data->dataflags |= FSESS_POSIX_LOCKS;
if (fiio->flags & FUSE_EXPORT_SUPPORT)
data->dataflags |= FSESS_EXPORT_SUPPORT;
- if (fiio->flags & FUSE_NO_OPEN_SUPPORT)
- data->dataflags |= FSESS_NO_OPEN_SUPPORT;
- if (fiio->flags & FUSE_NO_OPENDIR_SUPPORT)
- data->dataflags |= FSESS_NO_OPENDIR_SUPPORT;
/*
* Don't bother to check FUSE_BIG_WRITES, because it's
* redundant with max_write
diff --git a/sys/fs/fuse/fuse_ipc.h b/sys/fs/fuse/fuse_ipc.h
index 0ec556138be0..5648624f4c63 100644
--- a/sys/fs/fuse/fuse_ipc.h
+++ b/sys/fs/fuse/fuse_ipc.h
@@ -227,8 +227,6 @@ struct fuse_data {
/* (and being observed by the daemon) */
#define FSESS_PUSH_SYMLINKS_IN 0x0020 /* prefix absolute symlinks with mp */
#define FSESS_DEFAULT_PERMISSIONS 0x0040 /* kernel does permission checking */
-#define FSESS_NO_OPEN_SUPPORT 0x0080 /* can elide FUSE_OPEN ops */
-#define FSESS_NO_OPENDIR_SUPPORT 0x0100 /* can elide FUSE_OPENDIR ops */
#define FSESS_ASYNC_READ 0x1000 /* allow multiple reads of some file */
#define FSESS_POSIX_LOCKS 0x2000 /* daemon supports POSIX locks */
#define FSESS_EXPORT_SUPPORT 0x10000 /* daemon supports NFS-style lookups */
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
index aa44366ccb95..79317e4e4cd2 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -1961,10 +1961,9 @@ fuse_vnop_readdir(struct vop_readdir_args *ap)
tresid = uio->uio_resid;
err = fuse_filehandle_get_dir(vp, &fufh, cred, pid);
if (err == EBADF && mp->mnt_flag & MNT_EXPORTED) {
- KASSERT(fuse_get_mpdata(mp)->dataflags
- & FSESS_NO_OPENDIR_SUPPORT,
- ("FUSE file systems that don't set "
- "FUSE_NO_OPENDIR_SUPPORT should not be exported"));
+ KASSERT(!fsess_is_impl(mp, FUSE_OPENDIR),
+ ("FUSE file systems that implement "
+ "FUSE_OPENDIR should not be exported"));
/*
* nfsd will do VOP_READDIR without first doing VOP_OPEN. We
* must implicitly open the directory here.
@@ -3118,21 +3117,21 @@ fuse_vnop_vptofh(struct vop_vptofh_args *ap)
return EOPNOTSUPP;
}
if ((mp->mnt_flag & MNT_EXPORTED) &&
- !(data->dataflags & FSESS_NO_OPENDIR_SUPPORT))
+ fsess_is_impl(mp, FUSE_OPENDIR))
{
/*
* NFS is stateless, so nfsd must reopen a directory on every
* call to VOP_READDIR, passing in the d_off field from the
- * final dirent of the previous invocation. But without
- * FUSE_NO_OPENDIR_SUPPORT, the FUSE protocol does not
+ * final dirent of the previous invocation. But if the server
+ * implements FUSE_OPENDIR, the FUSE protocol does not
* guarantee that d_off will be valid after a directory is
* closed and reopened. So prohibit exporting FUSE file
- * systems that don't set that flag.
+ * systems that implement FUSE_OPENDIR.
*
* But userspace NFS servers don't have this problem.
*/
SDT_PROBE2(fusefs, , vnops, trace, 1,
- "VOP_VPTOFH without FUSE_NO_OPENDIR_SUPPORT");
+ "VOP_VPTOFH with FUSE_OPENDIR");
return EOPNOTSUPP;
}
diff --git a/tests/sys/fs/fusefs/open.cc b/tests/sys/fs/fusefs/open.cc
index 7ab3aeb6ba2a..e80d1aa2a393 100644
--- a/tests/sys/fs/fusefs/open.cc
+++ b/tests/sys/fs/fusefs/open.cc
@@ -70,14 +70,6 @@ void test_ok(int os_flags, int fuse_flags) {
}
};
-
-class OpenNoOpenSupport: public FuseTest {
- virtual void SetUp() {
- m_init_flags = FUSE_NO_OPEN_SUPPORT;
- FuseTest::SetUp();
- }
-};
-
/*
* fusefs(5) does not support I/O on device nodes (neither does UFS). But it
* shouldn't crash
@@ -281,37 +273,11 @@ TEST_F(Open, o_rdwr)
}
/*
- * Without FUSE_NO_OPEN_SUPPORT, returning ENOSYS is an error
- */
-TEST_F(Open, enosys)
-{
- const char FULLPATH[] = "mountpoint/some_file.txt";
- const char RELPATH[] = "some_file.txt";
- uint64_t ino = 42;
- int fd;
-
- FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
- EXPECT_CALL(*m_mock, process(
- ResultOf([=](auto in) {
- return (in.header.opcode == FUSE_OPEN &&
- in.body.open.flags == (uint32_t)O_RDONLY &&
- in.header.nodeid == ino);
- }, Eq(true)),
- _)
- ).Times(1)
- .WillOnce(Invoke(ReturnErrno(ENOSYS)));
-
- fd = open(FULLPATH, O_RDONLY);
- ASSERT_EQ(-1, fd) << strerror(errno);
- EXPECT_EQ(ENOSYS, errno);
-}
-
-/*
- * If a fuse server sets FUSE_NO_OPEN_SUPPORT and returns ENOSYS to a
+ * If a fuse server returns ENOSYS to a
* FUSE_OPEN, then it and subsequent FUSE_OPEN and FUSE_RELEASE operations will
* also succeed automatically without being sent to the server.
*/
-TEST_F(OpenNoOpenSupport, enosys)
+TEST_F(Open, enosys)
{
const char FULLPATH[] = "mountpoint/some_file.txt";
const char RELPATH[] = "some_file.txt";
diff --git a/tests/sys/fs/fusefs/opendir.cc b/tests/sys/fs/fusefs/opendir.cc
index dd837a8d43c1..e1fed59635fc 100644
--- a/tests/sys/fs/fusefs/opendir.cc
+++ b/tests/sys/fs/fusefs/opendir.cc
@@ -71,13 +71,6 @@ void expect_opendir(uint64_t ino, uint32_t flags, ProcessMockerT r)
};
-class OpendirNoOpendirSupport: public Opendir {
- virtual void SetUp() {
- m_init_flags = FUSE_NO_OPENDIR_SUPPORT;
- FuseTest::SetUp();
- }
-};
-
/*
* The fuse daemon fails the request with enoent. This usually indicates a
@@ -179,27 +172,11 @@ TEST_F(Opendir, opendir)
}
/*
- * Without FUSE_NO_OPENDIR_SUPPORT, returning ENOSYS is an error
- */
-TEST_F(Opendir, enosys)
-{
- const char FULLPATH[] = "mountpoint/some_file.txt";
- const char RELPATH[] = "some_file.txt";
- uint64_t ino = 42;
-
- expect_lookup(RELPATH, ino);
- expect_opendir(ino, O_RDONLY, ReturnErrno(ENOSYS));
-
- EXPECT_EQ(-1, open(FULLPATH, O_DIRECTORY));
- EXPECT_EQ(ENOSYS, errno);
-}
-
-/*
- * If a fuse server sets FUSE_NO_OPENDIR_SUPPORT and returns ENOSYS to a
+ * If a fuse server returns ENOSYS to a
* FUSE_OPENDIR, then it and subsequent FUSE_OPENDIR and FUSE_RELEASEDIR
* operations will also succeed automatically without being sent to the server.
*/
-TEST_F(OpendirNoOpendirSupport, enosys)
+TEST_F(Opendir, enosys)
{
const char FULLPATH[] = "mountpoint/some_file.txt";
const char RELPATH[] = "some_file.txt";