Page MenuHomeFreeBSD

D34753.id104521.diff
No OneTemporary

D34753.id104521.diff

Index: sys/fs/fuse/fuse_vnops.c
===================================================================
--- sys/fs/fuse/fuse_vnops.c
+++ sys/fs/fuse/fuse_vnops.c
@@ -1980,7 +1980,24 @@
fuse_filehandle_close(vp, fufh, td, NULL);
}
- if (!fuse_isdeadfs(vp) && fvdat->nlookup > 0) {
+ if (VTOI(vp) == 1) {
+ /*
+ * Don't send FUSE_FORGET for the root inode, because
+ * we never send FUSE_LOOKUP for it (see
+ * fuse_vfsop_root) and we don't want the server to see
+ * mismatched lookup counts.
+ */
+ struct fuse_data *data;
+ struct vnode *vroot;
+
+ data = fuse_get_mpdata(vnode_mount(vp));
+ FUSE_LOCK();
+ vroot = data->vroot;
+ data->vroot = NULL;
+ FUSE_UNLOCK();
+ if (vroot)
+ vrele(vroot);
+ } else if (!fuse_isdeadfs(vp) && fvdat->nlookup > 0) {
fuse_internal_forget_send(vnode_mount(vp), td, NULL, VTOI(vp),
fvdat->nlookup);
}
Index: tests/sys/fs/fusefs/destroy.cc
===================================================================
--- tests/sys/fs/fusefs/destroy.cc
+++ tests/sys/fs/fusefs/destroy.cc
@@ -141,7 +141,6 @@
uint64_t ino = 42;
expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
- expect_forget(FUSE_ROOT_ID, 1);
expect_forget(ino, 2);
expect_destroy(0);
Index: tests/sys/fs/fusefs/dev_fuse_poll.cc
===================================================================
--- tests/sys/fs/fusefs/dev_fuse_poll.cc
+++ tests/sys/fs/fusefs/dev_fuse_poll.cc
@@ -93,7 +93,6 @@
/* Ensure that we wake up pollers during unmount */
TEST_P(DevFusePoll, destroy)
{
- expect_forget(FUSE_ROOT_ID, 1);
expect_destroy(0);
m_mock->unmount();
Index: tests/sys/fs/fusefs/forget.cc
===================================================================
--- tests/sys/fs/fusefs/forget.cc
+++ tests/sys/fs/fusefs/forget.cc
@@ -32,6 +32,7 @@
extern "C" {
#include <sys/types.h>
+#include <sys/mount.h>
#include <sys/sysctl.h>
#include <fcntl.h>
@@ -145,3 +146,35 @@
/* Access the file again, causing another lookup */
ASSERT_EQ(0, access(FULLFPATH, F_OK)) << strerror(errno);
}
+
+/*
+ * Reclaiming the root inode should not send a FUSE_FORGET request, nor should
+ * it interfere with further lookup operations.
+ */
+TEST_F(Forget, root)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ uint64_t ino = 42;
+ mode_t mode = S_IFREG | 0755;
+
+ EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH)
+ .WillRepeatedly(Invoke(
+ ReturnImmediate([=](auto in __unused, auto& out) {
+ SET_OUT_HEADER_LEN(out, entry);
+ out.body.entry.attr.mode = mode;
+ out.body.entry.nodeid = ino;
+ out.body.entry.attr.nlink = 1;
+ out.body.entry.attr_valid = UINT64_MAX;
+ out.body.entry.entry_valid = UINT64_MAX;
+ })));
+
+ /* access(2) the file to force a lookup. */
+ ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno);
+
+ reclaim_vnode("mountpoint");
+ nap();
+
+ /* Access it again, to make sure it's still possible. */
+ ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno);
+}
Index: tests/sys/fs/fusefs/lookup.cc
===================================================================
--- tests/sys/fs/fusefs/lookup.cc
+++ tests/sys/fs/fusefs/lookup.cc
@@ -263,7 +263,6 @@
).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {
SET_OUT_HEADER_LEN(out, open);
})));
- expect_forget(FUSE_ROOT_ID, 1, NULL);
expect_forget(foo_ino, 1, NULL);
fd = open("mountpoint/foo/bar", O_EXEC| O_DIRECTORY);
@@ -574,7 +573,6 @@
).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {
SET_OUT_HEADER_LEN(out, open);
})));
- expect_forget(FUSE_ROOT_ID, 1, NULL);
expect_forget(foo_ino, 1, NULL);
EXPECT_LOOKUP(bar_ino, "..")
.WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 30, 5:07 AM (6 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32401982
Default Alt Text
D34753.id104521.diff (3 KB)

Event Timeline