mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Fix truncate(2) mtime and ctime handling
On Linux, ftruncate(2) always changes the file timestamps, even if the file size is not changed. However, in case of a successfull truncate(2), the timestamps are updated only if the file size changes. This translates to the VFS calling the ZFS Posix Layer "setattr" function (zpl_setattr) with ATTR_MTIME and ATTR_CTIME unconditionally set on the iattr mask only when doing a ftruncate(2), while the truncate(2) is left to the filesystem implementation to be dealt with. This behaviour is consistent with POSIX:2004/SUSv3 specifications where there's no explicit requirement for file size changes to update the timestamps only for ftruncate(2): http://pubs.opengroup.org/onlinepubs/009695399/functions/truncate.html http://pubs.opengroup.org/onlinepubs/009695399/functions/ftruncate.html This has been later updated in POSIX:2008/SUSv4 where, for both truncate(2)/ftruncate(2), there's no mention of this size change requirement: http://austingroupbugs.net/view.php?id=489 http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html Unfortunately the Linux VFS is still calling into the ZPL without ATTR_MTIME/ATTR_CTIME set in the truncate(2) case: we fix this by explicitly updating the timestamps when detecting the ATTR_SIZE bit, which is always set in do_truncate(), on the iattr mask. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes #6811 Closes #6819
This commit is contained in:
@@ -3155,7 +3155,7 @@ top:
|
||||
&atime, sizeof (atime));
|
||||
}
|
||||
|
||||
if (mask & ATTR_MTIME) {
|
||||
if (mask & (ATTR_MTIME | ATTR_SIZE)) {
|
||||
ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
|
||||
ZTOI(zp)->i_mtime = timespec_trunc(vap->va_mtime,
|
||||
ZTOI(zp)->i_sb->s_time_gran);
|
||||
@@ -3164,7 +3164,7 @@ top:
|
||||
mtime, sizeof (mtime));
|
||||
}
|
||||
|
||||
if (mask & ATTR_CTIME) {
|
||||
if (mask & (ATTR_CTIME | ATTR_SIZE)) {
|
||||
ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
|
||||
ZTOI(zp)->i_ctime = timespec_trunc(vap->va_ctime,
|
||||
ZTOI(zp)->i_sb->s_time_gran);
|
||||
|
||||
Reference in New Issue
Block a user