From fe221e0177ca1d3013f7a1a45964d30377d706a9 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Thu, 16 May 2019 23:17:39 +0000 Subject: [PATCH] fusefs: forward UTIME_NOW to the server If a user sets both atime and mtime to UTIME_NOW when calling a syscall like utimensat(2), allow the server to choose what "now" means. Due to the design of FreeBSD's VFS, it's not possible to do this for just one of atime or mtime; it's all or none. PR: 237181 Sponsored by: The FreeBSD Foundation --- sys/fs/fuse/fuse_internal.c | 4 ++++ tests/sys/fs/fusefs/setattr.cc | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c index b82b23aafae5..2e1c14319bc0 100644 --- a/sys/fs/fuse/fuse_internal.c +++ b/sys/fs/fuse/fuse_internal.c @@ -834,11 +834,15 @@ int fuse_internal_setattr(struct vnode *vp, struct vattr *vap, fsai->atime = vap->va_atime.tv_sec; fsai->atimensec = vap->va_atime.tv_nsec; fsai->valid |= FATTR_ATIME; + if (vap->va_vaflags & VA_UTIMES_NULL) + fsai->valid |= FATTR_ATIME_NOW; } if (vap->va_mtime.tv_sec != VNOVAL) { fsai->mtime = vap->va_mtime.tv_sec; fsai->mtimensec = vap->va_mtime.tv_nsec; fsai->valid |= FATTR_MTIME; + if (vap->va_vaflags & VA_UTIMES_NULL) + fsai->valid |= FATTR_MTIME_NOW; } if (vap->va_mode != (mode_t)VNOVAL) { fsai->mode = vap->va_mode & ALLPERMS; diff --git a/tests/sys/fs/fusefs/setattr.cc b/tests/sys/fs/fusefs/setattr.cc index 4cb5606f5edf..55d227f7006a 100644 --- a/tests/sys/fs/fusefs/setattr.cc +++ b/tests/sys/fs/fusefs/setattr.cc @@ -661,9 +661,12 @@ TEST_F(Setattr, utimensat_mtime_only) { << strerror(errno); } -/* Set a file's mtime and atime to now */ -/* TODO: enable this test after updating protocol to version 7.9 */ -#if 0 +/* + * Set a file's mtime and atime to now + * + * The design of FreeBSD's VFS does not allow fusefs to set just one of atime + * or mtime to UTIME_NOW; it's both or neither. + */ TEST_F(Setattr, utimensat_utime_now) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -689,6 +692,7 @@ TEST_F(Setattr, utimensat_utime_now) { out->body.entry.attr.mode = S_IFREG | 0644; out->body.entry.nodeid = ino; out->body.entry.attr_valid = UINT64_MAX; + out->body.entry.entry_valid = UINT64_MAX; out->body.entry.attr.atime = oldtimes[0].tv_sec; out->body.entry.attr.atimensec = oldtimes[0].tv_nsec; out->body.entry.attr.mtime = oldtimes[1].tv_sec; @@ -723,7 +727,6 @@ TEST_F(Setattr, utimensat_utime_now) { EXPECT_EQ(now[1].tv_sec, sb.st_mtim.tv_sec); EXPECT_EQ(now[1].tv_nsec, sb.st_mtim.tv_nsec); } -#endif /* On a read-only mount, no attributes may be changed */ TEST_F(RofsSetattr, erofs)