fusefs: cache file attributes
FUSE_LOOKUP, FUSE_GETATTR, FUSE_SETATTR, FUSE_MKDIR, FUSE_LINK, FUSE_SYMLINK, FUSE_MKNOD, and FUSE_CREATE all return file attributes with a cache validity period. fusefs will now cache the attributes, if the server returns a non-zero cache validity period. This change does _not_ implement finite attr cache timeouts. That will follow as part of PR 235773. PR: 235775 Reported by: cem Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
caf5f57d2d
commit
cad677915f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=346043
@ -175,9 +175,9 @@ fuse_internal_access(struct vnode *vp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cache FUSE attributes from feo, in attr cache associated with vnode 'vp'.
|
* Cache FUSE attributes from attr, in attribute cache associated with vnode
|
||||||
* Optionally, if argument 'vap' is not NULL, store a copy of the converted
|
* 'vp'. Optionally, if argument 'vap' is not NULL, store a copy of the
|
||||||
* attributes there as well.
|
* converted attributes there as well.
|
||||||
*
|
*
|
||||||
* If the nominal attribute cache TTL is zero, do not cache on the 'vp' (but do
|
* If the nominal attribute cache TTL is zero, do not cache on the 'vp' (but do
|
||||||
* return the result to the caller).
|
* return the result to the caller).
|
||||||
@ -583,6 +583,62 @@ fuse_internal_forget_send(struct mount *mp,
|
|||||||
fdisp_destroy(&fdi);
|
fdisp_destroy(&fdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read a vnode's attributes from cache or fetch them from the fuse daemon */
|
||||||
|
int
|
||||||
|
fuse_internal_getattr(struct vnode *vp, struct vattr *vap, struct ucred *cred,
|
||||||
|
struct thread *td)
|
||||||
|
{
|
||||||
|
struct fuse_dispatcher fdi;
|
||||||
|
struct fuse_vnode_data *fvdat = VTOFUD(vp);
|
||||||
|
struct vattr *attrs;
|
||||||
|
struct fuse_attr_out *fao;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if ((attrs = VTOVA(vp)) != NULL) {
|
||||||
|
/* struct copy */
|
||||||
|
*vap = *attrs;
|
||||||
|
if ((fvdat->flag & FN_SIZECHANGE) != 0)
|
||||||
|
vap->va_size = fvdat->filesize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdisp_init(&fdi, 0);
|
||||||
|
if ((err = fdisp_simple_putget_vp(&fdi, FUSE_GETATTR, vp, td, cred))) {
|
||||||
|
if (err == ENOENT) {
|
||||||
|
fuse_internal_vnode_disappear(vp);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fao = (struct fuse_attr_out *)fdi.answ;
|
||||||
|
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid,
|
||||||
|
fao->attr_valid_nsec, vap);
|
||||||
|
if (vap->va_type != vnode_vtype(vp)) {
|
||||||
|
fuse_internal_vnode_disappear(vp);
|
||||||
|
err = ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if ((fvdat->flag & FN_SIZECHANGE) != 0)
|
||||||
|
vap->va_size = fvdat->filesize;
|
||||||
|
|
||||||
|
if (vnode_isreg(vp) && (fvdat->flag & FN_SIZECHANGE) == 0) {
|
||||||
|
/*
|
||||||
|
* This is for those cases when the file size changed without us
|
||||||
|
* knowing, and we want to catch up.
|
||||||
|
*/
|
||||||
|
off_t new_filesize = fao->attr.size;
|
||||||
|
|
||||||
|
if (fvdat->filesize != new_filesize) {
|
||||||
|
fuse_vnode_setsize(vp, cred, new_filesize);
|
||||||
|
fvdat->flag &= ~FN_SIZECHANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
fdisp_destroy(&fdi);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fuse_internal_vnode_disappear(struct vnode *vp)
|
fuse_internal_vnode_disappear(struct vnode *vp)
|
||||||
{
|
{
|
||||||
|
@ -199,6 +199,10 @@ int fuse_internal_fsync(struct vnode *vp, struct thread *td, int waitfor,
|
|||||||
bool datasync);
|
bool datasync);
|
||||||
int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
|
int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
|
||||||
|
|
||||||
|
/* getattr */
|
||||||
|
int fuse_internal_getattr(struct vnode *vp, struct vattr *vap,
|
||||||
|
struct ucred *cred, struct thread *td);
|
||||||
|
|
||||||
/* readdir */
|
/* readdir */
|
||||||
|
|
||||||
struct pseudo_dirent {
|
struct pseudo_dirent {
|
||||||
|
@ -403,6 +403,7 @@ int
|
|||||||
fuse_vnode_setsize(struct vnode *vp, struct ucred *cred, off_t newsize)
|
fuse_vnode_setsize(struct vnode *vp, struct ucred *cred, off_t newsize)
|
||||||
{
|
{
|
||||||
struct fuse_vnode_data *fvdat = VTOFUD(vp);
|
struct fuse_vnode_data *fvdat = VTOFUD(vp);
|
||||||
|
struct vattr *attrs;
|
||||||
off_t oldsize;
|
off_t oldsize;
|
||||||
size_t iosize;
|
size_t iosize;
|
||||||
struct buf *bp = NULL;
|
struct buf *bp = NULL;
|
||||||
@ -413,6 +414,8 @@ fuse_vnode_setsize(struct vnode *vp, struct ucred *cred, off_t newsize)
|
|||||||
iosize = fuse_iosize(vp);
|
iosize = fuse_iosize(vp);
|
||||||
oldsize = fvdat->filesize;
|
oldsize = fvdat->filesize;
|
||||||
fvdat->filesize = newsize;
|
fvdat->filesize = newsize;
|
||||||
|
if ((attrs = VTOVA(vp)) != NULL)
|
||||||
|
attrs->va_size = newsize;
|
||||||
fvdat->flag |= FN_SIZECHANGE;
|
fvdat->flag |= FN_SIZECHANGE;
|
||||||
|
|
||||||
if (newsize < oldsize) {
|
if (newsize < oldsize) {
|
||||||
|
@ -80,7 +80,7 @@ struct fuse_vnode_data {
|
|||||||
uint64_t parent_nid;
|
uint64_t parent_nid;
|
||||||
|
|
||||||
/** I/O **/
|
/** I/O **/
|
||||||
/* List of file data for each of the vnode's open file descriptors */
|
/* List of file handles for all of the vnode's open file descriptors */
|
||||||
LIST_HEAD(, fuse_filehandle) handles;
|
LIST_HEAD(, fuse_filehandle) handles;
|
||||||
|
|
||||||
/** flags **/
|
/** flags **/
|
||||||
|
@ -478,6 +478,8 @@ fuse_vnop_create(struct vop_create_args *ap)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create");
|
ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create");
|
||||||
|
fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid,
|
||||||
|
feo->attr_valid_nsec, NULL);
|
||||||
|
|
||||||
fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, td, cred, foo);
|
fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, td, cred, foo);
|
||||||
fuse_vnode_open(*vpp, foo->open_flags, td);
|
fuse_vnode_open(*vpp, foo->open_flags, td);
|
||||||
@ -555,12 +557,9 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
|
|||||||
struct vattr *vap = ap->a_vap;
|
struct vattr *vap = ap->a_vap;
|
||||||
struct ucred *cred = ap->a_cred;
|
struct ucred *cred = ap->a_cred;
|
||||||
struct thread *td = curthread;
|
struct thread *td = curthread;
|
||||||
struct fuse_vnode_data *fvdat = VTOFUD(vp);
|
|
||||||
struct fuse_attr_out *fao;
|
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int dataflags;
|
int dataflags;
|
||||||
struct fuse_dispatcher fdi;
|
|
||||||
|
|
||||||
dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags;
|
dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags;
|
||||||
|
|
||||||
@ -575,48 +574,14 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
|
|||||||
goto fake;
|
goto fake;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fdisp_init(&fdi, 0);
|
err = fuse_internal_getattr(vp, vap, cred, td);
|
||||||
if ((err = fdisp_simple_putget_vp(&fdi, FUSE_GETATTR, vp, td, cred))) {
|
if (err == ENOTCONN && vnode_isvroot(vp)) {
|
||||||
if ((err == ENOTCONN) && vnode_isvroot(vp)) {
|
/* see comment in fuse_vfsop_statfs() */
|
||||||
/* see comment in fuse_vfsop_statfs() */
|
goto fake;
|
||||||
fdisp_destroy(&fdi);
|
} else {
|
||||||
goto fake;
|
return err;
|
||||||
}
|
|
||||||
if (err == ENOENT) {
|
|
||||||
fuse_internal_vnode_disappear(vp);
|
|
||||||
}
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fao = (struct fuse_attr_out *)fdi.answ;
|
|
||||||
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid,
|
|
||||||
fao->attr_valid_nsec, vap);
|
|
||||||
if (vap->va_type != vnode_vtype(vp)) {
|
|
||||||
fuse_internal_vnode_disappear(vp);
|
|
||||||
err = ENOENT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((fvdat->flag & FN_SIZECHANGE) != 0)
|
|
||||||
vap->va_size = fvdat->filesize;
|
|
||||||
|
|
||||||
if (vnode_isreg(vp) && (fvdat->flag & FN_SIZECHANGE) == 0) {
|
|
||||||
/*
|
|
||||||
* This is for those cases when the file size changed without us
|
|
||||||
* knowing, and we want to catch up.
|
|
||||||
*/
|
|
||||||
off_t new_filesize = ((struct fuse_attr_out *)
|
|
||||||
fdi.answ)->attr.size;
|
|
||||||
|
|
||||||
if (fvdat->filesize != new_filesize) {
|
|
||||||
fuse_vnode_setsize(vp, cred, new_filesize);
|
|
||||||
fvdat->flag &= ~FN_SIZECHANGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
fdisp_destroy(&fdi);
|
|
||||||
return err;
|
|
||||||
|
|
||||||
fake:
|
fake:
|
||||||
bzero(vap, sizeof(*vap));
|
bzero(vap, sizeof(*vap));
|
||||||
vap->va_type = vnode_vtype(vp);
|
vap->va_type = vnode_vtype(vp);
|
||||||
|
@ -80,7 +80,6 @@ TEST_F(AllowOther, allowed)
|
|||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_flush(ino, 1, ReturnErrno(0));
|
expect_flush(ino, 1, ReturnErrno(0));
|
||||||
expect_release(ino, FH);
|
expect_release(ino, FH);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
}, []() {
|
}, []() {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -137,7 +136,6 @@ TEST_F(AllowOther, privilege_escalation)
|
|||||||
_)
|
_)
|
||||||
).Times(AnyNumber())
|
).Times(AnyNumber())
|
||||||
.WillRepeatedly(Invoke(ReturnErrno(EPERM)));
|
.WillRepeatedly(Invoke(ReturnErrno(EPERM)));
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd1 = open(FULLPATH, O_RDONLY);
|
fd1 = open(FULLPATH, O_RDONLY);
|
||||||
EXPECT_LE(0, fd1) << strerror(errno);
|
EXPECT_LE(0, fd1) << strerror(errno);
|
||||||
|
@ -59,8 +59,7 @@ void expect_create(const char *relpath, ProcessMockerT r)
|
|||||||
* If FUSE_CREATE sets the attr_valid, then subsequent GETATTRs should use the
|
* If FUSE_CREATE sets the attr_valid, then subsequent GETATTRs should use the
|
||||||
* attribute cache
|
* attribute cache
|
||||||
*/
|
*/
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */
|
TEST_F(Create, attr_cache)
|
||||||
TEST_F(Create, DISABLED_attr_cache)
|
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
@ -151,19 +150,6 @@ TEST_F(Create, Enosys)
|
|||||||
SET_OUT_HEADER_LEN(out, open);
|
SET_OUT_HEADER_LEN(out, open);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | 0644;
|
|
||||||
})));
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
||||||
EXPECT_LE(0, fd) << strerror(errno);
|
EXPECT_LE(0, fd) << strerror(errno);
|
||||||
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
||||||
@ -196,19 +182,6 @@ TEST_F(Create, entry_cache_negative)
|
|||||||
out->body.create.entry.attr_valid = UINT64_MAX;
|
out->body.create.entry.attr_valid = UINT64_MAX;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | 0644;
|
|
||||||
})));
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
||||||
ASSERT_LE(0, fd) << strerror(errno);
|
ASSERT_LE(0, fd) << strerror(errno);
|
||||||
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
||||||
@ -239,19 +212,6 @@ TEST_F(Create, entry_cache_negative_purge)
|
|||||||
out->body.create.entry.attr_valid = UINT64_MAX;
|
out->body.create.entry.attr_valid = UINT64_MAX;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | 0644;
|
|
||||||
})));
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
||||||
ASSERT_LE(0, fd) << strerror(errno);
|
ASSERT_LE(0, fd) << strerror(errno);
|
||||||
|
|
||||||
@ -296,19 +256,6 @@ TEST_F(Create, ok)
|
|||||||
out->body.create.entry.attr_valid = UINT64_MAX;
|
out->body.create.entry.attr_valid = UINT64_MAX;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | mode;
|
|
||||||
})));
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
|
||||||
EXPECT_LE(0, fd) << strerror(errno);
|
EXPECT_LE(0, fd) << strerror(errno);
|
||||||
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
||||||
@ -339,19 +286,6 @@ TEST_F(Create, wronly_0444)
|
|||||||
out->body.create.entry.attr_valid = UINT64_MAX;
|
out->body.create.entry.attr_valid = UINT64_MAX;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | mode;
|
|
||||||
})));
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_CREAT | O_WRONLY, mode);
|
fd = open(FULLPATH, O_CREAT | O_WRONLY, mode);
|
||||||
EXPECT_LE(0, fd) << strerror(errno);
|
EXPECT_LE(0, fd) << strerror(errno);
|
||||||
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
||||||
|
@ -111,8 +111,6 @@ TEST_F(Open, ok)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, S_IFREG | 0644);
|
expect_lookup(RELPATH, ino, S_IFREG | 0644);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
EXPECT_LE(0, fd) << strerror(errno);
|
EXPECT_LE(0, fd) << strerror(errno);
|
||||||
|
@ -96,7 +96,6 @@ TEST_F(Flush, open_twice)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 2);
|
expect_lookup(RELPATH, ino, 2);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 2, 0, ReturnErrno(0));
|
expect_flush(ino, 2, 0, ReturnErrno(0));
|
||||||
expect_release();
|
expect_release();
|
||||||
|
|
||||||
@ -127,7 +126,6 @@ TEST_F(Flush, eio)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 1, 0, ReturnErrno(EIO));
|
expect_flush(ino, 1, 0, ReturnErrno(EIO));
|
||||||
expect_release();
|
expect_release();
|
||||||
|
|
||||||
@ -153,14 +151,12 @@ TEST_F(Flush, enosys)
|
|||||||
|
|
||||||
expect_lookup(RELPATH0, ino0, 1);
|
expect_lookup(RELPATH0, ino0, 1);
|
||||||
expect_open(ino0, 0, 1);
|
expect_open(ino0, 0, 1);
|
||||||
expect_getattr(ino0, 0);
|
|
||||||
/* On the 2nd close, FUSE_FLUSH won't be sent at all */
|
/* On the 2nd close, FUSE_FLUSH won't be sent at all */
|
||||||
expect_flush(ino0, 1, 0, ReturnErrno(ENOSYS));
|
expect_flush(ino0, 1, 0, ReturnErrno(ENOSYS));
|
||||||
expect_release();
|
expect_release();
|
||||||
|
|
||||||
expect_lookup(RELPATH1, ino1, 1);
|
expect_lookup(RELPATH1, ino1, 1);
|
||||||
expect_open(ino1, 0, 1);
|
expect_open(ino1, 0, 1);
|
||||||
expect_getattr(ino1, 0);
|
|
||||||
/* On the 2nd close, FUSE_FLUSH won't be sent at all */
|
/* On the 2nd close, FUSE_FLUSH won't be sent at all */
|
||||||
expect_release();
|
expect_release();
|
||||||
|
|
||||||
@ -184,7 +180,6 @@ TEST_F(Flush, flush)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 1, 0, ReturnErrno(0));
|
expect_flush(ino, 1, 0, ReturnErrno(0));
|
||||||
expect_release();
|
expect_release();
|
||||||
|
|
||||||
@ -210,7 +205,6 @@ TEST_F(FlushWithLocks, DISABLED_unlock_on_close)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_SETLK &&
|
return (in->header.opcode == FUSE_SETLK &&
|
||||||
|
@ -93,7 +93,6 @@ TEST_F(Fsync, aio_fsync)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, bufsize, CONTENTS);
|
expect_write(ino, bufsize, CONTENTS);
|
||||||
expect_fsync(ino, 0, 0);
|
expect_fsync(ino, 0, 0);
|
||||||
|
|
||||||
@ -127,7 +126,6 @@ TEST_F(Fsync, close)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, bufsize, CONTENTS);
|
expect_write(ino, bufsize, CONTENTS);
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
@ -164,7 +162,6 @@ TEST_F(Fsync, eio)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, bufsize, CONTENTS);
|
expect_write(ino, bufsize, CONTENTS);
|
||||||
expect_fsync(ino, FUSE_FSYNC_FDATASYNC, EIO);
|
expect_fsync(ino, FUSE_FSYNC_FDATASYNC, EIO);
|
||||||
|
|
||||||
@ -194,7 +191,6 @@ TEST_F(Fsync, DISABLED_enosys)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, bufsize, CONTENTS);
|
expect_write(ino, bufsize, CONTENTS);
|
||||||
expect_fsync(ino, FUSE_FSYNC_FDATASYNC, ENOSYS);
|
expect_fsync(ino, FUSE_FSYNC_FDATASYNC, ENOSYS);
|
||||||
|
|
||||||
@ -220,7 +216,6 @@ TEST_F(Fsync, fdatasync)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, bufsize, CONTENTS);
|
expect_write(ino, bufsize, CONTENTS);
|
||||||
expect_fsync(ino, FUSE_FSYNC_FDATASYNC, 0);
|
expect_fsync(ino, FUSE_FSYNC_FDATASYNC, 0);
|
||||||
|
|
||||||
@ -243,7 +238,6 @@ TEST_F(Fsync, fsync)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, bufsize, CONTENTS);
|
expect_write(ino, bufsize, CONTENTS);
|
||||||
expect_fsync(ino, 0, 0);
|
expect_fsync(ino, 0, 0);
|
||||||
|
|
||||||
|
@ -33,14 +33,32 @@
|
|||||||
|
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
|
|
||||||
class Getattr : public FuseTest {};
|
class Getattr : public FuseTest {
|
||||||
|
public:
|
||||||
|
void expect_lookup(const char *relpath, uint64_t ino, mode_t mode,
|
||||||
|
uint64_t size, int times, uint64_t attr_valid, uint32_t attr_valid_nsec)
|
||||||
|
{
|
||||||
|
EXPECT_LOOKUP(1, relpath)
|
||||||
|
.Times(times)
|
||||||
|
.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 = attr_valid;
|
||||||
|
out->body.entry.attr_valid_nsec = attr_valid_nsec;
|
||||||
|
out->body.entry.attr.size = size;
|
||||||
|
out->body.entry.entry_valid = UINT64_MAX;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If getattr returns a non-zero cache timeout, then subsequent VOP_GETATTRs
|
* If getattr returns a non-zero cache timeout, then subsequent VOP_GETATTRs
|
||||||
* should use the cached attributes, rather than query the daemon
|
* should use the cached attributes, rather than query the daemon
|
||||||
*/
|
*/
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */
|
TEST_F(Getattr, attr_cache)
|
||||||
TEST_F(Getattr, DISABLED_attr_cache)
|
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
@ -52,6 +70,7 @@ TEST_F(Getattr, DISABLED_attr_cache)
|
|||||||
SET_OUT_HEADER_LEN(out, entry);
|
SET_OUT_HEADER_LEN(out, entry);
|
||||||
out->body.entry.attr.mode = S_IFREG | 0644;
|
out->body.entry.attr.mode = S_IFREG | 0644;
|
||||||
out->body.entry.nodeid = ino;
|
out->body.entry.nodeid = ino;
|
||||||
|
out->body.entry.entry_valid = UINT64_MAX;
|
||||||
})));
|
})));
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([](auto in) {
|
ResultOf([](auto in) {
|
||||||
@ -76,7 +95,7 @@ TEST_F(Getattr, DISABLED_attr_cache)
|
|||||||
* period passes.
|
* period passes.
|
||||||
*/
|
*/
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */
|
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */
|
||||||
TEST_F(Getattr, attr_cache_timeout)
|
TEST_F(Getattr, DISABLED_attr_cache_timeout)
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
@ -88,7 +107,7 @@ TEST_F(Getattr, attr_cache_timeout)
|
|||||||
*/
|
*/
|
||||||
long timeout_ns = 250'000'000;
|
long timeout_ns = 250'000'000;
|
||||||
|
|
||||||
expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
|
expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2, 0, 0);
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([](auto in) {
|
ResultOf([](auto in) {
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
return (in->header.opcode == FUSE_GETATTR &&
|
||||||
@ -116,7 +135,7 @@ TEST_F(Getattr, enoent)
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
const uint64_t ino = 42;
|
const uint64_t ino = 42;
|
||||||
|
|
||||||
expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
|
expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1, 0, 0);
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([](auto in) {
|
ResultOf([](auto in) {
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
return (in->header.opcode == FUSE_GETATTR &&
|
||||||
@ -135,7 +154,7 @@ TEST_F(Getattr, ok)
|
|||||||
const uint64_t ino = 42;
|
const uint64_t ino = 42;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
expect_lookup(RELPATH, ino, S_IFREG | 0644, 1, 1);
|
expect_lookup(RELPATH, ino, S_IFREG | 0644, 1, 1, 0, 0);
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([](auto in) {
|
ResultOf([](auto in) {
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
return (in->header.opcode == FUSE_GETATTR &&
|
||||||
|
@ -80,7 +80,6 @@ TEST_F(GetlkFallback, local)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
ASSERT_LE(0, fd) << strerror(errno);
|
ASSERT_LE(0, fd) << strerror(errno);
|
||||||
@ -110,7 +109,6 @@ TEST_F(Getlk, DISABLED_no_locks)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_GETLK &&
|
return (in->header.opcode == FUSE_GETLK &&
|
||||||
@ -156,7 +154,6 @@ TEST_F(Getlk, DISABLED_lock_exists)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_GETLK &&
|
return (in->header.opcode == FUSE_GETLK &&
|
||||||
@ -209,7 +206,6 @@ TEST_F(SetlkFallback, local)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
ASSERT_LE(0, fd) << strerror(errno);
|
ASSERT_LE(0, fd) << strerror(errno);
|
||||||
@ -236,7 +232,6 @@ TEST_F(Setlk, DISABLED_set)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_SETLK &&
|
return (in->header.opcode == FUSE_SETLK &&
|
||||||
@ -279,7 +274,6 @@ TEST_F(Setlk, DISABLED_set_eof)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_SETLK &&
|
return (in->header.opcode == FUSE_SETLK &&
|
||||||
@ -322,7 +316,6 @@ TEST_F(Setlk, DISABLED_eagain)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_SETLK &&
|
return (in->header.opcode == FUSE_SETLK &&
|
||||||
@ -364,7 +357,6 @@ TEST_F(SetlkwFallback, local)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
ASSERT_LE(0, fd) << strerror(errno);
|
ASSERT_LE(0, fd) << strerror(errno);
|
||||||
@ -395,7 +387,6 @@ TEST_F(Setlkw, DISABLED_set)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino);
|
expect_lookup(RELPATH, ino);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_SETLK &&
|
return (in->header.opcode == FUSE_SETLK &&
|
||||||
|
@ -43,8 +43,7 @@ class Lookup: public FuseTest {};
|
|||||||
* If lookup returns a non-zero cache timeout, then subsequent VOP_GETATTRs
|
* If lookup returns a non-zero cache timeout, then subsequent VOP_GETATTRs
|
||||||
* should use the cached attributes, rather than query the daemon
|
* should use the cached attributes, rather than query the daemon
|
||||||
*/
|
*/
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */
|
TEST_F(Lookup, attr_cache)
|
||||||
TEST_F(Lookup, DISABLED_attr_cache)
|
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
@ -106,7 +105,7 @@ TEST_F(Lookup, DISABLED_attr_cache)
|
|||||||
* the cached attributes and requery the daemon.
|
* the cached attributes and requery the daemon.
|
||||||
*/
|
*/
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */
|
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235773 */
|
||||||
TEST_F(Lookup, attr_cache_timeout)
|
TEST_F(Lookup, DISABLED_attr_cache_timeout)
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
|
@ -61,9 +61,6 @@ void test_ok(int os_flags, int fuse_flags) {
|
|||||||
SET_OUT_HEADER_LEN(out, open);
|
SET_OUT_HEADER_LEN(out, open);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, os_flags);
|
fd = open(FULLPATH, os_flags);
|
||||||
EXPECT_LE(0, fd) << strerror(errno);
|
EXPECT_LE(0, fd) << strerror(errno);
|
||||||
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
/* Deliberately leak fd. close(2) will be tested in release.cc */
|
||||||
@ -204,7 +201,6 @@ TEST_F(Open, multiple_creds)
|
|||||||
out->header.len = sizeof(out->header);
|
out->header.len = sizeof(out->header);
|
||||||
SET_OUT_HEADER_LEN(out, open);
|
SET_OUT_HEADER_LEN(out, open);
|
||||||
})));
|
})));
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 2, ReturnErrno(0));
|
expect_flush(ino, 2, ReturnErrno(0));
|
||||||
expect_release(ino, fh0);
|
expect_release(ino, fh0);
|
||||||
expect_release(ino, fh1);
|
expect_release(ino, fh1);
|
||||||
|
@ -117,7 +117,6 @@ TEST_F(AioRead, aio_read)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
@ -152,7 +151,6 @@ TEST_F(AioRead, async_read_disabled)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_READ &&
|
return (in->header.opcode == FUSE_READ &&
|
||||||
@ -230,7 +228,6 @@ TEST_F(AsyncRead, DISABLED_async_read)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_READ &&
|
return (in->header.opcode == FUSE_READ &&
|
||||||
@ -299,7 +296,6 @@ TEST_F(Read, direct_io_read_nothing)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, offset + 1000);
|
expect_lookup(RELPATH, ino, offset + 1000);
|
||||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||||
expect_getattr(ino, offset + 1000);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
ASSERT_LE(0, fd) << strerror(errno);
|
ASSERT_LE(0, fd) << strerror(errno);
|
||||||
@ -325,7 +321,6 @@ TEST_F(Read, direct_io_pread)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, offset + bufsize);
|
expect_lookup(RELPATH, ino, offset + bufsize);
|
||||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||||
expect_getattr(ino, offset + bufsize);
|
|
||||||
expect_read(ino, offset, bufsize, bufsize, CONTENTS);
|
expect_read(ino, offset, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
@ -354,7 +349,6 @@ TEST_F(Read, direct_io_short_read)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, offset + bufsize);
|
expect_lookup(RELPATH, ino, offset + bufsize);
|
||||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||||
expect_getattr(ino, offset + bufsize);
|
|
||||||
expect_read(ino, offset, bufsize, halfbufsize, CONTENTS);
|
expect_read(ino, offset, bufsize, halfbufsize, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
@ -378,7 +372,6 @@ TEST_F(Read, eio)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_READ);
|
return (in->header.opcode == FUSE_READ);
|
||||||
@ -410,7 +403,6 @@ TEST_F(Read, keep_cache)
|
|||||||
|
|
||||||
FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2);
|
FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2);
|
||||||
expect_open(ino, FOPEN_KEEP_CACHE, 2);
|
expect_open(ino, FOPEN_KEEP_CACHE, 2);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd0 = open(FULLPATH, O_RDONLY);
|
fd0 = open(FULLPATH, O_RDONLY);
|
||||||
@ -445,7 +437,6 @@ TEST_F(Read, keep_cache_disabled)
|
|||||||
|
|
||||||
FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2);
|
FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2);
|
||||||
expect_open(ino, 0, 2);
|
expect_open(ino, 0, 2);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd0 = open(FULLPATH, O_RDONLY);
|
fd0 = open(FULLPATH, O_RDONLY);
|
||||||
@ -482,7 +473,6 @@ TEST_F(ReadCacheable, mmap)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
/* mmap may legitimately try to read more data than is available */
|
/* mmap may legitimately try to read more data than is available */
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
@ -526,7 +516,6 @@ TEST_F(Read, o_direct)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
@ -563,7 +552,6 @@ TEST_F(Read, pread)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, offset + bufsize);
|
expect_lookup(RELPATH, ino, offset + bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, offset + bufsize);
|
|
||||||
expect_read(ino, offset, bufsize, bufsize, CONTENTS);
|
expect_read(ino, offset, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
@ -586,7 +574,6 @@ TEST_F(Read, read)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDONLY);
|
fd = open(FULLPATH, O_RDONLY);
|
||||||
@ -620,7 +607,6 @@ TEST_F(ReadCacheable, default_readahead)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, filesize);
|
expect_lookup(RELPATH, ino, filesize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, filesize);
|
|
||||||
expect_read(ino, 0, default_maxreadahead, default_maxreadahead,
|
expect_read(ino, 0, default_maxreadahead, default_maxreadahead,
|
||||||
contents);
|
contents);
|
||||||
|
|
||||||
@ -651,7 +637,6 @@ TEST_F(ReadCacheable, sendfile)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
/* Like mmap, sendfile may request more data than is available */
|
/* Like mmap, sendfile may request more data than is available */
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
@ -697,7 +682,6 @@ TEST_F(ReadCacheable, DISABLED_sendfile_eio)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_READ);
|
return (in->header.opcode == FUSE_READ);
|
||||||
@ -739,7 +723,6 @@ TEST_P(ReadAhead, DISABLED_readahead) {
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, filesize);
|
expect_lookup(RELPATH, ino, filesize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, filesize);
|
|
||||||
/* fuse(4) should only read ahead the allowed amount */
|
/* fuse(4) should only read ahead the allowed amount */
|
||||||
expect_read(ino, 0, GetParam(), GetParam(), contents);
|
expect_read(ino, 0, GetParam(), GetParam(), contents);
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ TEST_F(Release, dup)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 1, ReturnErrno(0));
|
expect_flush(ino, 1, ReturnErrno(0));
|
||||||
expect_release(ino, 0, O_RDONLY, 0);
|
expect_release(ino, 0, O_RDONLY, 0);
|
||||||
|
|
||||||
@ -111,7 +110,6 @@ TEST_F(Release, eio)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 1, ReturnErrno(0));
|
expect_flush(ino, 1, ReturnErrno(0));
|
||||||
expect_release(ino, 0, O_WRONLY, EIO);
|
expect_release(ino, 0, O_WRONLY, EIO);
|
||||||
|
|
||||||
@ -134,7 +132,6 @@ TEST_F(Release, DISABLED_flags)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 1, ReturnErrno(0));
|
expect_flush(ino, 1, ReturnErrno(0));
|
||||||
expect_release(ino, 0, O_RDWR | O_APPEND, 0);
|
expect_release(ino, 0, O_RDWR | O_APPEND, 0);
|
||||||
|
|
||||||
@ -158,7 +155,6 @@ TEST_F(Release, multiple_opens)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 2);
|
expect_lookup(RELPATH, ino, 2);
|
||||||
expect_open(ino, 0, 2);
|
expect_open(ino, 0, 2);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 2, ReturnErrno(0));
|
expect_flush(ino, 2, ReturnErrno(0));
|
||||||
expect_release(ino, 0, O_RDONLY, 0);
|
expect_release(ino, 0, O_RDONLY, 0);
|
||||||
|
|
||||||
@ -182,7 +178,6 @@ TEST_F(Release, ok)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_flush(ino, 1, ReturnErrno(0));
|
expect_flush(ino, 1, ReturnErrno(0));
|
||||||
expect_release(ino, 0, O_RDONLY, 0);
|
expect_release(ino, 0, O_RDONLY, 0);
|
||||||
|
|
||||||
@ -205,7 +200,6 @@ TEST_F(ReleaseWithLocks, DISABLED_unlock_on_close)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 1);
|
expect_lookup(RELPATH, ino, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_SETLK &&
|
return (in->header.opcode == FUSE_SETLK &&
|
||||||
|
@ -46,8 +46,7 @@ class Setattr : public FuseTest {};
|
|||||||
* If setattr returns a non-zero cache timeout, then subsequent VOP_GETATTRs
|
* If setattr returns a non-zero cache timeout, then subsequent VOP_GETATTRs
|
||||||
* should use the cached attributes, rather than query the daemon
|
* should use the cached attributes, rather than query the daemon
|
||||||
*/
|
*/
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */
|
TEST_F(Setattr, attr_cache)
|
||||||
TEST_F(Setattr, DISABLED_attr_cache)
|
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
@ -60,11 +59,11 @@ TEST_F(Setattr, DISABLED_attr_cache)
|
|||||||
SET_OUT_HEADER_LEN(out, entry);
|
SET_OUT_HEADER_LEN(out, entry);
|
||||||
out->body.entry.attr.mode = S_IFREG | 0644;
|
out->body.entry.attr.mode = S_IFREG | 0644;
|
||||||
out->body.entry.nodeid = ino;
|
out->body.entry.nodeid = ino;
|
||||||
|
out->body.entry.entry_valid = UINT64_MAX;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([](auto in) {
|
ResultOf([](auto in) {
|
||||||
/* In protocol 7.23, ctime will be changed too */
|
|
||||||
return (in->header.opcode == FUSE_SETATTR &&
|
return (in->header.opcode == FUSE_SETATTR &&
|
||||||
in->header.nodeid == ino);
|
in->header.nodeid == ino);
|
||||||
}, Eq(true)),
|
}, Eq(true)),
|
||||||
@ -73,6 +72,7 @@ TEST_F(Setattr, DISABLED_attr_cache)
|
|||||||
SET_OUT_HEADER_LEN(out, attr);
|
SET_OUT_HEADER_LEN(out, attr);
|
||||||
out->body.attr.attr.ino = ino; // Must match nodeid
|
out->body.attr.attr.ino = ino; // Must match nodeid
|
||||||
out->body.attr.attr.mode = S_IFREG | newmode;
|
out->body.attr.attr.mode = S_IFREG | newmode;
|
||||||
|
out->body.attr.attr_valid = UINT64_MAX;
|
||||||
})));
|
})));
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([](auto in) {
|
ResultOf([](auto in) {
|
||||||
@ -227,19 +227,6 @@ TEST_F(Setattr, fchmod)
|
|||||||
SET_OUT_HEADER_LEN(out, open);
|
SET_OUT_HEADER_LEN(out, open);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | oldmode;
|
|
||||||
})));
|
|
||||||
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
/* In protocol 7.23, ctime will be changed too */
|
/* In protocol 7.23, ctime will be changed too */
|
||||||
@ -294,20 +281,6 @@ TEST_F(Setattr, ftruncate)
|
|||||||
out->body.open.fh = fh;
|
out->body.open.fh = fh;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).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.mode = S_IFREG | 0755;
|
|
||||||
out->body.attr.attr.size = oldsize;
|
|
||||||
})));
|
|
||||||
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
/* In protocol 7.23, ctime will be changed too */
|
/* In protocol 7.23, ctime will be changed too */
|
||||||
@ -502,26 +475,6 @@ TEST_F(Setattr, utimensat) {
|
|||||||
out->body.entry.attr.mtimensec = oldtimes[1].tv_nsec;
|
out->body.entry.attr.mtimensec = oldtimes[1].tv_nsec;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/*
|
|
||||||
* Until bug 235775 is fixed, utimensat will make an extra FUSE_GETATTR
|
|
||||||
* call
|
|
||||||
*/
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
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 | 0644;
|
|
||||||
out->body.attr.attr.atime = oldtimes[0].tv_sec;
|
|
||||||
out->body.attr.attr.atimensec = oldtimes[0].tv_nsec;
|
|
||||||
out->body.attr.attr.mtime = oldtimes[1].tv_sec;
|
|
||||||
out->body.attr.attr.mtimensec = oldtimes[1].tv_nsec;
|
|
||||||
})));
|
|
||||||
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
/* In protocol 7.23, ctime will be changed too */
|
/* In protocol 7.23, ctime will be changed too */
|
||||||
@ -576,26 +529,6 @@ TEST_F(Setattr, utimensat_mtime_only) {
|
|||||||
out->body.entry.attr.mtimensec = oldtimes[1].tv_nsec;
|
out->body.entry.attr.mtimensec = oldtimes[1].tv_nsec;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/*
|
|
||||||
* Until bug 235775 is fixed, utimensat will make an extra FUSE_GETATTR
|
|
||||||
* call
|
|
||||||
*/
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
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 | 0644;
|
|
||||||
out->body.attr.attr.atime = oldtimes[0].tv_sec;
|
|
||||||
out->body.attr.attr.atimensec = oldtimes[0].tv_nsec;
|
|
||||||
out->body.attr.attr.mtime = oldtimes[1].tv_sec;
|
|
||||||
out->body.attr.attr.mtimensec = oldtimes[1].tv_nsec;
|
|
||||||
})));
|
|
||||||
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
/* In protocol 7.23, ctime will be changed too */
|
/* In protocol 7.23, ctime will be changed too */
|
||||||
|
@ -92,7 +92,6 @@ TEST_F(Unlink, open_but_deleted)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 2);
|
expect_lookup(RELPATH, ino, 2);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_unlink(1, RELPATH, 0);
|
expect_unlink(1, RELPATH, 0);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
|
@ -144,14 +144,13 @@ FuseTest::expect_flush(uint64_t ino, int times, ProcessMockerT r)
|
|||||||
|
|
||||||
void FuseTest::expect_getattr(uint64_t ino, uint64_t size)
|
void FuseTest::expect_getattr(uint64_t ino, uint64_t size)
|
||||||
{
|
{
|
||||||
/* Until the attr cache is working, we may send an additional GETATTR */
|
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
return (in->header.opcode == FUSE_GETATTR &&
|
||||||
in->header.nodeid == ino);
|
in->header.nodeid == ino);
|
||||||
}, Eq(true)),
|
}, Eq(true)),
|
||||||
_)
|
_)
|
||||||
).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) {
|
).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto out) {
|
||||||
SET_OUT_HEADER_LEN(out, attr);
|
SET_OUT_HEADER_LEN(out, attr);
|
||||||
out->body.attr.attr.ino = ino; // Must match nodeid
|
out->body.attr.attr.ino = ino; // Must match nodeid
|
||||||
out->body.attr.attr.mode = S_IFREG | 0644;
|
out->body.attr.attr.mode = S_IFREG | 0644;
|
||||||
|
@ -153,7 +153,6 @@ TEST_F(AioWrite, DISABLED_aio_write)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY);
|
fd = open(FULLPATH, O_WRONLY);
|
||||||
@ -197,7 +196,6 @@ TEST_F(Write, append)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, initial_offset);
|
expect_lookup(RELPATH, ino, initial_offset);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, initial_offset);
|
|
||||||
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS);
|
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS);
|
||||||
|
|
||||||
/* Must open O_RDWR or fuse(4) implicitly sets direct_io */
|
/* Must open O_RDWR or fuse(4) implicitly sets direct_io */
|
||||||
@ -220,7 +218,6 @@ TEST_F(Write, append_direct_io)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, initial_offset);
|
expect_lookup(RELPATH, ino, initial_offset);
|
||||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||||
expect_getattr(ino, initial_offset);
|
|
||||||
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS);
|
expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY | O_APPEND);
|
fd = open(FULLPATH, O_WRONLY | O_APPEND);
|
||||||
@ -245,7 +242,6 @@ TEST_F(Write, DISABLED_direct_io_evicts_cache)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, bufsize);
|
expect_lookup(RELPATH, ino, bufsize);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, bufsize);
|
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS0);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS0);
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS1);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS1);
|
||||||
|
|
||||||
@ -290,7 +286,6 @@ TEST_F(Write, indirect_io_short_write)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, bufsize0, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize0, 0, CONTENTS);
|
||||||
expect_write(ino, bufsize0, bufsize1, bufsize1, 0,
|
expect_write(ino, bufsize0, bufsize1, bufsize1, 0,
|
||||||
contents1);
|
contents1);
|
||||||
@ -318,7 +313,6 @@ TEST_F(Write, direct_io_short_write)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, halfbufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, halfbufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY);
|
fd = open(FULLPATH, O_WRONLY);
|
||||||
@ -349,7 +343,6 @@ TEST_F(Write, direct_io_short_write_iov)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
expect_open(ino, FOPEN_DIRECT_IO, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, totalsize, size0, 0, EXPECTED0);
|
expect_write(ino, 0, totalsize, size0, 0, EXPECTED0);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY);
|
fd = open(FULLPATH, O_WRONLY);
|
||||||
@ -392,7 +385,6 @@ TEST_F(Write, DISABLED_mmap)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, len);
|
expect_lookup(RELPATH, ino, len);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, len);
|
|
||||||
expect_read(ino, 0, len, len, zeros);
|
expect_read(ino, 0, len, len, zeros);
|
||||||
/*
|
/*
|
||||||
* Writes from the pager may or may not be associated with the correct
|
* Writes from the pager may or may not be associated with the correct
|
||||||
@ -429,7 +421,6 @@ TEST_F(WriteThrough, pwrite)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY);
|
fd = open(FULLPATH, O_WRONLY);
|
||||||
@ -451,7 +442,6 @@ TEST_F(Write, write)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY);
|
fd = open(FULLPATH, O_WRONLY);
|
||||||
@ -481,7 +471,6 @@ TEST_F(Write, write_large)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, halfbufsize, halfbufsize, 0, contents);
|
expect_write(ino, 0, halfbufsize, halfbufsize, 0, contents);
|
||||||
expect_write(ino, halfbufsize, halfbufsize, halfbufsize, 0,
|
expect_write(ino, halfbufsize, halfbufsize, halfbufsize, 0,
|
||||||
&contents[halfbufsize / sizeof(int)]);
|
&contents[halfbufsize / sizeof(int)]);
|
||||||
@ -506,7 +495,6 @@ TEST_F(Write, write_nothing)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
|
|
||||||
fd = open(FULLPATH, O_WRONLY);
|
fd = open(FULLPATH, O_WRONLY);
|
||||||
EXPECT_LE(0, fd) << strerror(errno);
|
EXPECT_LE(0, fd) << strerror(errno);
|
||||||
@ -527,7 +515,6 @@ TEST_F(WriteBack, close)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||||
EXPECT_CALL(*m_mock, process(
|
EXPECT_CALL(*m_mock, process(
|
||||||
ResultOf([=](auto in) {
|
ResultOf([=](auto in) {
|
||||||
@ -564,9 +551,8 @@ TEST_F(WriteBack, rmw)
|
|||||||
int fd;
|
int fd;
|
||||||
ssize_t bufsize = strlen(CONTENTS);
|
ssize_t bufsize = strlen(CONTENTS);
|
||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, fsize, 1);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, fsize);
|
|
||||||
expect_read(ino, 0, fsize, fsize, INITIAL);
|
expect_read(ino, 0, fsize, fsize, INITIAL);
|
||||||
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
@ -593,7 +579,6 @@ TEST_F(WriteBack, writeback)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
@ -626,7 +611,6 @@ TEST_F(WriteBack, o_direct)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
expect_read(ino, 0, bufsize, bufsize, CONTENTS);
|
||||||
|
|
||||||
@ -660,7 +644,6 @@ TEST_F(WriteThrough, DISABLED_writethrough)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
expect_getattr(ino, 0);
|
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
@ -676,8 +659,7 @@ TEST_F(WriteThrough, DISABLED_writethrough)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* With writethrough caching, writes update the cached file size */
|
/* With writethrough caching, writes update the cached file size */
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235775 */
|
TEST_F(WriteThrough, update_file_size)
|
||||||
TEST_F(WriteThrough, DISABLED_update_file_size)
|
|
||||||
{
|
{
|
||||||
const char FULLPATH[] = "mountpoint/some_file.txt";
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
const char RELPATH[] = "some_file.txt";
|
const char RELPATH[] = "some_file.txt";
|
||||||
@ -689,20 +671,6 @@ TEST_F(WriteThrough, DISABLED_update_file_size)
|
|||||||
|
|
||||||
expect_lookup(RELPATH, ino, 0);
|
expect_lookup(RELPATH, ino, 0);
|
||||||
expect_open(ino, 0, 1);
|
expect_open(ino, 0, 1);
|
||||||
EXPECT_CALL(*m_mock, process(
|
|
||||||
ResultOf([=](auto in) {
|
|
||||||
return (in->header.opcode == FUSE_GETATTR &&
|
|
||||||
in->header.nodeid == ino);
|
|
||||||
}, Eq(true)),
|
|
||||||
_)
|
|
||||||
).Times(2)
|
|
||||||
.WillRepeatedly(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 | 0644;
|
|
||||||
out->body.attr.attr.size = 0;
|
|
||||||
out->body.attr.attr_valid = UINT64_MAX;
|
|
||||||
})));
|
|
||||||
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS);
|
||||||
|
|
||||||
fd = open(FULLPATH, O_RDWR);
|
fd = open(FULLPATH, O_RDWR);
|
||||||
|
Loading…
Reference in New Issue
Block a user