From dc66f47e91597bbc568ed40289263d5a75bdcfa8 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Thu, 8 Jan 2009 08:02:24 -0800 Subject: [PATCH] async: make the filesystem part of the atime update asynchronous the atime update is often a rather real latency source for applications; this patch makes the filesystem part of this operation run asynchronously so that applications don't have to wait for this. Signed-off-by: Arjan van de Ven --- fs/inode.c | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 0013ac1..dcf2c1a 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1288,6 +1288,20 @@ sector_t bmap(struct inode * inode, sector_t block) } EXPORT_SYMBOL(bmap); +struct mnt_inode { + struct vfsmount *mnt; + struct inode *inode; +}; + +void touch_atime_async(void *data, async_cookie_t cookie) +{ + struct mnt_inode *mi = data; + mark_inode_dirty_sync(mi->inode); + iput(mi->inode); + mnt_drop_write(mi->mnt); + kfree(mi); +} + /** * touch_atime - update the access time * @mnt: mount the inode is accessed on @@ -1301,6 +1315,7 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) { struct inode *inode = dentry->d_inode; struct timespec now; + struct mnt_inode *mi; if (mnt_want_write(mnt)) return; @@ -1330,7 +1345,21 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) goto out; inode->i_atime = now; - mark_inode_dirty_sync(inode); + + mi = kmalloc(sizeof(struct mnt_inode), GFP_NOFS); + if (mi) { + /* + * since we know the i_count count is already at least 1, no + * need to do get the inode lock and then do _iget... + */ + atomic_inc(&inode->i_count); + mi->inode = inode; + mi->mnt = mnt; + async_schedule(touch_atime_async, mi); + return; + } else { + mark_inode_dirty_sync(inode); + } out: mnt_drop_write(mnt); } -- 1.5.5.1