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:
@@ -66,3 +66,33 @@ function to_bytes
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# Verify $a is equal to $b, otherwise raise an error specifying
|
||||
# the $type of values being compared
|
||||
#
|
||||
function verify_eq # <a> <b> <type>
|
||||
{
|
||||
typeset a=$1
|
||||
typeset b=$2
|
||||
typeset type=$3
|
||||
|
||||
if [[ $a -ne $b ]]; then
|
||||
log_fail "Compared $type should be equal: $a != $b"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Verify $a is not equal to $b, otherwise raise an error specifying
|
||||
# the $type of values being compared
|
||||
#
|
||||
function verify_ne # <a> <b> <type>
|
||||
{
|
||||
typeset a=$1
|
||||
typeset b=$2
|
||||
typeset type=$3
|
||||
|
||||
if [[ $a -eq $b ]]; then
|
||||
log_fail "Compared $type should be not equal: $a == $b"
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user