aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-03-26 08:08:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 18:44:59 -0400
commit9e80d407736161d9b8b0c5a0d44f786e44c322ea (patch)
tree1d60b5b3e766cd123189278c3576f79d26315426
parent0384e2959127a56d0640505d004d8dd92f9c29f5 (diff)
ext3: Avoid starting a transaction in writepage when not necessary
We don't have to start a transaction in writepage() when all the blocks are a properly allocated. Even in ordered mode either the data has been written via write() and they are thus already added to transaction's list or the data was written via mmap and then it's random in which transaction they get written anyway. This should help VM to pageout dirty memory without blocking on transaction commits. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ext3/inode.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 5fa453b49a64..05e5c2e5c0d7 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1435,6 +1435,10 @@ static int journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
1435 return 0; 1435 return 0;
1436} 1436}
1437 1437
1438static int buffer_unmapped(handle_t *handle, struct buffer_head *bh)
1439{
1440 return !buffer_mapped(bh);
1441}
1438/* 1442/*
1439 * Note that we always start a transaction even if we're not journalling 1443 * Note that we always start a transaction even if we're not journalling
1440 * data. This is to preserve ordering: any hole instantiation within 1444 * data. This is to preserve ordering: any hole instantiation within
@@ -1505,6 +1509,15 @@ static int ext3_ordered_writepage(struct page *page,
1505 if (ext3_journal_current_handle()) 1509 if (ext3_journal_current_handle())
1506 goto out_fail; 1510 goto out_fail;
1507 1511
1512 if (!page_has_buffers(page)) {
1513 create_empty_buffers(page, inode->i_sb->s_blocksize,
1514 (1 << BH_Dirty)|(1 << BH_Uptodate));
1515 } else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
1516 /* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */
1517 return block_write_full_page(page, NULL, wbc);
1518 }
1519 page_bufs = page_buffers(page);
1520
1508 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); 1521 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
1509 1522
1510 if (IS_ERR(handle)) { 1523 if (IS_ERR(handle)) {
@@ -1512,11 +1525,6 @@ static int ext3_ordered_writepage(struct page *page,
1512 goto out_fail; 1525 goto out_fail;
1513 } 1526 }
1514 1527
1515 if (!page_has_buffers(page)) {
1516 create_empty_buffers(page, inode->i_sb->s_blocksize,
1517 (1 << BH_Dirty)|(1 << BH_Uptodate));
1518 }
1519 page_bufs = page_buffers(page);
1520 walk_page_buffers(handle, page_bufs, 0, 1528 walk_page_buffers(handle, page_bufs, 0,
1521 PAGE_CACHE_SIZE, NULL, bget_one); 1529 PAGE_CACHE_SIZE, NULL, bget_one);
1522 1530