aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2009-09-18 16:05:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-09-24 07:47:27 -0400
commitce06e0b21d6732a2bab10a585a3ec6909499be28 (patch)
tree5d796827ad968bf305c54a2dd7d6453a24e15344 /fs
parentb12536c27043f1c21195e587eb59950428326e22 (diff)
vfs: optimize touch_time() too
Do a similar optimization as earlier for touch_atime. Getting the lock in mnt_get_write is relatively costly, so try all avenues to avoid it first. This patch is careful to still only update inode fields inside the lock region. This didn't show up in benchmarks, but it's easy enough to do. [akpm@linux-foundation.org: fix typo in comment] [hugh.dickins@tiscali.co.uk: fix inverted test of mnt_want_write_file()] Signed-off-by: Andi Kleen <ak@linux.intel.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Valerie Aurora <vaurora@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Dave Hansen <haveblue@us.ibm.com> Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/inode.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 31168fd45bdc..4d8e3be55976 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1461,34 +1461,37 @@ void file_update_time(struct file *file)
1461{ 1461{
1462 struct inode *inode = file->f_path.dentry->d_inode; 1462 struct inode *inode = file->f_path.dentry->d_inode;
1463 struct timespec now; 1463 struct timespec now;
1464 int sync_it = 0; 1464 enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0;
1465 int err;
1466 1465
1466 /* First try to exhaust all avenues to not sync */
1467 if (IS_NOCMTIME(inode)) 1467 if (IS_NOCMTIME(inode))
1468 return; 1468 return;
1469 1469
1470 err = mnt_want_write_file(file);
1471 if (err)
1472 return;
1473
1474 now = current_fs_time(inode->i_sb); 1470 now = current_fs_time(inode->i_sb);
1475 if (!timespec_equal(&inode->i_mtime, &now)) { 1471 if (!timespec_equal(&inode->i_mtime, &now))
1476 inode->i_mtime = now; 1472 sync_it = S_MTIME;
1477 sync_it = 1;
1478 }
1479 1473
1480 if (!timespec_equal(&inode->i_ctime, &now)) { 1474 if (!timespec_equal(&inode->i_ctime, &now))
1481 inode->i_ctime = now; 1475 sync_it |= S_CTIME;
1482 sync_it = 1;
1483 }
1484 1476
1485 if (IS_I_VERSION(inode)) { 1477 if (IS_I_VERSION(inode))
1486 inode_inc_iversion(inode); 1478 sync_it |= S_VERSION;
1487 sync_it = 1;
1488 }
1489 1479
1490 if (sync_it) 1480 if (!sync_it)
1491 mark_inode_dirty_sync(inode); 1481 return;
1482
1483 /* Finally allowed to write? Takes lock. */
1484 if (mnt_want_write_file(file))
1485 return;
1486
1487 /* Only change inode inside the lock region */
1488 if (sync_it & S_VERSION)
1489 inode_inc_iversion(inode);
1490 if (sync_it & S_CTIME)
1491 inode->i_ctime = now;
1492 if (sync_it & S_MTIME)
1493 inode->i_mtime = now;
1494 mark_inode_dirty_sync(inode);
1492 mnt_drop_write(file->f_path.mnt); 1495 mnt_drop_write(file->f_path.mnt);
1493} 1496}
1494EXPORT_SYMBOL(file_update_time); 1497EXPORT_SYMBOL(file_update_time);