Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107678911
D24777.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D24777.diff
View Options
Index: head/sys/fs/fuse/fuse_internal.c
===================================================================
--- head/sys/fs/fuse/fuse_internal.c
+++ head/sys/fs/fuse/fuse_internal.c
@@ -158,6 +158,7 @@
return 0;
}
+SDT_PROBE_DEFINE0(fusefs, , internal, access_vadmin);
/* Synchronously send a FUSE_ACCESS operation */
int
fuse_internal_access(struct vnode *vp,
@@ -210,10 +211,18 @@
va.va_gid, mode, cred, NULL);
}
+ if (mode & VADMIN) {
+ /*
+ * The FUSE protocol doesn't have an equivalent of VADMIN, so
+ * it's a bug if we ever reach this point with that bit set.
+ */
+ SDT_PROBE0(fusefs, , internal, access_vadmin);
+ }
+
if (!fsess_isimpl(mp, FUSE_ACCESS))
return 0;
- if ((mode & (VWRITE | VAPPEND | VADMIN)) != 0)
+ if ((mode & (VWRITE | VAPPEND)) != 0)
mask |= W_OK;
if ((mode & VREAD) != 0)
mask |= R_OK;
Index: head/sys/fs/fuse/fuse_vnops.c
===================================================================
--- head/sys/fs/fuse/fuse_vnops.c
+++ head/sys/fs/fuse/fuse_vnops.c
@@ -235,6 +235,7 @@
{
struct mount *mp = vnode_mount(vp);
struct fuse_data *data = fuse_get_mpdata(mp);
+ int default_permissions = data->dataflags & FSESS_DEFAULT_PERMISSIONS;
/*
* Kernel-invoked always succeeds.
@@ -248,12 +249,15 @@
*/
switch (ns) {
case EXTATTR_NAMESPACE_SYSTEM:
- if (data->dataflags & FSESS_DEFAULT_PERMISSIONS) {
+ if (default_permissions) {
return (priv_check_cred(cred, PRIV_VFS_EXTATTR_SYSTEM));
}
- /* FALLTHROUGH */
+ return (0);
case EXTATTR_NAMESPACE_USER:
- return (fuse_internal_access(vp, accmode, td, cred));
+ if (default_permissions) {
+ return (fuse_internal_access(vp, accmode, td, cred));
+ }
+ return (0);
default:
return (EPERM);
}
@@ -985,6 +989,8 @@
int wantparent = flags & (LOCKPARENT | WANTPARENT);
int islastcn = flags & ISLASTCN;
struct mount *mp = vnode_mount(dvp);
+ struct fuse_data *data = fuse_get_mpdata(mp);
+ int default_permissions = data->dataflags & FSESS_DEFAULT_PERMISSIONS;
int err = 0;
int lookup_err = 0;
@@ -1108,7 +1114,11 @@
if (lookup_err) {
/* Entry not found */
if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
- err = fuse_internal_access(dvp, VWRITE, td, cred);
+ if (default_permissions)
+ err = fuse_internal_access(dvp, VWRITE, td,
+ cred);
+ else
+ err = 0;
if (!err) {
/*
* Set the SAVENAME flag to hold onto the
@@ -1191,7 +1201,7 @@
&fvdat->entry_cache_timeout);
if ((nameiop == DELETE || nameiop == RENAME) &&
- islastcn)
+ islastcn && default_permissions)
{
struct vattr dvattr;
@@ -1828,7 +1838,11 @@
if (vfs_isrdonly(mp))
return EROFS;
- err = fuse_internal_access(vp, accmode, td, cred);
+ if (checkperm) {
+ err = fuse_internal_access(vp, accmode, td, cred);
+ } else {
+ err = 0;
+ }
if (err)
return err;
else
Index: head/tests/sys/fs/fusefs/access.cc
===================================================================
--- head/tests/sys/fs/fusefs/access.cc
+++ head/tests/sys/fs/fusefs/access.cc
@@ -31,6 +31,9 @@
*/
extern "C" {
+#include <sys/types.h>
+#include <sys/extattr.h>
+
#include <fcntl.h>
#include <unistd.h>
}
@@ -42,10 +45,33 @@
class Access: public FuseTest {
public:
+virtual void SetUp() {
+ FuseTest::SetUp();
+ // Clear the default FUSE_ACCESS expectation
+ Mock::VerifyAndClearExpectations(m_mock);
+}
+
void expect_lookup(const char *relpath, uint64_t ino)
{
FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, 0, 1);
}
+
+/*
+ * Expect tha FUSE_ACCESS will never be called for the given inode, with any
+ * bits in the supplied access_mask set
+ */
+void expect_noaccess(uint64_t ino, mode_t access_mask)
+{
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_ACCESS &&
+ in.header.nodeid == ino &&
+ in.body.access.mask & access_mask);
+ }, Eq(true)),
+ _)
+ ).Times(0);
+}
+
};
class RofsAccess: public Access {
@@ -56,6 +82,68 @@
}
};
+/*
+ * Change the mode of a file.
+ *
+ * There should never be a FUSE_ACCESS sent for this operation, except for
+ * search permissions on the parent directory.
+ * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245689
+ */
+TEST_F(Access, chmod)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ const uint64_t ino = 42;
+ const mode_t newmode = 0644;
+
+ expect_access(FUSE_ROOT_ID, X_OK, 0);
+ expect_lookup(RELPATH, ino);
+ expect_noaccess(ino, 0);
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([](auto in) {
+ return (in.header.opcode == FUSE_SETATTR &&
+ in.header.nodeid == ino);
+ }, Eq(true)),
+ _)
+ ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto& out) {
+ SET_OUT_HEADER_LEN(out, attr);
+ out.body.attr.attr.ino = ino; // Must match nodeid
+ out.body.attr.attr.mode = S_IFREG | newmode;
+ })));
+
+ EXPECT_EQ(0, chmod(FULLPATH, newmode)) << strerror(errno);
+}
+
+/*
+ * Create a new file
+ *
+ * There should never be a FUSE_ACCESS sent for this operation, except for
+ * search permissions on the parent directory.
+ * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245689
+ */
+TEST_F(Access, create)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ mode_t mode = S_IFREG | 0755;
+ uint64_t ino = 42;
+
+ expect_access(FUSE_ROOT_ID, X_OK, 0);
+ expect_noaccess(FUSE_ROOT_ID, R_OK | W_OK);
+ EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH)
+ .WillOnce(Invoke(ReturnErrno(ENOENT)));
+ expect_noaccess(ino, 0);
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_CREATE);
+ }, Eq(true)),
+ _)
+ ).WillOnce(ReturnErrno(EPERM));
+
+ EXPECT_EQ(-1, open(FULLPATH, O_CREAT | O_EXCL, mode));
+ EXPECT_EQ(EPERM, errno);
+}
+
/* The error case of FUSE_ACCESS. */
TEST_F(Access, eaccess)
{
@@ -105,6 +193,33 @@
ASSERT_EQ(EROFS, errno);
}
+
+/*
+ * Lookup an extended attribute
+ *
+ * There should never be a FUSE_ACCESS sent for this operation, except for
+ * search permissions on the parent directory.
+ * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245689
+ */
+TEST_F(Access, Getxattr)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ uint64_t ino = 42;
+ char data[80];
+ int ns = EXTATTR_NAMESPACE_USER;
+ ssize_t r;
+
+ expect_access(FUSE_ROOT_ID, X_OK, 0);
+ expect_lookup(RELPATH, ino);
+ expect_noaccess(ino, 0);
+ expect_getxattr(ino, "user.foo", ReturnErrno(ENOATTR));
+
+ r = extattr_get_file(FULLPATH, ns, "foo", data, sizeof(data));
+ ASSERT_EQ(-1, r);
+ ASSERT_EQ(ENOATTR, errno);
+}
+
/* The successful case of FUSE_ACCESS. */
TEST_F(Access, ok)
{
@@ -118,4 +233,71 @@
expect_access(ino, access_mode, 0);
ASSERT_EQ(0, access(FULLPATH, access_mode)) << strerror(errno);
+}
+
+/*
+ * Unlink a file
+ *
+ * There should never be a FUSE_ACCESS sent for this operation, except for
+ * search permissions on the parent directory.
+ * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245689
+ */
+TEST_F(Access, unlink)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ uint64_t ino = 42;
+
+ expect_access(FUSE_ROOT_ID, X_OK, 0);
+ expect_noaccess(FUSE_ROOT_ID, W_OK | R_OK);
+ expect_noaccess(ino, 0);
+ expect_lookup(RELPATH, ino);
+ expect_unlink(1, RELPATH, EPERM);
+
+ ASSERT_NE(0, unlink(FULLPATH));
+ ASSERT_EQ(EPERM, errno);
+}
+
+/*
+ * Unlink a file whose parent diretory's sticky bit is set
+ *
+ * There should never be a FUSE_ACCESS sent for this operation, except for
+ * search permissions on the parent directory.
+ * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245689
+ */
+TEST_F(Access, unlink_sticky_directory)
+{
+ const char FULLPATH[] = "mountpoint/some_file.txt";
+ const char RELPATH[] = "some_file.txt";
+ uint64_t ino = 42;
+
+ expect_access(FUSE_ROOT_ID, X_OK, 0);
+ expect_noaccess(FUSE_ROOT_ID, W_OK | R_OK);
+ expect_noaccess(ino, 0);
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_GETATTR &&
+ in.header.nodeid == FUSE_ROOT_ID);
+ }, Eq(true)),
+ _)
+ ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out)
+ {
+ SET_OUT_HEADER_LEN(out, attr);
+ out.body.attr.attr.ino = FUSE_ROOT_ID;
+ out.body.attr.attr.mode = S_IFDIR | 01777;
+ out.body.attr.attr.uid = 0;
+ out.body.attr.attr_valid = UINT64_MAX;
+ })));
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_ACCESS &&
+ in.header.nodeid == ino);
+ }, Eq(true)),
+ _)
+ ).Times(0);
+ expect_lookup(RELPATH, ino);
+ expect_unlink(FUSE_ROOT_ID, RELPATH, EPERM);
+
+ ASSERT_EQ(-1, unlink(FULLPATH));
+ ASSERT_EQ(EPERM, errno);
}
Index: head/tests/sys/fs/fusefs/rename.cc
===================================================================
--- head/tests/sys/fs/fusefs/rename.cc
+++ head/tests/sys/fs/fusefs/rename.cc
@@ -53,24 +53,6 @@
FuseTest::TearDown();
}
-
- void expect_getattr(uint64_t ino, mode_t mode)
- {
- EXPECT_CALL(*m_mock, process(
- ResultOf([=](auto in) {
- return (in.header.opcode == FUSE_GETATTR &&
- in.header.nodeid == ino);
- }, Eq(true)),
- _)
- ).WillOnce(Invoke(
- ReturnImmediate([=](auto i __unused, auto& out) {
- SET_OUT_HEADER_LEN(out, attr);
- out.body.attr.attr.ino = ino; // Must match nodeid
- out.body.attr.attr.mode = mode;
- out.body.attr.attr_valid = UINT64_MAX;
- })));
- }
-
};
// EINVAL, dst is subdir of src
@@ -82,7 +64,6 @@
const char RELSRC[] = "src";
uint64_t src_ino = 42;
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELSRC, src_ino, S_IFDIR | 0755, 0, 2);
EXPECT_LOOKUP(src_ino, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT)));
@@ -123,7 +104,6 @@
*/
struct timespec entry_valid = {.tv_sec = 0, .tv_nsec = 0};
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1);
/* LOOKUP returns a negative cache entry for dst */
EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST)
@@ -158,7 +138,6 @@
uint64_t ino = 42;
struct timespec entry_valid = {.tv_sec = TIME_T_MAX, .tv_nsec = 0};
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1);
/* LOOKUP returns a negative cache entry for dst */
EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST)
@@ -196,7 +175,6 @@
tmpfd = mkstemp(tmpfile);
ASSERT_LE(0, tmpfd) << strerror(errno);
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELB, b_ino, S_IFREG | 0644, 0, 2);
ASSERT_NE(0, rename(tmpfile, FULLB));
@@ -215,7 +193,6 @@
uint64_t dst_dir_ino = FUSE_ROOT_ID;
uint64_t ino = 42;
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1);
EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST)
.WillOnce(Invoke(ReturnErrno(ENOENT)));
@@ -251,7 +228,6 @@
struct stat sb;
expect_lookup(RELSRC, ino, S_IFDIR | 0755, 0, 1);
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
EXPECT_LOOKUP(FUSE_ROOT_ID, RELDSTDIR)
.WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {
SET_OUT_HEADER_LEN(out, entry);
@@ -303,7 +279,6 @@
uint64_t dst_dir_ino = FUSE_ROOT_ID;
uint64_t ino = 42;
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELSRC, ino, S_IFREG | 0644, 0, 1);
expect_lookup(RELDST, dst_ino, S_IFREG | 0644, 0, 1);
EXPECT_CALL(*m_mock, process(
Index: head/tests/sys/fs/fusefs/rmdir.cc
===================================================================
--- head/tests/sys/fs/fusefs/rmdir.cc
+++ head/tests/sys/fs/fusefs/rmdir.cc
@@ -42,22 +42,6 @@
class Rmdir: public FuseTest {
public:
-void expect_getattr(uint64_t ino, mode_t mode)
-{
- EXPECT_CALL(*m_mock, process(
- ResultOf([=](auto in) {
- return (in.header.opcode == FUSE_GETATTR &&
- in.header.nodeid == ino);
- }, Eq(true)),
- _)
- ).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto& out) {
- SET_OUT_HEADER_LEN(out, attr);
- out.body.attr.attr.ino = ino; // Must match nodeid
- out.body.attr.attr.mode = mode;
- out.body.attr.attr_valid = UINT64_MAX;
- })));
-}
-
void expect_lookup(const char *relpath, uint64_t ino, int times=1)
{
EXPECT_LOOKUP(FUSE_ROOT_ID, relpath)
@@ -95,25 +79,34 @@
struct stat sb;
sem_t sem;
uint64_t ino = 42;
+ Sequence seq;
ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno);
+ expect_lookup(RELPATH, ino);
EXPECT_CALL(*m_mock, process(
ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_RMDIR &&
+ 0 == strcmp(RELPATH, in.body.rmdir) &&
+ in.header.nodeid == FUSE_ROOT_ID);
+ }, Eq(true)),
+ _)
+ ).InSequence(seq)
+ .WillOnce(Invoke(ReturnErrno(0)));
+ expect_forget(ino, 1, &sem);
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
return (in.header.opcode == FUSE_GETATTR &&
in.header.nodeid == FUSE_ROOT_ID);
}, Eq(true)),
_)
- ).Times(2)
+ ).InSequence(seq)
.WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) {
SET_OUT_HEADER_LEN(out, attr);
- out.body.attr.attr.ino = ino; // Must match nodeid
+ out.body.attr.attr.ino = FUSE_ROOT_ID;
out.body.attr.attr.mode = S_IFDIR | 0755;
out.body.attr.attr_valid = UINT64_MAX;
})));
- expect_lookup(RELPATH, ino);
- expect_rmdir(FUSE_ROOT_ID, RELPATH, 0);
- expect_forget(ino, 1, &sem);
ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno);
EXPECT_EQ(0, stat("mountpoint", &sb)) << strerror(errno);
@@ -127,7 +120,6 @@
const char RELPATH[] = "some_dir";
uint64_t ino = 42;
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELPATH, ino);
expect_rmdir(FUSE_ROOT_ID, RELPATH, ENOTEMPTY);
@@ -143,7 +135,6 @@
sem_t sem;
uint64_t ino = 42;
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH, ino, 2);
expect_rmdir(FUSE_ROOT_ID, RELPATH, 0);
expect_forget(ino, 1, &sem);
@@ -163,7 +154,6 @@
ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno);
- expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755);
expect_lookup(RELPATH, ino);
expect_rmdir(FUSE_ROOT_ID, RELPATH, 0);
expect_forget(ino, 1, &sem);
Index: head/tests/sys/fs/fusefs/unlink.cc
===================================================================
--- head/tests/sys/fs/fusefs/unlink.cc
+++ head/tests/sys/fs/fusefs/unlink.cc
@@ -41,22 +41,6 @@
class Unlink: public FuseTest {
public:
-void expect_getattr(uint64_t ino, mode_t mode)
-{
- EXPECT_CALL(*m_mock, process(
- ResultOf([=](auto in) {
- return (in.header.opcode == FUSE_GETATTR &&
- in.header.nodeid == ino);
- }, Eq(true)),
- _)
- ).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto& out) {
- SET_OUT_HEADER_LEN(out, attr);
- out.body.attr.attr.ino = ino; // Must match nodeid
- out.body.attr.attr.mode = mode;
- out.body.attr.attr_valid = UINT64_MAX;
- })));
-}
-
void expect_lookup(const char *relpath, uint64_t ino, int times, int nlink=1)
{
EXPECT_LOOKUP(FUSE_ROOT_ID, relpath)
@@ -89,7 +73,6 @@
struct stat sb_old, sb_new;
int fd1;
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH0, ino, 1, 2);
expect_lookup(RELPATH1, ino, 1, 2);
expect_open(ino, 0, 1);
@@ -117,23 +100,32 @@
const char RELPATH[] = "some_file.txt";
struct stat sb;
uint64_t ino = 42;
+ Sequence seq;
+ /* Use nlink=2 so we don't get a FUSE_FORGET */
+ expect_lookup(RELPATH, ino, 1, 2);
EXPECT_CALL(*m_mock, process(
ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_UNLINK &&
+ 0 == strcmp(RELPATH, in.body.unlink) &&
+ in.header.nodeid == FUSE_ROOT_ID);
+ }, Eq(true)),
+ _)
+ ).InSequence(seq)
+ .WillOnce(Invoke(ReturnErrno(0)));
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
return (in.header.opcode == FUSE_GETATTR &&
in.header.nodeid == FUSE_ROOT_ID);
}, Eq(true)),
_)
- ).Times(2)
+ ).InSequence(seq)
.WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) {
SET_OUT_HEADER_LEN(out, attr);
- out.body.attr.attr.ino = ino; // Must match nodeid
+ out.body.attr.attr.ino = FUSE_ROOT_ID;
out.body.attr.attr.mode = S_IFDIR | 0755;
out.body.attr.attr_valid = UINT64_MAX;
})));
- /* Use nlink=2 so we don't get a FUSE_FORGET */
- expect_lookup(RELPATH, ino, 1, 2);
- expect_unlink(1, RELPATH, 0);
ASSERT_EQ(0, unlink(FULLPATH)) << strerror(errno);
EXPECT_EQ(0, stat("mountpoint", &sb)) << strerror(errno);
@@ -145,7 +137,6 @@
const char RELPATH[] = "some_file.txt";
uint64_t ino = 42;
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH, ino, 1);
expect_unlink(1, RELPATH, EPERM);
@@ -162,7 +153,6 @@
const char RELPATH[] = "some_file.txt";
uint64_t ino = 42;
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH, ino, 2, 2);
expect_unlink(1, RELPATH, 0);
@@ -182,7 +172,6 @@
const char RELPATH1[] = "other_file.txt";
uint64_t ino = 42;
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH0, ino, 1, 2);
expect_unlink(1, RELPATH0, 0);
EXPECT_CALL(*m_mock, process(
@@ -213,7 +202,6 @@
ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno);
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH, ino, 1);
expect_unlink(1, RELPATH, 0);
expect_forget(ino, 1, &sem);
@@ -233,7 +221,6 @@
uint64_t ino = 42;
int fd;
- expect_getattr(1, S_IFDIR | 0755);
expect_lookup(RELPATH0, ino, 2);
expect_open(ino, 0, 1);
expect_unlink(1, RELPATH0, 0);
Index: head/tests/sys/fs/fusefs/utils.hh
===================================================================
--- head/tests/sys/fs/fusefs/utils.hh
+++ head/tests/sys/fs/fusefs/utils.hh
@@ -133,6 +133,12 @@
void expect_getattr(uint64_t ino, uint64_t size);
/*
+ * Create an expectation that FUSE_GETXATTR will be called once for the
+ * given inode.
+ */
+ void expect_getxattr(uint64_t ino, const char *attr, ProcessMockerT r);
+
+ /*
* Create an expectation that FUSE_LOOKUP will be called for the given
* path exactly times times and cache validity period. It will respond
* with inode ino, mode mode, filesize size.
Index: head/tests/sys/fs/fusefs/utils.cc
===================================================================
--- head/tests/sys/fs/fusefs/utils.cc
+++ head/tests/sys/fs/fusefs/utils.cc
@@ -273,6 +273,20 @@
})));
}
+void FuseTest::expect_getxattr(uint64_t ino, const char *attr, ProcessMockerT r)
+{
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
+ const char *a = (const char*)in.body.bytes +
+ sizeof(fuse_getxattr_in);
+ return (in.header.opcode == FUSE_GETXATTR &&
+ in.header.nodeid == ino &&
+ 0 == strcmp(attr, a));
+ }, Eq(true)),
+ _)
+ ).WillOnce(Invoke(r));
+}
+
void FuseTest::expect_lookup(const char *relpath, uint64_t ino, mode_t mode,
uint64_t size, int times, uint64_t attr_valid, uid_t uid, gid_t gid)
{
Index: head/tests/sys/fs/fusefs/xattr.cc
===================================================================
--- head/tests/sys/fs/fusefs/xattr.cc
+++ head/tests/sys/fs/fusefs/xattr.cc
@@ -62,20 +62,6 @@
class Xattr: public FuseTest {
public:
-void expect_getxattr(uint64_t ino, const char *attr, ProcessMockerT r)
-{
- EXPECT_CALL(*m_mock, process(
- ResultOf([=](auto in) {
- const char *a = (const char*)in.body.bytes +
- sizeof(fuse_getxattr_in);
- return (in.header.opcode == FUSE_GETXATTR &&
- in.header.nodeid == ino &&
- 0 == strcmp(attr, a));
- }, Eq(true)),
- _)
- ).WillOnce(Invoke(r));
-}
-
void expect_listxattr(uint64_t ino, uint32_t size, ProcessMockerT r,
Sequence *seq = NULL)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 18, 12:55 PM (6 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15859543
Default Alt Text
D24777.diff (19 KB)
Attached To
Mode
D24777: Fix issues with FUSE_ACCESS when default_permissions is disabled
Attached
Detach File
Event Timeline
Log In to Comment