aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@sgi.com>2005-11-01 18:26:59 -0500
committerNathan Scott <nathans@sgi.com>2005-11-01 18:26:59 -0500
commitf538d4da8d521746ca5ebf8c1a8105eb49bfb45e (patch)
tree5516e1d2df01e412709284e379085b348122c501 /fs/xfs/xfs_vnodeops.c
parent739cafd316235fc55463849e80710f2ca308b9ae (diff)
[XFS] write barrier support Issue all log sync operations as ordered
writes. In addition flush the disk cache on fsync if the sync cached operation didn't sync the log to disk (this requires some additional bookeping in the transaction and log code). If the device doesn't claim to support barriers, the filesystem has an extern log volume or the trial superblock write with barriers enabled failed we disable barriers and print a warning. We should probably fail the mount completely, but that could lead to nasty boot failures for the root filesystem. Not enabled by default yet, needs more destructive testing first. SGI-PV: 912426 SGI-Modid: xfs-linux:xfs-kern:198723a Signed-off-by: Christoph Hellwig <hch@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 58bfe629b933..e2bf2ef58b66 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1118,6 +1118,7 @@ xfs_fsync(
1118 xfs_inode_t *ip; 1118 xfs_inode_t *ip;
1119 xfs_trans_t *tp; 1119 xfs_trans_t *tp;
1120 int error; 1120 int error;
1121 int log_flushed = 0, changed = 1;
1121 1122
1122 vn_trace_entry(BHV_TO_VNODE(bdp), 1123 vn_trace_entry(BHV_TO_VNODE(bdp),
1123 __FUNCTION__, (inst_t *)__return_address); 1124 __FUNCTION__, (inst_t *)__return_address);
@@ -1171,10 +1172,18 @@ xfs_fsync(
1171 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1172 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1172 1173
1173 if (xfs_ipincount(ip)) { 1174 if (xfs_ipincount(ip)) {
1174 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, 1175 _xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
1175 XFS_LOG_FORCE | 1176 XFS_LOG_FORCE |
1176 ((flag & FSYNC_WAIT) 1177 ((flag & FSYNC_WAIT)
1177 ? XFS_LOG_SYNC : 0)); 1178 ? XFS_LOG_SYNC : 0),
1179 &log_flushed);
1180 } else {
1181 /*
1182 * If the inode is not pinned and nothing
1183 * has changed we don't need to flush the
1184 * cache.
1185 */
1186 changed = 0;
1178 } 1187 }
1179 error = 0; 1188 error = 0;
1180 } else { 1189 } else {
@@ -1210,10 +1219,27 @@ xfs_fsync(
1210 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1219 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1211 if (flag & FSYNC_WAIT) 1220 if (flag & FSYNC_WAIT)
1212 xfs_trans_set_sync(tp); 1221 xfs_trans_set_sync(tp);
1213 error = xfs_trans_commit(tp, 0, NULL); 1222 error = _xfs_trans_commit(tp, 0, NULL, &log_flushed);
1214 1223
1215 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1224 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1216 } 1225 }
1226
1227 if ((ip->i_mount->m_flags & XFS_MOUNT_BARRIER) && changed) {
1228 /*
1229 * If the log write didn't issue an ordered tag we need
1230 * to flush the disk cache for the data device now.
1231 */
1232 if (!log_flushed)
1233 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
1234
1235 /*
1236 * If this inode is on the RT dev we need to flush that
1237 * cache aswell.
1238 */
1239 if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
1240 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
1241 }
1242
1217 return error; 1243 return error;
1218} 1244}
1219 1245