aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/commit.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-07-11 19:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-11 19:27:31 -0400
commitc851ed540173736e60d48b53b91a16ea5c903896 (patch)
tree828fe0d71b7f18dc170090dbb2fb5ac9deae4ee0 /fs/jbd2/commit.c
parentf4c0a0fdfae708f7aa438c27a380ed4071294e11 (diff)
jbd2: Implement data=ordered mode handling via inodes
This patch adds necessary framework into JBD2 to be able to track inodes with each transaction and write-out their dirty data during transaction commit time. This new ordered mode brings all sorts of advantages such as possibility to get rid of journal heads and buffer heads for data buffers in ordered mode, better ordering of writes on transaction commit, simplification of some JBD code, no more anonymous pages when truncate of data being committed happens. Also with this new ordered mode, delayed allocation on ordered mode is much simpler. Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r--fs/jbd2/commit.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 92b6ac3df8ab..3ca107b5c86b 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -355,6 +355,81 @@ write_out_data:
355 journal_do_submit_data(wbuf, bufs); 355 journal_do_submit_data(wbuf, bufs);
356} 356}
357 357
358/*
359 * Submit all the data buffers of inode associated with the transaction to
360 * disk.
361 *
362 * We are in a committing transaction. Therefore no new inode can be added to
363 * our inode list. We use JI_COMMIT_RUNNING flag to protect inode we currently
364 * operate on from being released while we write out pages.
365 */
366static int journal_submit_inode_data_buffers(journal_t *journal,
367 transaction_t *commit_transaction)
368{
369 struct jbd2_inode *jinode;
370 int err, ret = 0;
371 struct address_space *mapping;
372
373 spin_lock(&journal->j_list_lock);
374 list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
375 mapping = jinode->i_vfs_inode->i_mapping;
376 jinode->i_flags |= JI_COMMIT_RUNNING;
377 spin_unlock(&journal->j_list_lock);
378 err = filemap_fdatawrite_range(mapping, 0,
379 i_size_read(jinode->i_vfs_inode));
380 if (!ret)
381 ret = err;
382 spin_lock(&journal->j_list_lock);
383 J_ASSERT(jinode->i_transaction == commit_transaction);
384 jinode->i_flags &= ~JI_COMMIT_RUNNING;
385 wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);
386 }
387 spin_unlock(&journal->j_list_lock);
388 return ret;
389}
390
391/*
392 * Wait for data submitted for writeout, refile inodes to proper
393 * transaction if needed.
394 *
395 */
396static int journal_finish_inode_data_buffers(journal_t *journal,
397 transaction_t *commit_transaction)
398{
399 struct jbd2_inode *jinode, *next_i;
400 int err, ret = 0;
401
402 /* For locking, see the comment in journal_submit_inode_data_buffers() */
403 spin_lock(&journal->j_list_lock);
404 list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
405 jinode->i_flags |= JI_COMMIT_RUNNING;
406 spin_unlock(&journal->j_list_lock);
407 err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping);
408 if (!ret)
409 ret = err;
410 spin_lock(&journal->j_list_lock);
411 jinode->i_flags &= ~JI_COMMIT_RUNNING;
412 wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);
413 }
414
415 /* Now refile inode to proper lists */
416 list_for_each_entry_safe(jinode, next_i,
417 &commit_transaction->t_inode_list, i_list) {
418 list_del(&jinode->i_list);
419 if (jinode->i_next_transaction) {
420 jinode->i_transaction = jinode->i_next_transaction;
421 jinode->i_next_transaction = NULL;
422 list_add(&jinode->i_list,
423 &jinode->i_transaction->t_inode_list);
424 } else {
425 jinode->i_transaction = NULL;
426 }
427 }
428 spin_unlock(&journal->j_list_lock);
429
430 return ret;
431}
432
358static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) 433static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh)
359{ 434{
360 struct page *page = bh->b_page; 435 struct page *page = bh->b_page;
@@ -529,6 +604,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
529 */ 604 */
530 err = 0; 605 err = 0;
531 journal_submit_data_buffers(journal, commit_transaction); 606 journal_submit_data_buffers(journal, commit_transaction);
607 err = journal_submit_inode_data_buffers(journal, commit_transaction);
608 if (err)
609 jbd2_journal_abort(journal, err);
532 610
533 /* 611 /*
534 * Wait for all previously submitted IO to complete if commit 612 * Wait for all previously submitted IO to complete if commit
@@ -760,6 +838,17 @@ start_journal_io:
760 __jbd2_journal_abort_hard(journal); 838 __jbd2_journal_abort_hard(journal);
761 } 839 }
762 840
841 /*
842 * This is the right place to wait for data buffers both for ASYNC
843 * and !ASYNC commit. If commit is ASYNC, we need to wait only after
844 * the commit block went to disk (which happens above). If commit is
845 * SYNC, we need to wait for data buffers before we start writing
846 * commit block, which happens below in such setting.
847 */
848 err = journal_finish_inode_data_buffers(journal, commit_transaction);
849 if (err)
850 jbd2_journal_abort(journal, err);
851
763 /* Lo and behold: we have just managed to send a transaction to 852 /* Lo and behold: we have just managed to send a transaction to
764 the log. Before we can commit it, wait for the IO so far to 853 the log. Before we can commit it, wait for the IO so far to
765 complete. Control buffers being written are on the 854 complete. Control buffers being written are on the
@@ -880,6 +969,7 @@ wait_for_iobuf:
880 jbd_debug(3, "JBD: commit phase 7\n"); 969 jbd_debug(3, "JBD: commit phase 7\n");
881 970
882 J_ASSERT(commit_transaction->t_sync_datalist == NULL); 971 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
972 J_ASSERT(list_empty(&commit_transaction->t_inode_list));
883 J_ASSERT(commit_transaction->t_buffers == NULL); 973 J_ASSERT(commit_transaction->t_buffers == NULL);
884 J_ASSERT(commit_transaction->t_checkpoint_list == NULL); 974 J_ASSERT(commit_transaction->t_checkpoint_list == NULL);
885 J_ASSERT(commit_transaction->t_iobuf_list == NULL); 975 J_ASSERT(commit_transaction->t_iobuf_list == NULL);