summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2008-03-06 05:45:29 +0300
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-18 05:39:45 +0400
commit44d814ced4cffbfe6a775c5bb8b941a6e734e7d9 (patch)
tree94e0cecd2b18cf2b126b702b30a8a982de3931e0 /fs/xfs/xfs_vnodeops.c
parent24bd861d1c3fff5248de7ba3bdddb3369087ad46 (diff)
downloadlinux-44d814ced4cffbfe6a775c5bb8b941a6e734e7d9.tar.xz
[XFS] Update c/mtime correctly on truncates
XFS changes the c/mtime of an inode when truncating it to the same size. The c/mtime is only supposed to change if the size is changed. Not to be confused with ftruncate, where the c/mtime is supposed to be changed even if the size is not changed. The Linux VFS encodes this semantic difference in the flags it sends down to ->setattr, which XFS currently ignores. We need to make XFS pay attention to the VFS flags and hence Do The Right Thing. SGI-PV: 977547 SGI-Modid: xfs-linux-melb:xfs-kern:30536a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 811ee874d868..b77dede91b71 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -633,6 +633,15 @@ xfs_setattr(
* Truncate file. Must have write permission and not be a directory.
*/
if (mask & XFS_AT_SIZE) {
+ /*
+ * Only change the c/mtime if we are changing the size
+ * or we are explicitly asked to change it. This handles
+ * the semantic difference between truncate() and ftruncate()
+ * as implemented in the VFS.
+ */
+ if (vap->va_size != ip->i_size || (mask & XFS_AT_CTIME))
+ timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
+
if (vap->va_size > ip->i_size) {
xfs_igrow_finish(tp, ip, vap->va_size,
!(flags & ATTR_DMI));
@@ -661,10 +670,6 @@ xfs_setattr(
*/
xfs_iflags_set(ip, XFS_ITRUNCATED);
}
- /*
- * Have to do this even if the file's size doesn't change.
- */
- timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
}
/*