diff options
author | Dave Chinner <dgc@sgi.com> | 2009-11-24 13:03:15 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2009-12-16 14:41:19 -0500 |
commit | 2ee1abad73a12df5521cd3f017f081f1f684a361 (patch) | |
tree | e44a88b0ae7f01d339426d7a6d18bde017bb9cf1 /fs/xfs | |
parent | b44b1126279b60597f96bbe77507b1650f88a969 (diff) |
xfs: improve metadata I/O merging in the elevator
Change all async metadata buffers to use [READ|WRITE]_META I/O types
so that the I/O doesn't get issued immediately. This allows merging of
adjacent metadata requests but still prioritises them over bulk data.
This shows a 10-15% improvement in sequential create speed of small
files.
Don't include the log buffers in this classification - leave them as
sync types so they are issued immediately.
Signed-off-by: Dave Chinner <dgc@sgi.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 6 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 2 |
3 files changed, 8 insertions, 1 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index b4c7d4248aac..162359b664ca 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1149,10 +1149,14 @@ _xfs_buf_ioapply( | |||
1149 | if (bp->b_flags & XBF_ORDERED) { | 1149 | if (bp->b_flags & XBF_ORDERED) { |
1150 | ASSERT(!(bp->b_flags & XBF_READ)); | 1150 | ASSERT(!(bp->b_flags & XBF_READ)); |
1151 | rw = WRITE_BARRIER; | 1151 | rw = WRITE_BARRIER; |
1152 | } else if (bp->b_flags & _XBF_RUN_QUEUES) { | 1152 | } else if (bp->b_flags & XBF_LOG_BUFFER) { |
1153 | ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); | 1153 | ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); |
1154 | bp->b_flags &= ~_XBF_RUN_QUEUES; | 1154 | bp->b_flags &= ~_XBF_RUN_QUEUES; |
1155 | rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC; | 1155 | rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC; |
1156 | } else if (bp->b_flags & _XBF_RUN_QUEUES) { | ||
1157 | ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); | ||
1158 | bp->b_flags &= ~_XBF_RUN_QUEUES; | ||
1159 | rw = (bp->b_flags & XBF_WRITE) ? WRITE_META : READ_META; | ||
1156 | } else { | 1160 | } else { |
1157 | rw = (bp->b_flags & XBF_WRITE) ? WRITE : | 1161 | rw = (bp->b_flags & XBF_WRITE) ? WRITE : |
1158 | (bp->b_flags & XBF_READ_AHEAD) ? READA : READ; | 1162 | (bp->b_flags & XBF_READ_AHEAD) ? READA : READ; |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index a509f4addc2a..a34c7b54822d 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -55,6 +55,7 @@ typedef enum { | |||
55 | XBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */ | 55 | XBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */ |
56 | XBF_ORDERED = (1 << 11), /* use ordered writes */ | 56 | XBF_ORDERED = (1 << 11), /* use ordered writes */ |
57 | XBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */ | 57 | XBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */ |
58 | XBF_LOG_BUFFER = (1 << 13), /* this is a buffer used for the log */ | ||
58 | 59 | ||
59 | /* flags used only as arguments to access routines */ | 60 | /* flags used only as arguments to access routines */ |
60 | XBF_LOCK = (1 << 14), /* lock requested */ | 61 | XBF_LOCK = (1 << 14), /* lock requested */ |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 4cb1792040e3..600b5b06aaeb 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1441,6 +1441,7 @@ xlog_sync(xlog_t *log, | |||
1441 | XFS_BUF_ZEROFLAGS(bp); | 1441 | XFS_BUF_ZEROFLAGS(bp); |
1442 | XFS_BUF_BUSY(bp); | 1442 | XFS_BUF_BUSY(bp); |
1443 | XFS_BUF_ASYNC(bp); | 1443 | XFS_BUF_ASYNC(bp); |
1444 | bp->b_flags |= XBF_LOG_BUFFER; | ||
1444 | /* | 1445 | /* |
1445 | * Do an ordered write for the log block. | 1446 | * Do an ordered write for the log block. |
1446 | * Its unnecessary to flush the first split block in the log wrap case. | 1447 | * Its unnecessary to flush the first split block in the log wrap case. |
@@ -1478,6 +1479,7 @@ xlog_sync(xlog_t *log, | |||
1478 | XFS_BUF_ZEROFLAGS(bp); | 1479 | XFS_BUF_ZEROFLAGS(bp); |
1479 | XFS_BUF_BUSY(bp); | 1480 | XFS_BUF_BUSY(bp); |
1480 | XFS_BUF_ASYNC(bp); | 1481 | XFS_BUF_ASYNC(bp); |
1482 | bp->b_flags |= XBF_LOG_BUFFER; | ||
1481 | if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) | 1483 | if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) |
1482 | XFS_BUF_ORDERED(bp); | 1484 | XFS_BUF_ORDERED(bp); |
1483 | dptr = XFS_BUF_PTR(bp); | 1485 | dptr = XFS_BUF_PTR(bp); |