Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7b334de authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 72ae9e09 430db323
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -1596,6 +1596,16 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
 * locked buffer.   This only can happen if someone has written the buffer
 * directly, with submit_bh().  At the address_space level PageWriteback
 * 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,
			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;
	const unsigned blocksize = 1 << inode->i_blkbits;
	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));

+18 −5
Original line number Diff line number Diff line
@@ -1521,12 +1521,16 @@ static int ext3_ordered_writepage(struct page *page,
	if (!page_has_buffers(page)) {
		create_empty_buffers(page, inode->i_sb->s_blocksize,
				(1 << BH_Dirty)|(1 << BH_Uptodate));
	} else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
		/* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */
		page_bufs = page_buffers(page);
	} else {
		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));

	if (IS_ERR(handle)) {
@@ -1581,6 +1585,15 @@ static int ext3_writeback_writepage(struct page *page,
	if (ext3_journal_current_handle())
		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));
	if (IS_ERR(handle)) {
		ret = PTR_ERR(handle);