aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2013-07-26 10:38:49 -0700
committerBrian Behlendorf <[email protected]>2013-08-07 16:11:19 -0700
commit78d7a5d780d44708a6e8835a0f1e185cc8ee3dfb (patch)
tree9d46f9015f172175080e82c4381c4ff8ece7219e
parente0fd27870850d7beef9f01f93f30b7255338f4b0 (diff)
Write dirty inodes on close
When the property atime=on is set operations which only access and inode do cause an atime update. However, it turns out that dirty inodes with updated atimes are only written to disk when the inodes get evicted from the cache. Somewhat surprisingly the source suggests that this isn't a ZoL specific issue. This behavior may in part explain why zfs's reclaim logic has been observed to be slow. When reclaiming inodes its likely that they have a dirty atime which will force a write to disk. Obviously we don't want to force a write to disk for every atime update, these needs to be batched. The right way to do this is to fully implement the .dirty_inode and .write_inode callbacks. However, to do that right requires proper unification of some fields in the znode/inode. Then we could just mark the inode dirty and leave it to the VFS to call .write_inode periodically. Until that work gets done we have to settle for some middle ground. The simplest and safest thing we can do for now is to write the dirty inode on last close. This should prevent the majority of inodes in the cache from having dirty atimes and not drastically increase the number of writes. Some rudimentally testing to show how long it takes to drop 500,000 inodes from the cache shows promising results. This is as expected because we're no longer do lots of IO as part of the eviction, it was done earlier during the close. w/out patch: ~30s to drop 500,000 inodes with drop_caches. with patch: ~3s to drop 500,000 inodes with drop_caches. Signed-off-by: Brian Behlendorf <[email protected]>
-rw-r--r--module/zfs/zpl_file.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
index ebae6bfe2..299589193 100644
--- a/module/zfs/zpl_file.c
+++ b/module/zfs/zpl_file.c
@@ -52,6 +52,9 @@ zpl_release(struct inode *ip, struct file *filp)
cred_t *cr = CRED();
int error;
+ if (ITOZ(ip)->z_atime_dirty)
+ mark_inode_dirty(ip);
+
crhold(cr);
error = -zfs_close(ip, filp->f_flags, cr);
crfree(cr);