diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index f3ad1598b201..7f21cf3aaf92 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -105,6 +105,8 @@ static int journal_submit_commit_record(journal_t *journal, | |||
105 | int ret; | 105 | int ret; |
106 | struct timespec now = current_kernel_time(); | 106 | struct timespec now = current_kernel_time(); |
107 | 107 | ||
108 | *cbh = NULL; | ||
109 | |||
108 | if (is_journal_aborted(journal)) | 110 | if (is_journal_aborted(journal)) |
109 | return 0; | 111 | return 0; |
110 | 112 | ||
@@ -137,9 +139,9 @@ static int journal_submit_commit_record(journal_t *journal, | |||
137 | if (journal->j_flags & JBD2_BARRIER && | 139 | if (journal->j_flags & JBD2_BARRIER && |
138 | !JBD2_HAS_INCOMPAT_FEATURE(journal, | 140 | !JBD2_HAS_INCOMPAT_FEATURE(journal, |
139 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) | 141 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) |
140 | ret = submit_bh(WRITE_SYNC_PLUG | WRITE_FLUSH_FUA, bh); | 142 | ret = submit_bh(WRITE_SYNC | WRITE_FLUSH_FUA, bh); |
141 | else | 143 | else |
142 | ret = submit_bh(WRITE_SYNC_PLUG, bh); | 144 | ret = submit_bh(WRITE_SYNC, bh); |
143 | 145 | ||
144 | *cbh = bh; | 146 | *cbh = bh; |
145 | return ret; | 147 | return ret; |
@@ -217,7 +219,6 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
217 | ret = err; | 219 | ret = err; |
218 | spin_lock(&journal->j_list_lock); | 220 | spin_lock(&journal->j_list_lock); |
219 | J_ASSERT(jinode->i_transaction == commit_transaction); | 221 | J_ASSERT(jinode->i_transaction == commit_transaction); |
220 | commit_transaction->t_flushed_data_blocks = 1; | ||
221 | clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); | 222 | clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); |
222 | smp_mb__after_clear_bit(); | 223 | smp_mb__after_clear_bit(); |
223 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); | 224 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); |
@@ -329,19 +330,13 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
329 | int tag_bytes = journal_tag_bytes(journal); | 330 | int tag_bytes = journal_tag_bytes(journal); |
330 | struct buffer_head *cbh = NULL; /* For transactional checksums */ | 331 | struct buffer_head *cbh = NULL; /* For transactional checksums */ |
331 | __u32 crc32_sum = ~0; | 332 | __u32 crc32_sum = ~0; |
332 | int write_op = WRITE_SYNC; | 333 | struct blk_plug plug; |
333 | 334 | ||
334 | /* | 335 | /* |
335 | * First job: lock down the current transaction and wait for | 336 | * First job: lock down the current transaction and wait for |
336 | * all outstanding updates to complete. | 337 | * all outstanding updates to complete. |
337 | */ | 338 | */ |
338 | 339 | ||
339 | #ifdef COMMIT_STATS | ||
340 | spin_lock(&journal->j_list_lock); | ||
341 | summarise_journal_usage(journal); | ||
342 | spin_unlock(&journal->j_list_lock); | ||
343 | #endif | ||
344 | |||
345 | /* Do we need to erase the effects of a prior jbd2_journal_flush? */ | 340 | /* Do we need to erase the effects of a prior jbd2_journal_flush? */ |
346 | if (journal->j_flags & JBD2_FLUSHED) { | 341 | if (journal->j_flags & JBD2_FLUSHED) { |
347 | jbd_debug(3, "super block updated\n"); | 342 | jbd_debug(3, "super block updated\n"); |
@@ -363,13 +358,6 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
363 | write_lock(&journal->j_state_lock); | 358 | write_lock(&journal->j_state_lock); |
364 | commit_transaction->t_state = T_LOCKED; | 359 | commit_transaction->t_state = T_LOCKED; |
365 | 360 | ||
366 | /* | ||
367 | * Use plugged writes here, since we want to submit several before | ||
368 | * we unplug the device. We don't do explicit unplugging in here, | ||
369 | * instead we rely on sync_buffer() doing the unplug for us. | ||
370 | */ | ||
371 | if (commit_transaction->t_synchronous_commit) | ||
372 | write_op = WRITE_SYNC_PLUG; | ||
373 | trace_jbd2_commit_locking(journal, commit_transaction); | 361 | trace_jbd2_commit_locking(journal, commit_transaction); |
374 | stats.run.rs_wait = commit_transaction->t_max_wait; | 362 | stats.run.rs_wait = commit_transaction->t_max_wait; |
375 | stats.run.rs_locked = jiffies; | 363 | stats.run.rs_locked = jiffies; |
@@ -410,7 +398,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
410 | * we do not require it to remember exactly which old buffers it | 398 | * we do not require it to remember exactly which old buffers it |
411 | * has reserved. This is consistent with the existing behaviour | 399 | * has reserved. This is consistent with the existing behaviour |
412 | * that multiple jbd2_journal_get_write_access() calls to the same | 400 | * that multiple jbd2_journal_get_write_access() calls to the same |
413 | * buffer are perfectly permissable. | 401 | * buffer are perfectly permissible. |
414 | */ | 402 | */ |
415 | while (commit_transaction->t_reserved_list) { | 403 | while (commit_transaction->t_reserved_list) { |
416 | jh = commit_transaction->t_reserved_list; | 404 | jh = commit_transaction->t_reserved_list; |
@@ -469,8 +457,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
469 | if (err) | 457 | if (err) |
470 | jbd2_journal_abort(journal, err); | 458 | jbd2_journal_abort(journal, err); |
471 | 459 | ||
460 | blk_start_plug(&plug); | ||
472 | jbd2_journal_write_revoke_records(journal, commit_transaction, | 461 | jbd2_journal_write_revoke_records(journal, commit_transaction, |
473 | write_op); | 462 | WRITE_SYNC); |
463 | blk_finish_plug(&plug); | ||
474 | 464 | ||
475 | jbd_debug(3, "JBD: commit phase 2\n"); | 465 | jbd_debug(3, "JBD: commit phase 2\n"); |
476 | 466 | ||
@@ -497,6 +487,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
497 | err = 0; | 487 | err = 0; |
498 | descriptor = NULL; | 488 | descriptor = NULL; |
499 | bufs = 0; | 489 | bufs = 0; |
490 | blk_start_plug(&plug); | ||
500 | while (commit_transaction->t_buffers) { | 491 | while (commit_transaction->t_buffers) { |
501 | 492 | ||
502 | /* Find the next buffer to be journaled... */ | 493 | /* Find the next buffer to be journaled... */ |
@@ -658,7 +649,7 @@ start_journal_io: | |||
658 | clear_buffer_dirty(bh); | 649 | clear_buffer_dirty(bh); |
659 | set_buffer_uptodate(bh); | 650 | set_buffer_uptodate(bh); |
660 | bh->b_end_io = journal_end_buffer_io_sync; | 651 | bh->b_end_io = journal_end_buffer_io_sync; |
661 | submit_bh(write_op, bh); | 652 | submit_bh(WRITE_SYNC, bh); |
662 | } | 653 | } |
663 | cond_resched(); | 654 | cond_resched(); |
664 | stats.run.rs_blocks_logged += bufs; | 655 | stats.run.rs_blocks_logged += bufs; |
@@ -680,12 +671,16 @@ start_journal_io: | |||
680 | err = 0; | 671 | err = 0; |
681 | } | 672 | } |
682 | 673 | ||
674 | write_lock(&journal->j_state_lock); | ||
675 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | ||
676 | commit_transaction->t_state = T_COMMIT_DFLUSH; | ||
677 | write_unlock(&journal->j_state_lock); | ||
683 | /* | 678 | /* |
684 | * If the journal is not located on the file system device, | 679 | * If the journal is not located on the file system device, |
685 | * then we must flush the file system device before we issue | 680 | * then we must flush the file system device before we issue |
686 | * the commit record | 681 | * the commit record |
687 | */ | 682 | */ |
688 | if (commit_transaction->t_flushed_data_blocks && | 683 | if (commit_transaction->t_need_data_flush && |
689 | (journal->j_fs_dev != journal->j_dev) && | 684 | (journal->j_fs_dev != journal->j_dev) && |
690 | (journal->j_flags & JBD2_BARRIER)) | 685 | (journal->j_flags & JBD2_BARRIER)) |
691 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); | 686 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); |
@@ -699,6 +694,8 @@ start_journal_io: | |||
699 | __jbd2_journal_abort_hard(journal); | 694 | __jbd2_journal_abort_hard(journal); |
700 | } | 695 | } |
701 | 696 | ||
697 | blk_finish_plug(&plug); | ||
698 | |||
702 | /* Lo and behold: we have just managed to send a transaction to | 699 | /* Lo and behold: we have just managed to send a transaction to |
703 | the log. Before we can commit it, wait for the IO so far to | 700 | the log. Before we can commit it, wait for the IO so far to |
704 | complete. Control buffers being written are on the | 701 | complete. Control buffers being written are on the |
@@ -760,8 +757,13 @@ wait_for_iobuf: | |||
760 | required. */ | 757 | required. */ |
761 | JBUFFER_TRACE(jh, "file as BJ_Forget"); | 758 | JBUFFER_TRACE(jh, "file as BJ_Forget"); |
762 | jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); | 759 | jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); |
763 | /* Wake up any transactions which were waiting for this | 760 | /* |
764 | IO to complete */ | 761 | * Wake up any transactions which were waiting for this IO to |
762 | * complete. The barrier must be here so that changes by | ||
763 | * jbd2_journal_file_buffer() take effect before wake_up_bit() | ||
764 | * does the waitqueue check. | ||
765 | */ | ||
766 | smp_mb(); | ||
765 | wake_up_bit(&bh->b_state, BH_Unshadow); | 767 | wake_up_bit(&bh->b_state, BH_Unshadow); |
766 | JBUFFER_TRACE(jh, "brelse shadowed buffer"); | 768 | JBUFFER_TRACE(jh, "brelse shadowed buffer"); |
767 | __brelse(bh); | 769 | __brelse(bh); |
@@ -800,6 +802,10 @@ wait_for_iobuf: | |||
800 | jbd2_journal_abort(journal, err); | 802 | jbd2_journal_abort(journal, err); |
801 | 803 | ||
802 | jbd_debug(3, "JBD: commit phase 5\n"); | 804 | jbd_debug(3, "JBD: commit phase 5\n"); |
805 | write_lock(&journal->j_state_lock); | ||
806 | J_ASSERT(commit_transaction->t_state == T_COMMIT_DFLUSH); | ||
807 | commit_transaction->t_state = T_COMMIT_JFLUSH; | ||
808 | write_unlock(&journal->j_state_lock); | ||
803 | 809 | ||
804 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, | 810 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, |
805 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 811 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
@@ -808,7 +814,7 @@ wait_for_iobuf: | |||
808 | if (err) | 814 | if (err) |
809 | __jbd2_journal_abort_hard(journal); | 815 | __jbd2_journal_abort_hard(journal); |
810 | } | 816 | } |
811 | if (!err && !is_journal_aborted(journal)) | 817 | if (cbh) |
812 | err = journal_wait_on_commit_record(journal, cbh); | 818 | err = journal_wait_on_commit_record(journal, cbh); |
813 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, | 819 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, |
814 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) && | 820 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) && |
@@ -955,7 +961,7 @@ restart_loop: | |||
955 | 961 | ||
956 | jbd_debug(3, "JBD: commit phase 7\n"); | 962 | jbd_debug(3, "JBD: commit phase 7\n"); |
957 | 963 | ||
958 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 964 | J_ASSERT(commit_transaction->t_state == T_COMMIT_JFLUSH); |
959 | 965 | ||
960 | commit_transaction->t_start = jiffies; | 966 | commit_transaction->t_start = jiffies; |
961 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, | 967 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, |