From 33c3de32872ef3c075e4dac04c0de8f86ac39f6f Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 30 Nov 2006 10:14:32 -0500 Subject: [GFS2] Don't flush everything on fdatasync The gfs2_fsync() function was doing a journal flush on each and every call. While this is correct, its also a lot of overhead. This patch means that on fdatasync flushes we rely on the VFS to flush the data for us and we don't do a journal flush unless we really need to. We have to do a journal flush for stuffed files though because they have the data and the inode metadata in the same block. Journaled files also need a journal flush too of course. Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_file.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index c2be216eb928..7bd971bf7cdd 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "gfs2.h" @@ -503,16 +504,39 @@ static int gfs2_close(struct inode *inode, struct file *file) * @file: the file that points to the dentry (we ignore this) * @dentry: the dentry that points to the inode to sync * + * The VFS will flush "normal" data for us. We only need to worry + * about metadata here. For journaled data, we just do a log flush + * as we can't avoid it. Otherwise we can just bale out if datasync + * is set. For stuffed inodes we must flush the log in order to + * ensure that all data is on disk. + * * Returns: errno */ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) { - struct gfs2_inode *ip = GFS2_I(dentry->d_inode); + struct inode *inode = dentry->d_inode; + int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); + int ret = 0; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL, + .nr_to_write = 0, + }; + + if (gfs2_is_jdata(GFS2_I(inode))) { + gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); + return 0; + } - gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); + if (sync_state != 0) { + if (!datasync) + ret = sync_inode(inode, &wbc); - return 0; + if (gfs2_is_stuffed(GFS2_I(inode))) + gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); + } + + return ret; } /** -- cgit v1.2.3