ext4: optimize ext4_writepage() for attempted 4k delalloc writes
In cases where the file system block size is the same as the page size, and ext4_writepage() is asked to write out a page which is either has the unwritten bit set in the extent tree, or which does not yet have a block assigned due to delayed allocation, we can bail out early and, unlocking the page earlier and avoiding a round trip through ext4_bio_write_page() with the attendant calls to set_page_writeback() and redirty_page_for_writeback(). Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
937d7b84dc
commit
cccd147a57
|
@ -1815,11 +1815,22 @@ static int ext4_writepage(struct page *page,
|
||||||
* the page. But we may reach here when we do a journal commit via
|
* the page. But we may reach here when we do a journal commit via
|
||||||
* journal_submit_inode_data_buffers() and in that case we must write
|
* journal_submit_inode_data_buffers() and in that case we must write
|
||||||
* allocated buffers to achieve data=ordered mode guarantees.
|
* allocated buffers to achieve data=ordered mode guarantees.
|
||||||
|
*
|
||||||
|
* Also, if there is only one buffer per page (the fs block
|
||||||
|
* size == the page size), if one buffer needs block
|
||||||
|
* allocation or needs to modify the extent tree to clear the
|
||||||
|
* unwritten flag, we know that the page can't be written at
|
||||||
|
* all, so we might as well refuse the write immediately.
|
||||||
|
* Unfortunately if the block size != page size, we can't as
|
||||||
|
* easily detect this case using ext4_walk_page_buffers(), but
|
||||||
|
* for the extremely common case, this is an optimization that
|
||||||
|
* skips a useless round trip through ext4_bio_write_page().
|
||||||
*/
|
*/
|
||||||
if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL,
|
if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL,
|
||||||
ext4_bh_delay_or_unwritten)) {
|
ext4_bh_delay_or_unwritten)) {
|
||||||
redirty_page_for_writepage(wbc, page);
|
redirty_page_for_writepage(wbc, page);
|
||||||
if (current->flags & PF_MEMALLOC) {
|
if ((current->flags & PF_MEMALLOC) ||
|
||||||
|
(inode->i_sb->s_blocksize == PAGE_CACHE_SIZE)) {
|
||||||
/*
|
/*
|
||||||
* For memory cleaning there's no point in writing only
|
* For memory cleaning there's no point in writing only
|
||||||
* some buffers. So just bail out. Warn if we came here
|
* some buffers. So just bail out. Warn if we came here
|
||||||
|
|
Loading…
Reference in New Issue