diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-26 12:53:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-26 12:53:20 -0400 |
commit | 35806b4f7c5620b547f183e9d53f7cfaeabb582b (patch) | |
tree | dc966f5edd9e482fdc85b8fb886ae39ce5c5ec80 /fs/jbd2 | |
parent | 32e51f141fd8d880f57b6a2eb53ce72856254d4a (diff) | |
parent | d183e11a4a66d80e10d60b0918a47cf073135379 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (61 commits)
jbd2: Add MAINTAINERS entry
jbd2: fix a potential leak of a journal_head on an error path
ext4: teach ext4_ext_split to calculate extents efficiently
ext4: Convert ext4 to new truncate calling convention
ext4: do not normalize block requests from fallocate()
ext4: enable "punch hole" functionality
ext4: add "punch hole" flag to ext4_map_blocks()
ext4: punch out extents
ext4: add new function ext4_block_zero_page_range()
ext4: add flag to ext4_has_free_blocks
ext4: reserve inodes and feature code for 'quota' feature
ext4: add support for multiple mount protection
ext4: ensure f_bfree returned by ext4_statfs() is non-negative
ext4: protect bb_first_free in ext4_trim_all_free() with group lock
ext4: only load buddy bitmap in ext4_trim_fs() when it is needed
jbd2: Fix comment to match the code in jbd2__journal_start()
ext4: fix waiting and sending of a barrier in ext4_sync_file()
jbd2: Add function jbd2_trans_will_send_data_barrier()
jbd2: fix sending of data flush on journal commit
ext4: fix ext4_ext_fiemap_cb() to handle blocks before request range correctly
...
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/commit.c | 22 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 58 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 22 |
3 files changed, 87 insertions, 15 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 29148a81c783..7f21cf3aaf92 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -219,7 +219,6 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
219 | ret = err; | 219 | ret = err; |
220 | spin_lock(&journal->j_list_lock); | 220 | spin_lock(&journal->j_list_lock); |
221 | J_ASSERT(jinode->i_transaction == commit_transaction); | 221 | J_ASSERT(jinode->i_transaction == commit_transaction); |
222 | commit_transaction->t_flushed_data_blocks = 1; | ||
223 | clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); | 222 | clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); |
224 | smp_mb__after_clear_bit(); | 223 | smp_mb__after_clear_bit(); |
225 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); | 224 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); |
@@ -672,12 +671,16 @@ start_journal_io: | |||
672 | err = 0; | 671 | err = 0; |
673 | } | 672 | } |
674 | 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); | ||
675 | /* | 678 | /* |
676 | * If the journal is not located on the file system device, | 679 | * If the journal is not located on the file system device, |
677 | * then we must flush the file system device before we issue | 680 | * then we must flush the file system device before we issue |
678 | * the commit record | 681 | * the commit record |
679 | */ | 682 | */ |
680 | if (commit_transaction->t_flushed_data_blocks && | 683 | if (commit_transaction->t_need_data_flush && |
681 | (journal->j_fs_dev != journal->j_dev) && | 684 | (journal->j_fs_dev != journal->j_dev) && |
682 | (journal->j_flags & JBD2_BARRIER)) | 685 | (journal->j_flags & JBD2_BARRIER)) |
683 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); | 686 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); |
@@ -754,8 +757,13 @@ wait_for_iobuf: | |||
754 | required. */ | 757 | required. */ |
755 | JBUFFER_TRACE(jh, "file as BJ_Forget"); | 758 | JBUFFER_TRACE(jh, "file as BJ_Forget"); |
756 | jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); | 759 | jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); |
757 | /* Wake up any transactions which were waiting for this | 760 | /* |
758 | 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(); | ||
759 | wake_up_bit(&bh->b_state, BH_Unshadow); | 767 | wake_up_bit(&bh->b_state, BH_Unshadow); |
760 | JBUFFER_TRACE(jh, "brelse shadowed buffer"); | 768 | JBUFFER_TRACE(jh, "brelse shadowed buffer"); |
761 | __brelse(bh); | 769 | __brelse(bh); |
@@ -794,6 +802,10 @@ wait_for_iobuf: | |||
794 | jbd2_journal_abort(journal, err); | 802 | jbd2_journal_abort(journal, err); |
795 | 803 | ||
796 | 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); | ||
797 | 809 | ||
798 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, | 810 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, |
799 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 811 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
@@ -949,7 +961,7 @@ restart_loop: | |||
949 | 961 | ||
950 | jbd_debug(3, "JBD: commit phase 7\n"); | 962 | jbd_debug(3, "JBD: commit phase 7\n"); |
951 | 963 | ||
952 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 964 | J_ASSERT(commit_transaction->t_state == T_COMMIT_JFLUSH); |
953 | 965 | ||
954 | commit_transaction->t_start = jiffies; | 966 | commit_transaction->t_start = jiffies; |
955 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, | 967 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index e0ec3db1c395..9a7826990304 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -479,9 +479,12 @@ int __jbd2_log_space_left(journal_t *journal) | |||
479 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) | 479 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) |
480 | { | 480 | { |
481 | /* | 481 | /* |
482 | * Are we already doing a recent enough commit? | 482 | * The only transaction we can possibly wait upon is the |
483 | * currently running transaction (if it exists). Otherwise, | ||
484 | * the target tid must be an old one. | ||
483 | */ | 485 | */ |
484 | if (!tid_geq(journal->j_commit_request, target)) { | 486 | if (journal->j_running_transaction && |
487 | journal->j_running_transaction->t_tid == target) { | ||
485 | /* | 488 | /* |
486 | * We want a new commit: OK, mark the request and wakeup the | 489 | * We want a new commit: OK, mark the request and wakeup the |
487 | * commit thread. We do _not_ do the commit ourselves. | 490 | * commit thread. We do _not_ do the commit ourselves. |
@@ -493,7 +496,15 @@ int __jbd2_log_start_commit(journal_t *journal, tid_t target) | |||
493 | journal->j_commit_sequence); | 496 | journal->j_commit_sequence); |
494 | wake_up(&journal->j_wait_commit); | 497 | wake_up(&journal->j_wait_commit); |
495 | return 1; | 498 | return 1; |
496 | } | 499 | } else if (!tid_geq(journal->j_commit_request, target)) |
500 | /* This should never happen, but if it does, preserve | ||
501 | the evidence before kjournald goes into a loop and | ||
502 | increments j_commit_sequence beyond all recognition. */ | ||
503 | WARN_ONCE(1, "jbd: bad log_start_commit: %u %u %u %u\n", | ||
504 | journal->j_commit_request, | ||
505 | journal->j_commit_sequence, | ||
506 | target, journal->j_running_transaction ? | ||
507 | journal->j_running_transaction->t_tid : 0); | ||
497 | return 0; | 508 | return 0; |
498 | } | 509 | } |
499 | 510 | ||
@@ -577,6 +588,47 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) | |||
577 | } | 588 | } |
578 | 589 | ||
579 | /* | 590 | /* |
591 | * Return 1 if a given transaction has not yet sent barrier request | ||
592 | * connected with a transaction commit. If 0 is returned, transaction | ||
593 | * may or may not have sent the barrier. Used to avoid sending barrier | ||
594 | * twice in common cases. | ||
595 | */ | ||
596 | int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid) | ||
597 | { | ||
598 | int ret = 0; | ||
599 | transaction_t *commit_trans; | ||
600 | |||
601 | if (!(journal->j_flags & JBD2_BARRIER)) | ||
602 | return 0; | ||
603 | read_lock(&journal->j_state_lock); | ||
604 | /* Transaction already committed? */ | ||
605 | if (tid_geq(journal->j_commit_sequence, tid)) | ||
606 | goto out; | ||
607 | commit_trans = journal->j_committing_transaction; | ||
608 | if (!commit_trans || commit_trans->t_tid != tid) { | ||
609 | ret = 1; | ||
610 | goto out; | ||
611 | } | ||
612 | /* | ||
613 | * Transaction is being committed and we already proceeded to | ||
614 | * submitting a flush to fs partition? | ||
615 | */ | ||
616 | if (journal->j_fs_dev != journal->j_dev) { | ||
617 | if (!commit_trans->t_need_data_flush || | ||
618 | commit_trans->t_state >= T_COMMIT_DFLUSH) | ||
619 | goto out; | ||
620 | } else { | ||
621 | if (commit_trans->t_state >= T_COMMIT_JFLUSH) | ||
622 | goto out; | ||
623 | } | ||
624 | ret = 1; | ||
625 | out: | ||
626 | read_unlock(&journal->j_state_lock); | ||
627 | return ret; | ||
628 | } | ||
629 | EXPORT_SYMBOL(jbd2_trans_will_send_data_barrier); | ||
630 | |||
631 | /* | ||
580 | * Wait for a specified commit to complete. | 632 | * Wait for a specified commit to complete. |
581 | * The caller may not hold the journal lock. | 633 | * The caller may not hold the journal lock. |
582 | */ | 634 | */ |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 05fa77a23711..3eec82d32fd4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -82,7 +82,7 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) | |||
82 | */ | 82 | */ |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Update transiaction's maximum wait time, if debugging is enabled. | 85 | * Update transaction's maximum wait time, if debugging is enabled. |
86 | * | 86 | * |
87 | * In order for t_max_wait to be reliable, it must be protected by a | 87 | * In order for t_max_wait to be reliable, it must be protected by a |
88 | * lock. But doing so will mean that start_this_handle() can not be | 88 | * lock. But doing so will mean that start_this_handle() can not be |
@@ -91,11 +91,10 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) | |||
91 | * means that maximum wait time reported by the jbd2_run_stats | 91 | * means that maximum wait time reported by the jbd2_run_stats |
92 | * tracepoint will always be zero. | 92 | * tracepoint will always be zero. |
93 | */ | 93 | */ |
94 | static inline void update_t_max_wait(transaction_t *transaction) | 94 | static inline void update_t_max_wait(transaction_t *transaction, |
95 | unsigned long ts) | ||
95 | { | 96 | { |
96 | #ifdef CONFIG_JBD2_DEBUG | 97 | #ifdef CONFIG_JBD2_DEBUG |
97 | unsigned long ts = jiffies; | ||
98 | |||
99 | if (jbd2_journal_enable_debug && | 98 | if (jbd2_journal_enable_debug && |
100 | time_after(transaction->t_start, ts)) { | 99 | time_after(transaction->t_start, ts)) { |
101 | ts = jbd2_time_diff(ts, transaction->t_start); | 100 | ts = jbd2_time_diff(ts, transaction->t_start); |
@@ -121,6 +120,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle, | |||
121 | tid_t tid; | 120 | tid_t tid; |
122 | int needed, need_to_start; | 121 | int needed, need_to_start; |
123 | int nblocks = handle->h_buffer_credits; | 122 | int nblocks = handle->h_buffer_credits; |
123 | unsigned long ts = jiffies; | ||
124 | 124 | ||
125 | if (nblocks > journal->j_max_transaction_buffers) { | 125 | if (nblocks > journal->j_max_transaction_buffers) { |
126 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", | 126 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", |
@@ -271,7 +271,7 @@ repeat: | |||
271 | /* OK, account for the buffers that this operation expects to | 271 | /* OK, account for the buffers that this operation expects to |
272 | * use and add the handle to the running transaction. | 272 | * use and add the handle to the running transaction. |
273 | */ | 273 | */ |
274 | update_t_max_wait(transaction); | 274 | update_t_max_wait(transaction, ts); |
275 | handle->h_transaction = transaction; | 275 | handle->h_transaction = transaction; |
276 | atomic_inc(&transaction->t_updates); | 276 | atomic_inc(&transaction->t_updates); |
277 | atomic_inc(&transaction->t_handle_count); | 277 | atomic_inc(&transaction->t_handle_count); |
@@ -316,7 +316,8 @@ static handle_t *new_handle(int nblocks) | |||
316 | * This function is visible to journal users (like ext3fs), so is not | 316 | * This function is visible to journal users (like ext3fs), so is not |
317 | * called with the journal already locked. | 317 | * called with the journal already locked. |
318 | * | 318 | * |
319 | * Return a pointer to a newly allocated handle, or NULL on failure | 319 | * Return a pointer to a newly allocated handle, or an ERR_PTR() value |
320 | * on failure. | ||
320 | */ | 321 | */ |
321 | handle_t *jbd2__journal_start(journal_t *journal, int nblocks, int gfp_mask) | 322 | handle_t *jbd2__journal_start(journal_t *journal, int nblocks, int gfp_mask) |
322 | { | 323 | { |
@@ -921,8 +922,8 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) | |||
921 | */ | 922 | */ |
922 | JBUFFER_TRACE(jh, "cancelling revoke"); | 923 | JBUFFER_TRACE(jh, "cancelling revoke"); |
923 | jbd2_journal_cancel_revoke(handle, jh); | 924 | jbd2_journal_cancel_revoke(handle, jh); |
924 | jbd2_journal_put_journal_head(jh); | ||
925 | out: | 925 | out: |
926 | jbd2_journal_put_journal_head(jh); | ||
926 | return err; | 927 | return err; |
927 | } | 928 | } |
928 | 929 | ||
@@ -2147,6 +2148,13 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) | |||
2147 | jinode->i_next_transaction == transaction) | 2148 | jinode->i_next_transaction == transaction) |
2148 | goto done; | 2149 | goto done; |
2149 | 2150 | ||
2151 | /* | ||
2152 | * We only ever set this variable to 1 so the test is safe. Since | ||
2153 | * t_need_data_flush is likely to be set, we do the test to save some | ||
2154 | * cacheline bouncing | ||
2155 | */ | ||
2156 | if (!transaction->t_need_data_flush) | ||
2157 | transaction->t_need_data_flush = 1; | ||
2150 | /* On some different transaction's list - should be | 2158 | /* On some different transaction's list - should be |
2151 | * the committing one */ | 2159 | * the committing one */ |
2152 | if (jinode->i_transaction) { | 2160 | if (jinode->i_transaction) { |