From f0b86a150f26161911b7311f9d3b9a5eeae25a93 Mon Sep 17 00:00:00 2001 From: asomers Date: Wed, 26 Jun 2019 00:03:37 +0000 Subject: [PATCH] fusefs: set ctime during FUSE_SETATTR following a write As of r349396 the kernel will internally update the mtime and ctime of files on write. It will also flush the mtime should a SETATTR happen before the data cache gets flushed. Now it will flush the ctime too, if the server is using protocol 7.23 or higher. This is the only case in which the kernel will explicitly set a file's ctime, since neither utimensat(2) nor any other user interfaces allow it. Sponsored by: The FreeBSD Foundation --- sys/fs/fuse/fuse_internal.c | 5 +++++ tests/sys/fs/fusefs/write.cc | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c index 933bc7aa65c..5df6e18444c 100644 --- a/sys/fs/fuse/fuse_internal.c +++ b/sys/fs/fuse/fuse_internal.c @@ -1074,6 +1074,11 @@ int fuse_internal_setattr(struct vnode *vp, struct vattr *vap, fsai->mtimensec = fvdat->cached_attrs.va_mtime.tv_nsec; fsai->valid |= FATTR_MTIME; } + if (fuse_libabi_geq(data, 7, 23) && fvdat->flag & FN_CTIMECHANGE) { + fsai->ctime = fvdat->cached_attrs.va_ctime.tv_sec; + fsai->ctimensec = fvdat->cached_attrs.va_ctime.tv_nsec; + fsai->valid |= FATTR_CTIME; + } if (vap->va_mode != (mode_t)VNOVAL) { fsai->mode = vap->va_mode & ALLPERMS; fsai->valid |= FATTR_MODE; diff --git a/tests/sys/fs/fusefs/write.cc b/tests/sys/fs/fusefs/write.cc index 3dd6e1cf399..147027d1b0a 100644 --- a/tests/sys/fs/fusefs/write.cc +++ b/tests/sys/fs/fusefs/write.cc @@ -1117,8 +1117,7 @@ TEST_F(WriteBackAsync, timestamps_during_setattr) expect_open(ino, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - /* In protocol 7.23, ctime will be changed too */ - uint32_t valid = FATTR_MODE | FATTR_MTIME; + uint32_t valid = FATTR_MODE | FATTR_MTIME | FATTR_CTIME; return (in.header.opcode == FUSE_SETATTR && in.header.nodeid == ino && in.body.setattr.valid == valid); -- 2.45.0