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
This commit is contained in:
commit
a7b334de4d
13
fs/buffer.c
13
fs/buffer.c
@ -1596,6 +1596,16 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
|
|||||||
* locked buffer. This only can happen if someone has written the buffer
|
* locked buffer. This only can happen if someone has written the buffer
|
||||||
* directly, with submit_bh(). At the address_space level PageWriteback
|
* directly, with submit_bh(). At the address_space level PageWriteback
|
||||||
* prevents this contention from occurring.
|
* prevents this contention from occurring.
|
||||||
|
*
|
||||||
|
* If block_write_full_page() is called with wbc->sync_mode ==
|
||||||
|
* WB_SYNC_ALL, the writes are posted using WRITE_SYNC_PLUG; this
|
||||||
|
* causes the writes to be flagged as synchronous writes, but the
|
||||||
|
* block device queue will NOT be unplugged, since usually many pages
|
||||||
|
* will be pushed to the out before the higher-level caller actually
|
||||||
|
* waits for the writes to be completed. The various wait functions,
|
||||||
|
* such as wait_on_writeback_range() will ultimately call sync_page()
|
||||||
|
* which will ultimately call blk_run_backing_dev(), which will end up
|
||||||
|
* unplugging the device queue.
|
||||||
*/
|
*/
|
||||||
static int __block_write_full_page(struct inode *inode, struct page *page,
|
static int __block_write_full_page(struct inode *inode, struct page *page,
|
||||||
get_block_t *get_block, struct writeback_control *wbc)
|
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,
|
|||||||
struct buffer_head *bh, *head;
|
struct buffer_head *bh, *head;
|
||||||
const unsigned blocksize = 1 << inode->i_blkbits;
|
const unsigned blocksize = 1 << inode->i_blkbits;
|
||||||
int nr_underway = 0;
|
int nr_underway = 0;
|
||||||
int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
|
int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
|
||||||
|
WRITE_SYNC_PLUG : WRITE);
|
||||||
|
|
||||||
BUG_ON(!PageLocked(page));
|
BUG_ON(!PageLocked(page));
|
||||||
|
|
||||||
|
@ -1521,12 +1521,16 @@ static int ext3_ordered_writepage(struct page *page,
|
|||||||
if (!page_has_buffers(page)) {
|
if (!page_has_buffers(page)) {
|
||||||
create_empty_buffers(page, inode->i_sb->s_blocksize,
|
create_empty_buffers(page, inode->i_sb->s_blocksize,
|
||||||
(1 << BH_Dirty)|(1 << BH_Uptodate));
|
(1 << BH_Dirty)|(1 << BH_Uptodate));
|
||||||
} else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
|
page_bufs = page_buffers(page);
|
||||||
/* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */
|
} else {
|
||||||
return block_write_full_page(page, NULL, wbc);
|
page_bufs = page_buffers(page);
|
||||||
|
if (!walk_page_buffers(NULL, page_bufs, 0, PAGE_CACHE_SIZE,
|
||||||
|
NULL, buffer_unmapped)) {
|
||||||
|
/* Provide NULL get_block() to catch bugs if buffers
|
||||||
|
* weren't really mapped */
|
||||||
|
return block_write_full_page(page, NULL, wbc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
page_bufs = page_buffers(page);
|
|
||||||
|
|
||||||
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
|
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
|
||||||
|
|
||||||
if (IS_ERR(handle)) {
|
if (IS_ERR(handle)) {
|
||||||
@ -1581,6 +1585,15 @@ static int ext3_writeback_writepage(struct page *page,
|
|||||||
if (ext3_journal_current_handle())
|
if (ext3_journal_current_handle())
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
|
|
||||||
|
if (page_has_buffers(page)) {
|
||||||
|
if (!walk_page_buffers(NULL, page_buffers(page), 0,
|
||||||
|
PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
|
||||||
|
/* Provide NULL get_block() to catch bugs if buffers
|
||||||
|
* weren't really mapped */
|
||||||
|
return block_write_full_page(page, NULL, wbc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
|
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
|
||||||
if (IS_ERR(handle)) {
|
if (IS_ERR(handle)) {
|
||||||
ret = PTR_ERR(handle);
|
ret = PTR_ERR(handle);
|
||||||
|
Loading…
Reference in New Issue
Block a user