diff options
author | LOLi <[email protected]> | 2017-11-13 18:24:26 +0100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-11-13 09:24:26 -0800 |
commit | 99834d1950f654d08585b61a1b0b4458d3d9e100 (patch) | |
tree | 0469f2f351adefb974c5202c54a7bdc03d5e0e13 /module/zfs/zfs_vnops.c | |
parent | 13042a6ccdf3450a758511c4b64e800a371bb891 (diff) |
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 <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes #6811
Closes #6819
Diffstat (limited to 'module/zfs/zfs_vnops.c')
-rw-r--r-- | module/zfs/zfs_vnops.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 85dd4a049..703f6299f 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -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); |