aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-06-23 21:39:25 -0400
committerAlex Elder <aelder@sgi.com>2010-07-26 14:16:41 -0400
commit7a36c8a98a7dd05756bb147be2ac350325ff5830 (patch)
tree7a95c3e6090f209aecd0a1d5532ec577862248ca /fs
parent20cb52ebd1b5ca6fa8a5d9b6b1392292f5ca8a45 (diff)
xfs: avoid synchronous transaction in xfs_fs_write_inode
We already rely on the fact that the sync code will cause a synchronous log force later on (currently via xfs_fs_sync_fs -> xfs_quiesce_data -> xfs_sync_data), so no need to do this here. This allows us to avoid a lot of synchronous log forces during sync, which pays of especially with delayed logging enabled. Some compilebench numbers that show this: xfs (delayed logging, 256k logbufs) =================================== intial create 25.94 MB/s 25.75 MB/s 25.64 MB/s create 8.54 MB/s 9.12 MB/s 9.15 MB/s patch 2.47 MB/s 2.47 MB/s 3.17 MB/s compile 29.65 MB/s 30.51 MB/s 27.33 MB/s clean 90.92 MB/s 98.83 MB/s 128.87 MB/s read tree 11.90 MB/s 11.84 MB/s 8.56 MB/s read compiled 28.75 MB/s 29.96 MB/s 24.25 MB/s delete tree 8.39 seconds 8.12 seconds 8.46 seconds delete compiled 8.35 seconds 8.44 seconds 5.11 seconds stat tree 6.03 seconds 5.59 seconds 5.19 seconds stat compiled tree 9.00 seconds 9.52 seconds 8.49 seconds xfs + write_inode log_force removal =================================== intial create 25.87 MB/s 25.76 MB/s 25.87 MB/s create 15.18 MB/s 14.80 MB/s 14.94 MB/s patch 3.13 MB/s 3.14 MB/s 3.11 MB/s compile 36.74 MB/s 37.17 MB/s 36.84 MB/s clean 226.02 MB/s 222.58 MB/s 217.94 MB/s read tree 15.14 MB/s 15.02 MB/s 15.14 MB/s read compiled tree 29.30 MB/s 29.31 MB/s 29.32 MB/s delete tree 6.22 seconds 6.14 seconds 6.15 seconds delete compiled tree 5.75 seconds 5.92 seconds 5.81 seconds stat tree 4.60 seconds 4.51 seconds 4.56 seconds stat compiled tree 4.07 seconds 3.87 seconds 3.96 seconds In addition to that also remove the delwri inode flush that is unessecary now that bulkstat is always coherent. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index b8ad17e730b6..9a72c05b6177 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1025,7 +1025,6 @@ xfs_log_inode(
1025 */ 1025 */
1026 xfs_trans_ijoin(tp, ip); 1026 xfs_trans_ijoin(tp, ip);
1027 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1027 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1028 xfs_trans_set_sync(tp);
1029 error = xfs_trans_commit(tp, 0); 1028 error = xfs_trans_commit(tp, 0);
1030 xfs_ilock_demote(ip, XFS_ILOCK_EXCL); 1029 xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
1031 1030
@@ -1048,20 +1047,11 @@ xfs_fs_write_inode(
1048 1047
1049 if (wbc->sync_mode == WB_SYNC_ALL) { 1048 if (wbc->sync_mode == WB_SYNC_ALL) {
1050 /* 1049 /*
1051 * Make sure the inode has hit stable storage. By using the 1050 * Make sure the inode has made it it into the log. Instead
1052 * log and the fsync transactions we reduce the IOs we have 1051 * of forcing it all the way to stable storage using a
1053 * to do here from two (log and inode) to just the log. 1052 * synchronous transaction we let the log force inside the
1054 * 1053 * ->sync_fs call do that for thus, which reduces the number
1055 * Note: We still need to do a delwri write of the inode after 1054 * of synchronous log foces dramatically.
1056 * this to flush it to the backing buffer so that bulkstat
1057 * works properly if this is the first time the inode has been
1058 * written. Because we hold the ilock atomically over the
1059 * transaction commit and the inode flush we are guaranteed
1060 * that the inode is not pinned when it returns. If the flush
1061 * lock is already held, then the inode has already been
1062 * flushed once and we don't need to flush it again. Hence
1063 * the code will only flush the inode if it isn't already
1064 * being flushed.
1065 */ 1055 */
1066 xfs_ioend_wait(ip); 1056 xfs_ioend_wait(ip);
1067 xfs_ilock(ip, XFS_ILOCK_SHARED); 1057 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1075,27 +1065,29 @@ xfs_fs_write_inode(
1075 * We make this non-blocking if the inode is contended, return 1065 * We make this non-blocking if the inode is contended, return
1076 * EAGAIN to indicate to the caller that they did not succeed. 1066 * EAGAIN to indicate to the caller that they did not succeed.
1077 * This prevents the flush path from blocking on inodes inside 1067 * This prevents the flush path from blocking on inodes inside
1078 * another operation right now, they get caught later by xfs_sync. 1068 * another operation right now, they get caught later by
1069 * xfs_sync.
1079 */ 1070 */
1080 if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) 1071 if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
1081 goto out; 1072 goto out;
1082 }
1083 1073
1084 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) 1074 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
1085 goto out_unlock; 1075 goto out_unlock;
1086 1076
1087 /* 1077 /*
1088 * Now we have the flush lock and the inode is not pinned, we can check 1078 * Now we have the flush lock and the inode is not pinned, we
1089 * if the inode is really clean as we know that there are no pending 1079 * can check if the inode is really clean as we know that
1090 * transaction completions, it is not waiting on the delayed write 1080 * there are no pending transaction completions, it is not
1091 * queue and there is no IO in progress. 1081 * waiting on the delayed write queue and there is no IO in
1092 */ 1082 * progress.
1093 if (xfs_inode_clean(ip)) { 1083 */
1094 xfs_ifunlock(ip); 1084 if (xfs_inode_clean(ip)) {
1095 error = 0; 1085 xfs_ifunlock(ip);
1096 goto out_unlock; 1086 error = 0;
1087 goto out_unlock;
1088 }
1089 error = xfs_iflush(ip, 0);
1097 } 1090 }
1098 error = xfs_iflush(ip, 0);
1099 1091
1100 out_unlock: 1092 out_unlock:
1101 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1093 xfs_iunlock(ip, XFS_ILOCK_SHARED);