diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-02-15 04:44:49 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-03-01 17:34:45 -0500 |
commit | 66d834ea603d61bd90fedad90300ca91c5bba0a3 (patch) | |
tree | f73072b9d87bd71a0739f07e4d0e26f10c5d925a /fs/xfs/linux-2.6/xfs_file.c | |
parent | fd3200bef7d66ed3924f72c79a465fb7ff85478a (diff) |
xfs: implement optimized fdatasync
Allow us to track the difference between timestamp and size updates
by using mark_inode_dirty from the I/O completion code, and checking
the VFS inode flags in xfs_file_fsync.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_file.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 6c283b7be8ab..43f9554adaac 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -97,16 +97,6 @@ xfs_iozero( | |||
97 | return (-status); | 97 | return (-status); |
98 | } | 98 | } |
99 | 99 | ||
100 | /* | ||
101 | * We ignore the datasync flag here because a datasync is effectively | ||
102 | * identical to an fsync. That is, datasync implies that we need to write | ||
103 | * only the metadata needed to be able to access the data that is written | ||
104 | * if we crash after the call completes. Hence if we are writing beyond | ||
105 | * EOF we have to log the inode size change as well, which makes it a | ||
106 | * full fsync. If we don't write beyond EOF, the inode core will be | ||
107 | * clean in memory and so we don't need to log the inode, just like | ||
108 | * fsync. | ||
109 | */ | ||
110 | STATIC int | 100 | STATIC int |
111 | xfs_file_fsync( | 101 | xfs_file_fsync( |
112 | struct file *file, | 102 | struct file *file, |
@@ -139,7 +129,18 @@ xfs_file_fsync( | |||
139 | */ | 129 | */ |
140 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 130 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
141 | 131 | ||
142 | if (ip->i_update_core) { | 132 | /* |
133 | * First check if the VFS inode is marked dirty. All the dirtying | ||
134 | * of non-transactional updates no goes through mark_inode_dirty*, | ||
135 | * which allows us to distinguish beteeen pure timestamp updates | ||
136 | * and i_size updates which need to be caught for fdatasync. | ||
137 | * After that also theck for the dirty state in the XFS inode, which | ||
138 | * might gets cleared when the inode gets written out via the AIL | ||
139 | * or xfs_iflush_cluster. | ||
140 | */ | ||
141 | if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) || | ||
142 | ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) && | ||
143 | ip->i_update_core) { | ||
143 | /* | 144 | /* |
144 | * Kick off a transaction to log the inode core to get the | 145 | * Kick off a transaction to log the inode core to get the |
145 | * updates. The sync transaction will also force the log. | 146 | * updates. The sync transaction will also force the log. |