Commit af5a30d8cfcfc561336f982b06345d6b815e0bb3

Authored by Nick Piggin
Committed by Al Viro
1 parent 8718d36cf9

fix truncate inode time modification breakage

mtime and ctime should be changed only if the file size has actually
changed. Patches changing ext2 and tmpfs from vmtruncate to new truncate
sequence has caused regressions where they always update timestamps.

There is some strange cases in POSIX where truncate(2) must not update
times unless the size has acutally changed, see 6e656be89.

This area is all still rather buggy in different ways in a lot of
filesystems and needs a cleanup and audit (ideally the vfs will provide
a simple attribute or call to direct all filesystems exactly which
attributes to change). But coming up with the best solution will take a
while and is not appropriate for rc anyway.

So fix recent regression for now.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 2 changed files with 4 additions and 3 deletions Side-by-side Diff

... ... @@ -1552,7 +1552,7 @@
1552 1552 if (error)
1553 1553 return error;
1554 1554 }
1555   - if (iattr->ia_valid & ATTR_SIZE) {
  1555 + if (iattr->ia_valid & ATTR_SIZE && iattr->ia_size != inode->i_size) {
1556 1556 error = ext2_setsize(inode, iattr->ia_size);
1557 1557 if (error)
1558 1558 return error;
... ... @@ -764,10 +764,11 @@
764 764 static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
765 765 {
766 766 struct inode *inode = dentry->d_inode;
  767 + loff_t newsize = attr->ia_size;
767 768 int error;
768 769  
769   - if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
770   - loff_t newsize = attr->ia_size;
  770 + if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
  771 + && newsize != inode->i_size) {
771 772 struct page *page = NULL;
772 773  
773 774 if (newsize < inode->i_size) {