aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2016-04-24 00:56:07 -0400
committerTheodore Ts'o <tytso@mit.edu>2016-04-24 00:56:07 -0400
commit41617e1a8dec9fe082ba5dec26bacb154eb55482 (patch)
treecad9847e725526c8af355f116ec5cf317dc2d24c /fs/jbd2
parent3957ef53a5033bd519b19cf375061be1929bdb5f (diff)
jbd2: add support for avoiding data writes during transaction commits
Currently when filesystem needs to make sure data is on permanent storage before committing a transaction it adds inode to transaction's inode list. During transaction commit, jbd2 writes back all dirty buffers that have allocated underlying blocks and waits for the IO to finish. However when doing writeback for delayed allocated data, we allocate blocks and immediately submit the data. Thus asking jbd2 to write dirty pages just unnecessarily adds more work to jbd2 possibly writing back other redirtied blocks. Add support to jbd2 to allow filesystem to ask jbd2 to only wait for outstanding data writes before committing a transaction and thus avoid unnecessary writes. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2')
-rw-r--r--fs/jbd2/commit.c4
-rw-r--r--fs/jbd2/journal.c3
-rw-r--r--fs/jbd2/transaction.c22
3 files changed, 24 insertions, 5 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 2ad98d6e19f4..70078096117d 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -219,6 +219,8 @@ static int journal_submit_data_buffers(journal_t *journal,
219 219
220 spin_lock(&journal->j_list_lock); 220 spin_lock(&journal->j_list_lock);
221 list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { 221 list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
222 if (!(jinode->i_flags & JI_WRITE_DATA))
223 continue;
222 mapping = jinode->i_vfs_inode->i_mapping; 224 mapping = jinode->i_vfs_inode->i_mapping;
223 jinode->i_flags |= JI_COMMIT_RUNNING; 225 jinode->i_flags |= JI_COMMIT_RUNNING;
224 spin_unlock(&journal->j_list_lock); 226 spin_unlock(&journal->j_list_lock);
@@ -256,6 +258,8 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
256 /* For locking, see the comment in journal_submit_data_buffers() */ 258 /* For locking, see the comment in journal_submit_data_buffers() */
257 spin_lock(&journal->j_list_lock); 259 spin_lock(&journal->j_list_lock);
258 list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { 260 list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
261 if (!(jinode->i_flags & JI_WAIT_DATA))
262 continue;
259 jinode->i_flags |= JI_COMMIT_RUNNING; 263 jinode->i_flags |= JI_COMMIT_RUNNING;
260 spin_unlock(&journal->j_list_lock); 264 spin_unlock(&journal->j_list_lock);
261 err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping); 265 err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping);
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 435f0b26ac20..b31852f76f46 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -94,7 +94,8 @@ EXPORT_SYMBOL(jbd2_journal_blocks_per_page);
94EXPORT_SYMBOL(jbd2_journal_invalidatepage); 94EXPORT_SYMBOL(jbd2_journal_invalidatepage);
95EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); 95EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
96EXPORT_SYMBOL(jbd2_journal_force_commit); 96EXPORT_SYMBOL(jbd2_journal_force_commit);
97EXPORT_SYMBOL(jbd2_journal_file_inode); 97EXPORT_SYMBOL(jbd2_journal_inode_add_write);
98EXPORT_SYMBOL(jbd2_journal_inode_add_wait);
98EXPORT_SYMBOL(jbd2_journal_init_jbd_inode); 99EXPORT_SYMBOL(jbd2_journal_init_jbd_inode);
99EXPORT_SYMBOL(jbd2_journal_release_jbd_inode); 100EXPORT_SYMBOL(jbd2_journal_release_jbd_inode);
100EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate); 101EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate);
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 67c103867bf8..be56c8ca34c2 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -2462,7 +2462,8 @@ void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh)
2462/* 2462/*
2463 * File inode in the inode list of the handle's transaction 2463 * File inode in the inode list of the handle's transaction
2464 */ 2464 */
2465int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) 2465static int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode,
2466 unsigned long flags)
2466{ 2467{
2467 transaction_t *transaction = handle->h_transaction; 2468 transaction_t *transaction = handle->h_transaction;
2468 journal_t *journal; 2469 journal_t *journal;
@@ -2487,12 +2488,14 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode)
2487 * and if jinode->i_next_transaction == transaction, commit code 2488 * and if jinode->i_next_transaction == transaction, commit code
2488 * will only file the inode where we want it. 2489 * will only file the inode where we want it.
2489 */ 2490 */
2490 if (jinode->i_transaction == transaction || 2491 if ((jinode->i_transaction == transaction ||
2491 jinode->i_next_transaction == transaction) 2492 jinode->i_next_transaction == transaction) &&
2493 (jinode->i_flags & flags) == flags)
2492 return 0; 2494 return 0;
2493 2495
2494 spin_lock(&journal->j_list_lock); 2496 spin_lock(&journal->j_list_lock);
2495 2497 jinode->i_flags |= flags;
2498 /* Is inode already attached where we need it? */
2496 if (jinode->i_transaction == transaction || 2499 if (jinode->i_transaction == transaction ||
2497 jinode->i_next_transaction == transaction) 2500 jinode->i_next_transaction == transaction)
2498 goto done; 2501 goto done;
@@ -2523,6 +2526,17 @@ done:
2523 return 0; 2526 return 0;
2524} 2527}
2525 2528
2529int jbd2_journal_inode_add_write(handle_t *handle, struct jbd2_inode *jinode)
2530{
2531 return jbd2_journal_file_inode(handle, jinode,
2532 JI_WRITE_DATA | JI_WAIT_DATA);
2533}
2534
2535int jbd2_journal_inode_add_wait(handle_t *handle, struct jbd2_inode *jinode)
2536{
2537 return jbd2_journal_file_inode(handle, jinode, JI_WAIT_DATA);
2538}
2539
2526/* 2540/*
2527 * File truncate and transaction commit interact with each other in a 2541 * File truncate and transaction commit interact with each other in a
2528 * non-trivial way. If a transaction writing data block A is 2542 * non-trivial way. If a transaction writing data block A is