On Tue, Nov 05, 2013 at 03:55:43AM -0800, Andrew Gallagher wrote: > From: Andrew Gallagher <andrewjcg@xxxxxx> > > Various read operations (e.g. readlink, readdir) invalidate the > cached attrs for atime changes. However, mounts that have disabled > atime can avoid this invalidation and any performance cose. This > patch adds a new function 'fuse_invalidate_atime' modeled around > the 'touch_atime' function that which performs the various checks > for noatime situations and avoids the attr invalidation in that case. Doing it based on "MNT_NOATIME" isn't going to work, unfortunately: the nameidata in ->follow_link() doesn't contain a valid path. And besides, it's ugly. So lets just base this on MS_RDONLY, which implies NOATIME already. Updated, untested patch follows. Thanks, Miklos --- fs/fuse/dir.c | 14 ++++++++++++-- fs/fuse/file.c | 4 ++-- fs/fuse/fuse_i.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -112,6 +112,16 @@ void fuse_invalidate_attr(struct inode * get_fuse_inode(inode)->i_time = 0; } +/** + * Mark the attributes as stale due to an atime change. Avoid the invalidate if + * atime is not used. + */ +void fuse_invalidate_atime(struct inode *inode) +{ + if (!IS_RDONLY(inode)) + fuse_invalidate_attr(inode); +} + /* * Just mark the entry as stale, so that a next attempt to look it up * will result in a new lookup call to userspace @@ -1371,7 +1381,7 @@ static int fuse_readdir(struct file *fil } __free_page(page); - fuse_invalidate_attr(inode); /* atime changed */ + fuse_invalidate_atime(inode); return err; } @@ -1404,7 +1414,7 @@ static char *read_link(struct dentry *de link[req->out.args[0].size] = '\0'; out: fuse_put_request(fc, req); - fuse_invalidate_attr(inode); /* atime changed */ + fuse_invalidate_atime(inode); return link; } --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -687,7 +687,7 @@ static int fuse_readpage(struct file *fi SetPageUptodate(page); } - fuse_invalidate_attr(inode); /* atime changed */ + fuse_invalidate_atime(inode); out: unlock_page(page); return err; @@ -716,7 +716,7 @@ static void fuse_readpages_end(struct fu fuse_read_update_size(inode, pos, req->misc.read.attr_ver); } - fuse_invalidate_attr(inode); /* atime changed */ + fuse_invalidate_atime(inode); } for (i = 0; i < req->num_pages; i++) { --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -788,6 +788,8 @@ void fuse_invalidate_attr(struct inode * void fuse_invalidate_entry_cache(struct dentry *entry); +void fuse_invalidate_atime(struct inode *inode); + /** * Acquire reference to fuse_conn */ -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html