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

Commit 20bec8ab 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: Add replace-on-rename hueristics for data=writeback mode
  ext3: Add replace-on-truncate hueristics for data=writeback mode
  ext3: Use WRITE_SYNC for commits which are caused by fsync()
  block_write_full_page: Use synchronous writes for WBC_SYNC_ALL writebacks
parents 18b34b95 e7c8f507
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1595,6 +1595,7 @@ 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);

	BUG_ON(!PageLocked(page));

@@ -1686,7 +1687,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
	do {
		struct buffer_head *next = bh->b_this_page;
		if (buffer_async_write(bh)) {
			submit_bh(WRITE, bh);
			submit_bh(write_op, bh);
			nr_underway++;
		}
		bh = next;
@@ -1740,7 +1741,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
		struct buffer_head *next = bh->b_this_page;
		if (buffer_async_write(bh)) {
			clear_buffer_dirty(bh);
			submit_bh(WRITE, bh);
			submit_bh(write_op, bh);
			nr_underway++;
		}
		bh = next;
+4 −0
Original line number Diff line number Diff line
@@ -33,6 +33,10 @@
 */
static int ext3_release_file (struct inode * inode, struct file * filp)
{
	if (EXT3_I(inode)->i_state & EXT3_STATE_FLUSH_ON_CLOSE) {
		filemap_flush(inode->i_mapping);
		EXT3_I(inode)->i_state &= ~EXT3_STATE_FLUSH_ON_CLOSE;
	}
	/* if we are the last writer on the inode, drop the block reservation */
	if ((filp->f_mode & FMODE_WRITE) &&
			(atomic_read(&inode->i_writecount) == 1))
+3 −0
Original line number Diff line number Diff line
@@ -2363,6 +2363,9 @@ void ext3_truncate(struct inode *inode)
	if (!ext3_can_truncate(inode))
		return;

	if (inode->i_size == 0 && ext3_should_writeback_data(inode))
		ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE;

	/*
	 * We have to lock the EOF page here, because lock_page() nests
	 * outside journal_start().
+5 −1
Original line number Diff line number Diff line
@@ -2274,7 +2274,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
	struct inode * old_inode, * new_inode;
	struct buffer_head * old_bh, * new_bh, * dir_bh;
	struct ext3_dir_entry_2 * old_de, * new_de;
	int retval;
	int retval, flush_file = 0;

	old_bh = new_bh = dir_bh = NULL;

@@ -2410,6 +2410,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
		ext3_mark_inode_dirty(handle, new_inode);
		if (!new_inode->i_nlink)
			ext3_orphan_add(handle, new_inode);
		if (ext3_should_writeback_data(new_inode))
			flush_file = 1;
	}
	retval = 0;

@@ -2418,6 +2420,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
	brelse (old_bh);
	brelse (new_bh);
	ext3_journal_stop(handle);
	if (retval == 0 && flush_file)
		filemap_flush(old_inode->i_mapping);
	return retval;
}

+15 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/bio.h>

/*
 * Default IO end handler for temporary BJ_IO buffer_heads.
@@ -171,14 +172,15 @@ static int journal_write_commit_record(journal_t *journal,
	return (ret == -EIO);
}

static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
static void journal_do_submit_data(struct buffer_head **wbuf, int bufs,
				   int write_op)
{
	int i;

	for (i = 0; i < bufs; i++) {
		wbuf[i]->b_end_io = end_buffer_write_sync;
		/* We use-up our safety reference in submit_bh() */
		submit_bh(WRITE, wbuf[i]);
		submit_bh(write_op, wbuf[i]);
	}
}

@@ -186,7 +188,8 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
 *  Submit all the data buffers to disk
 */
static int journal_submit_data_buffers(journal_t *journal,
				transaction_t *commit_transaction)
				       transaction_t *commit_transaction,
				       int write_op)
{
	struct journal_head *jh;
	struct buffer_head *bh;
@@ -225,7 +228,7 @@ static int journal_submit_data_buffers(journal_t *journal,
				BUFFER_TRACE(bh, "needs blocking lock");
				spin_unlock(&journal->j_list_lock);
				/* Write out all data to prevent deadlocks */
				journal_do_submit_data(wbuf, bufs);
				journal_do_submit_data(wbuf, bufs, write_op);
				bufs = 0;
				lock_buffer(bh);
				spin_lock(&journal->j_list_lock);
@@ -256,7 +259,7 @@ static int journal_submit_data_buffers(journal_t *journal,
			jbd_unlock_bh_state(bh);
			if (bufs == journal->j_wbufsize) {
				spin_unlock(&journal->j_list_lock);
				journal_do_submit_data(wbuf, bufs);
				journal_do_submit_data(wbuf, bufs, write_op);
				bufs = 0;
				goto write_out_data;
			}
@@ -286,7 +289,7 @@ static int journal_submit_data_buffers(journal_t *journal,
		}
	}
	spin_unlock(&journal->j_list_lock);
	journal_do_submit_data(wbuf, bufs);
	journal_do_submit_data(wbuf, bufs, write_op);

	return err;
}
@@ -315,6 +318,7 @@ void journal_commit_transaction(journal_t *journal)
	int first_tag = 0;
	int tag_flag;
	int i;
	int write_op = WRITE;

	/*
	 * First job: lock down the current transaction and wait for
@@ -347,6 +351,8 @@ void journal_commit_transaction(journal_t *journal)
	spin_lock(&journal->j_state_lock);
	commit_transaction->t_state = T_LOCKED;

	if (commit_transaction->t_synchronous_commit)
		write_op = WRITE_SYNC;
	spin_lock(&commit_transaction->t_handle_lock);
	while (commit_transaction->t_updates) {
		DEFINE_WAIT(wait);
@@ -431,7 +437,8 @@ void journal_commit_transaction(journal_t *journal)
	 * Now start flushing things to disk, in the order they appear
	 * on the transaction lists.  Data blocks go first.
	 */
	err = journal_submit_data_buffers(journal, commit_transaction);
	err = journal_submit_data_buffers(journal, commit_transaction,
					  write_op);

	/*
	 * Wait for all previously submitted IO to complete.
@@ -660,7 +667,7 @@ void journal_commit_transaction(journal_t *journal)
				clear_buffer_dirty(bh);
				set_buffer_uptodate(bh);
				bh->b_end_io = journal_end_buffer_io_sync;
				submit_bh(WRITE, bh);
				submit_bh(write_op, bh);
			}
			cond_resched();

Loading