tmpfs: Update mtime/ctime on open(O_TRUNC) for zero-length files#12771
tmpfs: Update mtime/ctime on open(O_TRUNC) for zero-length files#12771tanyifeng wants to merge 1 commit intogoogle:masterfrom
Conversation
f65bb8b to e82ab6c Compare Currently, tmpfs truncate only updates mtime/ctime when the file size actually changes. This causes open(O_TRUNC) on an already-empty file to skip the timestamp update, breaking applications like khal that rely on open('w').close() to advance mtime. Fix this by unconditionally updating mtime/ctime on every truncate call. Rename truncateLocked() to truncateNoTimeUpdateLocked() and move timestamp updates into its callers. This is slightly more aggressive than Linux tmpfs for the truncate(2) same-size case (Linux tmpfs skips, ext4 updates), but simplifies the implementation Signed-off-by: Tan Yifeng <yiftan@tencent.com> e82ab6c to d5da431 Compare | Thanks, the current changes look good! I think we'd need to make the same fix in fsimpl/gofer because we run the same syscall tests against gofer and tmpfs so that new test will fail when we try to submit it. |
d5da431 to ec4efec Compare
I've applied the same fix to |
| Actually I was mistaken above when I said that fsimpl/gofer is also impacted. When I was experiementing, the container was running with default overlayfs setting. So the rootfs was actually an overlayfs, so I was observing tmpfs behavior on rootfs. In reality, the fsimpl/gofer filesystem is not impacted. Here is the fixed-up incompatibility table:
So if you could just revert your changes in fsimpl/gofer, then this PR looks good to me. Sorry for the back-and-forth. |
There was a problem hiding this comment.
Thanks for the verification, I reverted the changes in fsimpl/gofer.
ec4efec to d5da431 Compare
Linux unconditionally updates mtime and ctime when handling O_TRUNC via handle_truncate() -> do_truncate() with ATTR_MTIME|ATTR_CTIME, regardless of whether the file size actually changes.
gVisor's tmpfs truncateLocked() returns early when newSize == oldSize, skipping the timestamp update. This causes programs that rely on mtime changes (e.g. file sync tools, make) to malfunction when repeatedly truncating an already-empty file.
Fix by calling d.inode.touchCMtime() after truncate(0) in the O_TRUNC path of dentry.open(), ensuring timestamps are always updated consistent with Linux behavior.