diff options
author | David Chinner <dgc@sgi.com> | 2008-03-05 21:45:29 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-17 21:39:45 -0400 |
commit | 44d814ced4cffbfe6a775c5bb8b941a6e734e7d9 (patch) | |
tree | 94e0cecd2b18cf2b126b702b30a8a982de3931e0 /fs/xfs | |
parent | 24bd861d1c3fff5248de7ba3bdddb3369087ad46 (diff) |
[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')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 13 |
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( | |||
633 | * Truncate file. Must have write permission and not be a directory. | 633 | * Truncate file. Must have write permission and not be a directory. |
634 | */ | 634 | */ |
635 | if (mask & XFS_AT_SIZE) { | 635 | if (mask & XFS_AT_SIZE) { |
636 | /* | ||
637 | * Only change the c/mtime if we are changing the size | ||
638 | * or we are explicitly asked to change it. This handles | ||
639 | * the semantic difference between truncate() and ftruncate() | ||
640 | * as implemented in the VFS. | ||
641 | */ | ||
642 | if (vap->va_size != ip->i_size || (mask & XFS_AT_CTIME)) | ||
643 | timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; | ||
644 | |||
636 | if (vap->va_size > ip->i_size) { | 645 | if (vap->va_size > ip->i_size) { |
637 | xfs_igrow_finish(tp, ip, vap->va_size, | 646 | xfs_igrow_finish(tp, ip, vap->va_size, |
638 | !(flags & ATTR_DMI)); | 647 | !(flags & ATTR_DMI)); |
@@ -661,10 +670,6 @@ xfs_setattr( | |||
661 | */ | 670 | */ |
662 | xfs_iflags_set(ip, XFS_ITRUNCATED); | 671 | xfs_iflags_set(ip, XFS_ITRUNCATED); |
663 | } | 672 | } |
664 | /* | ||
665 | * Have to do this even if the file's size doesn't change. | ||
666 | */ | ||
667 | timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; | ||
668 | } | 673 | } |
669 | 674 | ||
670 | /* | 675 | /* |