aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Somers <asomers@FreeBSD.org>2022-04-28 21:13:09 +0000
committerAlan Somers <asomers@FreeBSD.org>2022-08-20 01:11:23 +0000
commite2182a594d84a84a0ff3edf2a7ad9ee141027a60 (patch)
tree3f1f1cdba1f7081f1e8eb148f033da249f0a0046
parentb524667411e93d1e828bbaca03d96bb8637a5357 (diff)
downloadsrc-e2182a594d84a84a0ff3edf2a7ad9ee141027a60.tar.gz
src-e2182a594d84a84a0ff3edf2a7ad9ee141027a60.zip
fusefs: fix FUSE_CREATE with file handles and fuse protocol < 7.9
Prior to fuse protocol version 7.9, the fuse_entry_out structure had a smaller size. But fuse_vnop_create did not take that into account when working with servers that use older protocols. The bug does not matter for servers which don't use file handles or open flags (the only fields affected). PR: 263625 Submitted by: Ali Abdallah <ali.abdallah@suse.com> (cherry picked from commit 45825a12f9851213e627cf41398706bacb793f83)
-rw-r--r--sys/fs/fuse/fuse_vnops.c6
-rw-r--r--tests/sys/fs/fusefs/create.cc13
2 files changed, 13 insertions, 6 deletions
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
index b8d5af589a63..c390c5d7792c 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -713,7 +713,11 @@ fuse_vnop_create(struct vop_create_args *ap)
}
if (op == FUSE_CREATE) {
- foo = (struct fuse_open_out*)(feo + 1);
+ if (fuse_libabi_geq(data, 7, 9))
+ foo = (struct fuse_open_out*)(feo + 1);
+ else
+ foo = (struct fuse_open_out*)((char*)feo +
+ FUSE_COMPAT_ENTRY_OUT_SIZE);
} else {
/* Issue a separate FUSE_OPEN */
struct fuse_open_in *foi;
diff --git a/tests/sys/fs/fusefs/create.cc b/tests/sys/fs/fusefs/create.cc
index 0797a3ff9e34..df3225ed1837 100644
--- a/tests/sys/fs/fusefs/create.cc
+++ b/tests/sys/fs/fusefs/create.cc
@@ -415,15 +415,18 @@ TEST_F(Create_7_8, ok)
expect_create(RELPATH, mode,
ReturnImmediate([=](auto in __unused, auto& out) {
SET_OUT_HEADER_LEN(out, create_7_8);
- out.body.create.entry.attr.mode = mode;
- out.body.create.entry.nodeid = ino;
- out.body.create.entry.entry_valid = UINT64_MAX;
- out.body.create.entry.attr_valid = UINT64_MAX;
+ out.body.create_7_8.entry.attr.mode = mode;
+ out.body.create_7_8.entry.nodeid = ino;
+ out.body.create_7_8.entry.entry_valid = UINT64_MAX;
+ out.body.create_7_8.entry.attr_valid = UINT64_MAX;
+ out.body.create_7_8.open.fh = FH;
}));
+ expect_flush(ino, 1, ReturnErrno(0));
+ expect_release(ino, FH);
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
ASSERT_LE(0, fd) << strerror(errno);
- leak(fd);
+ close(fd);
}
TEST_F(Create_7_11, ok)