Commit 9aabee2e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ext3_commit_write speedup

For an appending write, ext3_commit_write() will call the expensive
ext3_mark_inode_dirty() twice.  Once in generic_commit_write()'s extension of
i_size and once in ext3_commit_write() itself where i_disksize is updated.

But by updating i_disksize _before_ calling generic_commit_write() these can
be piggybacked.

The patch takes the overhead of a write() from 1.96 microseconds down to
1.63.
parent f0f46afd
......@@ -1165,6 +1165,12 @@ static int ext3_commit_write(struct file *file, struct page *page,
if (pos > inode->i_size)
inode->i_size = pos;
EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
if (inode->i_size > EXT3_I(inode)->i_disksize) {
EXT3_I(inode)->i_disksize = inode->i_size;
ret2 = ext3_mark_inode_dirty(handle, inode);
if (!ret)
ret = ret2;
}
} else {
if (ext3_should_order_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
......@@ -1172,14 +1178,18 @@ static int ext3_commit_write(struct file *file, struct page *page,
}
/* Be careful here if generic_commit_write becomes a
* required invocation after block_prepare_write. */
if (ret == 0)
if (ret == 0) {
/*
* generic_commit_write() will run mark_inode_dirty()
* if i_size changes. So let's piggyback the
* i_disksize mark_inode_dirty into that.
*/
loff_t new_i_size =
((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
if (new_i_size > EXT3_I(inode)->i_disksize)
EXT3_I(inode)->i_disksize = new_i_size;
ret = generic_commit_write(file, page, from, to);
}
if (inode->i_size > EXT3_I(inode)->i_disksize) {
EXT3_I(inode)->i_disksize = inode->i_size;
ret2 = ext3_mark_inode_dirty(handle, inode);
if (!ret)
ret = ret2;
}
}
ret2 = ext3_journal_stop(handle);
unlock_kernel();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment