aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_file.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-02-15 04:44:48 -0500
committerAlex Elder <aelder@sgi.com>2010-03-01 17:34:38 -0500
commitfd3200bef7d66ed3924f72c79a465fb7ff85478a (patch)
treef10c210269fc59854dd8f8b247b63454d772a574 /fs/xfs/linux-2.6/xfs_file.c
parent00258e36b2d33b1b5cef7b489e06c5e0a9df58b5 (diff)
xfs: remove wrapper for the fsync file operation
Currently the fsync file operation is divided into a low-level routine doing all the work and one that implements the Linux file operation and does minimal argument wrapping. This is a leftover from the days of the vnode operations layer and can be removed to simplify the code a bit, as well as preparing for the implementation of an optimized fdatasync which needs to look at the Linux inode state. Signed-off-by: Christoph Hellwig <hch@lst.de> 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.c140
1 files changed, 117 insertions, 23 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 1eb561a10e26..6c283b7be8ab 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -35,6 +35,7 @@
35#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
36#include "xfs_dinode.h" 36#include "xfs_dinode.h"
37#include "xfs_inode.h" 37#include "xfs_inode.h"
38#include "xfs_inode_item.h"
38#include "xfs_bmap.h" 39#include "xfs_bmap.h"
39#include "xfs_error.h" 40#include "xfs_error.h"
40#include "xfs_rw.h" 41#include "xfs_rw.h"
@@ -96,6 +97,120 @@ xfs_iozero(
96 return (-status); 97 return (-status);
97} 98}
98 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 */
110STATIC int
111xfs_file_fsync(
112 struct file *file,
113 struct dentry *dentry,
114 int datasync)
115{
116 struct xfs_inode *ip = XFS_I(dentry->d_inode);
117 struct xfs_trans *tp;
118 int error = 0;
119 int log_flushed = 0;
120
121 xfs_itrace_entry(ip);
122
123 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
124 return -XFS_ERROR(EIO);
125
126 xfs_iflags_clear(ip, XFS_ITRUNCATED);
127
128 /*
129 * We always need to make sure that the required inode state is safe on
130 * disk. The inode might be clean but we still might need to force the
131 * log because of committed transactions that haven't hit the disk yet.
132 * Likewise, there could be unflushed non-transactional changes to the
133 * inode core that have to go to disk and this requires us to issue
134 * a synchronous transaction to capture these changes correctly.
135 *
136 * This code relies on the assumption that if the i_update_core field
137 * of the inode is clear and the inode is unpinned then it is clean
138 * and no action is required.
139 */
140 xfs_ilock(ip, XFS_ILOCK_SHARED);
141
142 if (ip->i_update_core) {
143 /*
144 * Kick off a transaction to log the inode core to get the
145 * updates. The sync transaction will also force the log.
146 */
147 xfs_iunlock(ip, XFS_ILOCK_SHARED);
148 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
149 error = xfs_trans_reserve(tp, 0,
150 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
151 if (error) {
152 xfs_trans_cancel(tp, 0);
153 return -error;
154 }
155 xfs_ilock(ip, XFS_ILOCK_EXCL);
156
157 /*
158 * Note - it's possible that we might have pushed ourselves out
159 * of the way during trans_reserve which would flush the inode.
160 * But there's no guarantee that the inode buffer has actually
161 * gone out yet (it's delwri). Plus the buffer could be pinned
162 * anyway if it's part of an inode in another recent
163 * transaction. So we play it safe and fire off the
164 * transaction anyway.
165 */
166 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
167 xfs_trans_ihold(tp, ip);
168 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
169 xfs_trans_set_sync(tp);
170 error = _xfs_trans_commit(tp, 0, &log_flushed);
171
172 xfs_iunlock(ip, XFS_ILOCK_EXCL);
173 } else {
174 /*
175 * Timestamps/size haven't changed since last inode flush or
176 * inode transaction commit. That means either nothing got
177 * written or a transaction committed which caught the updates.
178 * If the latter happened and the transaction hasn't hit the
179 * disk yet, the inode will be still be pinned. If it is,
180 * force the log.
181 */
182 xfs_iunlock(ip, XFS_ILOCK_SHARED);
183 if (xfs_ipincount(ip)) {
184 if (ip->i_itemp->ili_last_lsn) {
185 error = _xfs_log_force_lsn(ip->i_mount,
186 ip->i_itemp->ili_last_lsn,
187 XFS_LOG_SYNC, &log_flushed);
188 } else {
189 error = _xfs_log_force(ip->i_mount,
190 XFS_LOG_SYNC, &log_flushed);
191 }
192 }
193 }
194
195 if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
196 /*
197 * If the log write didn't issue an ordered tag we need
198 * to flush the disk cache for the data device now.
199 */
200 if (!log_flushed)
201 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
202
203 /*
204 * If this inode is on the RT dev we need to flush that
205 * cache as well.
206 */
207 if (XFS_IS_REALTIME_INODE(ip))
208 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
209 }
210
211 return -error;
212}
213
99STATIC ssize_t 214STATIC ssize_t
100xfs_file_aio_read( 215xfs_file_aio_read(
101 struct kiocb *iocb, 216 struct kiocb *iocb,
@@ -755,7 +870,8 @@ write_retry:
755 mutex_lock(&inode->i_mutex); 870 mutex_lock(&inode->i_mutex);
756 xfs_ilock(ip, iolock); 871 xfs_ilock(ip, iolock);
757 872
758 error2 = xfs_fsync(ip); 873 error2 = -xfs_file_fsync(file, file->f_path.dentry,
874 (file->f_flags & __O_SYNC) ? 0 : 1);
759 if (!error) 875 if (!error)
760 error = error2; 876 error = error2;
761 } 877 }
@@ -826,28 +942,6 @@ xfs_file_release(
826 return -xfs_release(XFS_I(inode)); 942 return -xfs_release(XFS_I(inode));
827} 943}
828 944
829/*
830 * We ignore the datasync flag here because a datasync is effectively
831 * identical to an fsync. That is, datasync implies that we need to write
832 * only the metadata needed to be able to access the data that is written
833 * if we crash after the call completes. Hence if we are writing beyond
834 * EOF we have to log the inode size change as well, which makes it a
835 * full fsync. If we don't write beyond EOF, the inode core will be
836 * clean in memory and so we don't need to log the inode, just like
837 * fsync.
838 */
839STATIC int
840xfs_file_fsync(
841 struct file *file,
842 struct dentry *dentry,
843 int datasync)
844{
845 struct xfs_inode *ip = XFS_I(dentry->d_inode);
846
847 xfs_iflags_clear(ip, XFS_ITRUNCATED);
848 return -xfs_fsync(ip);
849}
850
851STATIC int 945STATIC int
852xfs_file_readdir( 946xfs_file_readdir(
853 struct file *filp, 947 struct file *filp,