Page MenuHomeFreeBSD

D24777.diff
No OneTemporary

D24777.diff

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

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)

Event Timeline