diff options
Diffstat (limited to 'fs/jbd/commit.c')
| -rw-r--r-- | fs/jbd/commit.c | 60 |
1 files changed, 21 insertions, 39 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 4bd882548c45..34a4861c14b8 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 18 | #include <linux/jbd.h> | 18 | #include <linux/jbd.h> |
| 19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
| 22 | #include <linux/pagemap.h> | 21 | #include <linux/pagemap.h> |
| 23 | #include <linux/bio.h> | 22 | #include <linux/bio.h> |
| @@ -120,7 +119,6 @@ static int journal_write_commit_record(journal_t *journal, | |||
| 120 | struct buffer_head *bh; | 119 | struct buffer_head *bh; |
| 121 | journal_header_t *header; | 120 | journal_header_t *header; |
| 122 | int ret; | 121 | int ret; |
| 123 | int barrier_done = 0; | ||
| 124 | 122 | ||
| 125 | if (is_journal_aborted(journal)) | 123 | if (is_journal_aborted(journal)) |
| 126 | return 0; | 124 | return 0; |
| @@ -138,34 +136,12 @@ static int journal_write_commit_record(journal_t *journal, | |||
| 138 | 136 | ||
| 139 | JBUFFER_TRACE(descriptor, "write commit block"); | 137 | JBUFFER_TRACE(descriptor, "write commit block"); |
| 140 | set_buffer_dirty(bh); | 138 | set_buffer_dirty(bh); |
| 141 | if (journal->j_flags & JFS_BARRIER) { | ||
| 142 | set_buffer_ordered(bh); | ||
| 143 | barrier_done = 1; | ||
| 144 | } | ||
| 145 | ret = sync_dirty_buffer(bh); | ||
| 146 | if (barrier_done) | ||
| 147 | clear_buffer_ordered(bh); | ||
| 148 | /* is it possible for another commit to fail at roughly | ||
| 149 | * the same time as this one? If so, we don't want to | ||
| 150 | * trust the barrier flag in the super, but instead want | ||
| 151 | * to remember if we sent a barrier request | ||
| 152 | */ | ||
| 153 | if (ret == -EOPNOTSUPP && barrier_done) { | ||
| 154 | char b[BDEVNAME_SIZE]; | ||
| 155 | |||
| 156 | printk(KERN_WARNING | ||
| 157 | "JBD: barrier-based sync failed on %s - " | ||
| 158 | "disabling barriers\n", | ||
| 159 | bdevname(journal->j_dev, b)); | ||
| 160 | spin_lock(&journal->j_state_lock); | ||
| 161 | journal->j_flags &= ~JFS_BARRIER; | ||
| 162 | spin_unlock(&journal->j_state_lock); | ||
| 163 | 139 | ||
| 164 | /* And try again, without the barrier */ | 140 | if (journal->j_flags & JFS_BARRIER) |
| 165 | set_buffer_uptodate(bh); | 141 | ret = __sync_dirty_buffer(bh, WRITE_SYNC | WRITE_FLUSH_FUA); |
| 166 | set_buffer_dirty(bh); | 142 | else |
| 167 | ret = sync_dirty_buffer(bh); | 143 | ret = sync_dirty_buffer(bh); |
| 168 | } | 144 | |
| 169 | put_bh(bh); /* One for getblk() */ | 145 | put_bh(bh); /* One for getblk() */ |
| 170 | journal_put_journal_head(descriptor); | 146 | journal_put_journal_head(descriptor); |
| 171 | 147 | ||
| @@ -318,7 +294,7 @@ void journal_commit_transaction(journal_t *journal) | |||
| 318 | int first_tag = 0; | 294 | int first_tag = 0; |
| 319 | int tag_flag; | 295 | int tag_flag; |
| 320 | int i; | 296 | int i; |
| 321 | int write_op = WRITE; | 297 | int write_op = WRITE_SYNC; |
| 322 | 298 | ||
| 323 | /* | 299 | /* |
| 324 | * First job: lock down the current transaction and wait for | 300 | * First job: lock down the current transaction and wait for |
| @@ -611,13 +587,13 @@ void journal_commit_transaction(journal_t *journal) | |||
| 611 | /* Bump b_count to prevent truncate from stumbling over | 587 | /* Bump b_count to prevent truncate from stumbling over |
| 612 | the shadowed buffer! @@@ This can go if we ever get | 588 | the shadowed buffer! @@@ This can go if we ever get |
| 613 | rid of the BJ_IO/BJ_Shadow pairing of buffers. */ | 589 | rid of the BJ_IO/BJ_Shadow pairing of buffers. */ |
| 614 | atomic_inc(&jh2bh(jh)->b_count); | 590 | get_bh(jh2bh(jh)); |
| 615 | 591 | ||
| 616 | /* Make a temporary IO buffer with which to write it out | 592 | /* Make a temporary IO buffer with which to write it out |
| 617 | (this will requeue both the metadata buffer and the | 593 | (this will requeue both the metadata buffer and the |
| 618 | temporary IO buffer). new_bh goes on BJ_IO*/ | 594 | temporary IO buffer). new_bh goes on BJ_IO*/ |
| 619 | 595 | ||
| 620 | set_bit(BH_JWrite, &jh2bh(jh)->b_state); | 596 | set_buffer_jwrite(jh2bh(jh)); |
| 621 | /* | 597 | /* |
| 622 | * akpm: journal_write_metadata_buffer() sets | 598 | * akpm: journal_write_metadata_buffer() sets |
| 623 | * new_bh->b_transaction to commit_transaction. | 599 | * new_bh->b_transaction to commit_transaction. |
| @@ -627,7 +603,7 @@ void journal_commit_transaction(journal_t *journal) | |||
| 627 | JBUFFER_TRACE(jh, "ph3: write metadata"); | 603 | JBUFFER_TRACE(jh, "ph3: write metadata"); |
| 628 | flags = journal_write_metadata_buffer(commit_transaction, | 604 | flags = journal_write_metadata_buffer(commit_transaction, |
| 629 | jh, &new_jh, blocknr); | 605 | jh, &new_jh, blocknr); |
| 630 | set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); | 606 | set_buffer_jwrite(jh2bh(new_jh)); |
| 631 | wbuf[bufs++] = jh2bh(new_jh); | 607 | wbuf[bufs++] = jh2bh(new_jh); |
| 632 | 608 | ||
| 633 | /* Record the new block's tag in the current descriptor | 609 | /* Record the new block's tag in the current descriptor |
| @@ -737,7 +713,7 @@ wait_for_iobuf: | |||
| 737 | shadowed buffer */ | 713 | shadowed buffer */ |
| 738 | jh = commit_transaction->t_shadow_list->b_tprev; | 714 | jh = commit_transaction->t_shadow_list->b_tprev; |
| 739 | bh = jh2bh(jh); | 715 | bh = jh2bh(jh); |
| 740 | clear_bit(BH_JWrite, &bh->b_state); | 716 | clear_buffer_jwrite(bh); |
| 741 | J_ASSERT_BH(bh, buffer_jbddirty(bh)); | 717 | J_ASSERT_BH(bh, buffer_jbddirty(bh)); |
| 742 | 718 | ||
| 743 | /* The metadata is now released for reuse, but we need | 719 | /* The metadata is now released for reuse, but we need |
| @@ -787,6 +763,12 @@ wait_for_iobuf: | |||
| 787 | 763 | ||
| 788 | jbd_debug(3, "JBD: commit phase 6\n"); | 764 | jbd_debug(3, "JBD: commit phase 6\n"); |
| 789 | 765 | ||
| 766 | /* All metadata is written, now write commit record and do cleanup */ | ||
| 767 | spin_lock(&journal->j_state_lock); | ||
| 768 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | ||
| 769 | commit_transaction->t_state = T_COMMIT_RECORD; | ||
| 770 | spin_unlock(&journal->j_state_lock); | ||
| 771 | |||
| 790 | if (journal_write_commit_record(journal, commit_transaction)) | 772 | if (journal_write_commit_record(journal, commit_transaction)) |
| 791 | err = -EIO; | 773 | err = -EIO; |
| 792 | 774 | ||
| @@ -862,12 +844,12 @@ restart_loop: | |||
| 862 | /* A buffer which has been freed while still being | 844 | /* A buffer which has been freed while still being |
| 863 | * journaled by a previous transaction may end up still | 845 | * journaled by a previous transaction may end up still |
| 864 | * being dirty here, but we want to avoid writing back | 846 | * being dirty here, but we want to avoid writing back |
| 865 | * that buffer in the future now that the last use has | 847 | * that buffer in the future after the "add to orphan" |
| 866 | * been committed. That's not only a performance gain, | 848 | * operation been committed, That's not only a performance |
| 867 | * it also stops aliasing problems if the buffer is left | 849 | * gain, it also stops aliasing problems if the buffer is |
| 868 | * behind for writeback and gets reallocated for another | 850 | * left behind for writeback and gets reallocated for another |
| 869 | * use in a different page. */ | 851 | * use in a different page. */ |
| 870 | if (buffer_freed(bh)) { | 852 | if (buffer_freed(bh) && !jh->b_next_transaction) { |
| 871 | clear_buffer_freed(bh); | 853 | clear_buffer_freed(bh); |
| 872 | clear_buffer_jbddirty(bh); | 854 | clear_buffer_jbddirty(bh); |
| 873 | } | 855 | } |
| @@ -924,7 +906,7 @@ restart_loop: | |||
| 924 | 906 | ||
| 925 | jbd_debug(3, "JBD: commit phase 8\n"); | 907 | jbd_debug(3, "JBD: commit phase 8\n"); |
| 926 | 908 | ||
| 927 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 909 | J_ASSERT(commit_transaction->t_state == T_COMMIT_RECORD); |
| 928 | 910 | ||
| 929 | commit_transaction->t_state = T_FINISHED; | 911 | commit_transaction->t_state = T_FINISHED; |
| 930 | J_ASSERT(commit_transaction == journal->j_committing_transaction); | 912 | J_ASSERT(commit_transaction == journal->j_committing_transaction); |
