aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-08 20:42:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-08 20:42:32 -0400
commita7b334de4d3651491ccd8c52c744af88d48785b9 (patch)
treedeba5b23183c0c8e9f75b86810b7628ce6d792d5
parent72ae9e092c8a62ef60a364ec812f5f88eb6442fc (diff)
parent430db323fae7665da721768949ade6304811c648 (diff)
Merge branch 'ext3-latency-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'ext3-latency-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext3: Try to avoid starting a transaction in writepage for data=writepage block_write_full_page: switch synchronous writes to use WRITE_SYNC_PLUG
-rw-r--r--fs/buffer.c13
-rw-r--r--fs/ext3/inode.c23
2 files changed, 30 insertions, 6 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 6e35762b6169..13edf7ad3ff1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1596,6 +1596,16 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
1596 * locked buffer. This only can happen if someone has written the buffer 1596 * locked buffer. This only can happen if someone has written the buffer
1597 * directly, with submit_bh(). At the address_space level PageWriteback 1597 * directly, with submit_bh(). At the address_space level PageWriteback
1598 * prevents this contention from occurring. 1598 * prevents this contention from occurring.
1599 *
1600 * If block_write_full_page() is called with wbc->sync_mode ==
1601 * WB_SYNC_ALL, the writes are posted using WRITE_SYNC_PLUG; this
1602 * causes the writes to be flagged as synchronous writes, but the
1603 * block device queue will NOT be unplugged, since usually many pages
1604 * will be pushed to the out before the higher-level caller actually
1605 * waits for the writes to be completed. The various wait functions,
1606 * such as wait_on_writeback_range() will ultimately call sync_page()
1607 * which will ultimately call blk_run_backing_dev(), which will end up
1608 * unplugging the device queue.
1599 */ 1609 */
1600static int __block_write_full_page(struct inode *inode, struct page *page, 1610static int __block_write_full_page(struct inode *inode, struct page *page,
1601 get_block_t *get_block, struct writeback_control *wbc) 1611 get_block_t *get_block, struct writeback_control *wbc)
@@ -1606,7 +1616,8 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
1606 struct buffer_head *bh, *head; 1616 struct buffer_head *bh, *head;
1607 const unsigned blocksize = 1 << inode->i_blkbits; 1617 const unsigned blocksize = 1 << inode->i_blkbits;
1608 int nr_underway = 0; 1618 int nr_underway = 0;
1609 int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE); 1619 int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
1620 WRITE_SYNC_PLUG : WRITE);
1610 1621
1611 BUG_ON(!PageLocked(page)); 1622 BUG_ON(!PageLocked(page));
1612 1623
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 466a332e0bd1..fcfa24361856 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1521,12 +1521,16 @@ static int ext3_ordered_writepage(struct page *page,
1521 if (!page_has_buffers(page)) { 1521 if (!page_has_buffers(page)) {
1522 create_empty_buffers(page, inode->i_sb->s_blocksize, 1522 create_empty_buffers(page, inode->i_sb->s_blocksize,
1523 (1 << BH_Dirty)|(1 << BH_Uptodate)); 1523 (1 << BH_Dirty)|(1 << BH_Uptodate));
1524 } else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) { 1524 page_bufs = page_buffers(page);
1525 /* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */ 1525 } else {
1526 return block_write_full_page(page, NULL, wbc); 1526 page_bufs = page_buffers(page);
1527 if (!walk_page_buffers(NULL, page_bufs, 0, PAGE_CACHE_SIZE,
1528 NULL, buffer_unmapped)) {
1529 /* Provide NULL get_block() to catch bugs if buffers
1530 * weren't really mapped */
1531 return block_write_full_page(page, NULL, wbc);
1532 }
1527 } 1533 }
1528 page_bufs = page_buffers(page);
1529
1530 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); 1534 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
1531 1535
1532 if (IS_ERR(handle)) { 1536 if (IS_ERR(handle)) {
@@ -1581,6 +1585,15 @@ static int ext3_writeback_writepage(struct page *page,
1581 if (ext3_journal_current_handle()) 1585 if (ext3_journal_current_handle())
1582 goto out_fail; 1586 goto out_fail;
1583 1587
1588 if (page_has_buffers(page)) {
1589 if (!walk_page_buffers(NULL, page_buffers(page), 0,
1590 PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
1591 /* Provide NULL get_block() to catch bugs if buffers
1592 * weren't really mapped */
1593 return block_write_full_page(page, NULL, wbc);
1594 }
1595 }
1596
1584 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); 1597 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
1585 if (IS_ERR(handle)) { 1598 if (IS_ERR(handle)) {
1586 ret = PTR_ERR(handle); 1599 ret = PTR_ERR(handle);