From 824f53bb3e3a6575ca7369aa91adb7a902e6d9af Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 27 Jul 2011 10:58:48 +0100 Subject: [PATCH] --- yaml --- r: 269990 b: refs/heads/master c: 2f0264d592e34cde99efbad7d616b04af138e913 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/gfs2/file.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index f3c94f401260..120026f2a55e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4c28d33803d4aeaff32b4ac502af11a9b2aed8f4 +refs/heads/master: 2f0264d592e34cde99efbad7d616b04af138e913 diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index edeb9e802903..92c3db424b40 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -551,8 +551,16 @@ static int gfs2_close(struct inode *inode, struct file *file) * @end: the end position in the file to sync * @datasync: set if we can ignore timestamp changes * - * The VFS will flush data for us. We only need to worry - * about metadata here. + * We split the data flushing here so that we don't wait for the data + * until after we've also sent the metadata to disk. Note that for + * data=ordered, we will write & wait for the data at the log flush + * stage anyway, so this is unlikely to make much of a difference + * except in the data=writeback case. + * + * If the fdatawrite fails due to any reason except -EIO, we will + * continue the remainder of the fsync, although we'll still report + * the error at the end. This is to match filemap_write_and_wait_range() + * behaviour. * * Returns: errno */ @@ -560,30 +568,36 @@ static int gfs2_close(struct inode *inode, struct file *file) static int gfs2_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - struct inode *inode = file->f_mapping->host; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); struct gfs2_inode *ip = GFS2_I(inode); - int ret; + int ret, ret1 = 0; - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); - if (ret) - return ret; - mutex_lock(&inode->i_mutex); + if (mapping->nrpages) { + ret1 = filemap_fdatawrite_range(mapping, start, end); + if (ret1 == -EIO) + return ret1; + } if (datasync) sync_state &= ~I_DIRTY_SYNC; if (sync_state) { + mutex_lock(&inode->i_mutex); ret = sync_inode_metadata(inode, 1); if (ret) { mutex_unlock(&inode->i_mutex); return ret; } gfs2_ail_flush(ip->i_gl); + mutex_unlock(&inode->i_mutex); } - mutex_unlock(&inode->i_mutex); - return 0; + if (mapping->nrpages) + ret = filemap_fdatawait_range(mapping, start, end); + + return ret ? ret : ret1; } /**