aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 11:04:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 11:04:12 -0400
commit149b306089b88e186942a8d6647028ae6683aaf9 (patch)
tree1b7436034261947bae3efad41c55a91a8ef0f68d /fs/jbd2
parentb0ca4d0123608cfec73fc689c74295da89fc934e (diff)
parent0d606e2c9fccdd4e67febf1e2da500e1bfe9e045 (diff)
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "Mostly performance and bug fixes, plus some cleanups. The one new feature this merge window is a new ioctl EXT4_IOC_SWAP_BOOT which allows installation of a hidden inode designed for boot loaders." * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (50 commits) ext4: fix type-widening bug in inode table readahead code ext4: add check for inodes_count overflow in new resize ioctl ext4: fix Kconfig documentation for CONFIG_EXT4_DEBUG ext4: fix online resizing for ext3-compat file systems jbd2: trace when lock_buffer in do_get_write_access takes a long time ext4: mark metadata blocks using bh flags buffer: add BH_Prio and BH_Meta flags ext4: mark all metadata I/O with REQ_META ext4: fix readdir error in case inline_data+^dir_index. ext4: fix readdir error in the case of inline_data+dir_index jbd2: use kmem_cache_zalloc instead of kmem_cache_alloc/memset ext4: mext_insert_extents should update extent block checksum ext4: move quota initialization out of inode allocation transaction ext4: reserve xattr index for Rich ACL support jbd2: reduce journal_head size ext4: clear buffer_uninit flag when submitting IO ext4: use io_end for multiple bios ext4: make ext4_bio_write_page() use BH_Async_Write flags ext4: Use kstrtoul() instead of parse_strtoul() ext4: defragmentation code cleanup ...
Diffstat (limited to 'fs/jbd2')
-rw-r--r--fs/jbd2/commit.c50
-rw-r--r--fs/jbd2/journal.c31
-rw-r--r--fs/jbd2/transaction.c9
3 files changed, 67 insertions, 23 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 750c70148eff..0f53946f13c1 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -382,7 +382,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
382 int space_left = 0; 382 int space_left = 0;
383 int first_tag = 0; 383 int first_tag = 0;
384 int tag_flag; 384 int tag_flag;
385 int i, to_free = 0; 385 int i;
386 int tag_bytes = journal_tag_bytes(journal); 386 int tag_bytes = journal_tag_bytes(journal);
387 struct buffer_head *cbh = NULL; /* For transactional checksums */ 387 struct buffer_head *cbh = NULL; /* For transactional checksums */
388 __u32 crc32_sum = ~0; 388 __u32 crc32_sum = ~0;
@@ -1134,7 +1134,7 @@ restart_loop:
1134 journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; 1134 journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
1135 spin_unlock(&journal->j_history_lock); 1135 spin_unlock(&journal->j_history_lock);
1136 1136
1137 commit_transaction->t_state = T_FINISHED; 1137 commit_transaction->t_state = T_COMMIT_CALLBACK;
1138 J_ASSERT(commit_transaction == journal->j_committing_transaction); 1138 J_ASSERT(commit_transaction == journal->j_committing_transaction);
1139 journal->j_commit_sequence = commit_transaction->t_tid; 1139 journal->j_commit_sequence = commit_transaction->t_tid;
1140 journal->j_committing_transaction = NULL; 1140 journal->j_committing_transaction = NULL;
@@ -1149,38 +1149,44 @@ restart_loop:
1149 journal->j_average_commit_time*3) / 4; 1149 journal->j_average_commit_time*3) / 4;
1150 else 1150 else
1151 journal->j_average_commit_time = commit_time; 1151 journal->j_average_commit_time = commit_time;
1152
1152 write_unlock(&journal->j_state_lock); 1153 write_unlock(&journal->j_state_lock);
1153 1154
1154 if (commit_transaction->t_checkpoint_list == NULL && 1155 if (journal->j_checkpoint_transactions == NULL) {
1155 commit_transaction->t_checkpoint_io_list == NULL) { 1156 journal->j_checkpoint_transactions = commit_transaction;
1156 __jbd2_journal_drop_transaction(journal, commit_transaction); 1157 commit_transaction->t_cpnext = commit_transaction;
1157 to_free = 1; 1158 commit_transaction->t_cpprev = commit_transaction;
1158 } else { 1159 } else {
1159 if (journal->j_checkpoint_transactions == NULL) { 1160 commit_transaction->t_cpnext =
1160 journal->j_checkpoint_transactions = commit_transaction; 1161 journal->j_checkpoint_transactions;
1161 commit_transaction->t_cpnext = commit_transaction; 1162 commit_transaction->t_cpprev =
1162 commit_transaction->t_cpprev = commit_transaction; 1163 commit_transaction->t_cpnext->t_cpprev;
1163 } else { 1164 commit_transaction->t_cpnext->t_cpprev =
1164 commit_transaction->t_cpnext = 1165 commit_transaction;
1165 journal->j_checkpoint_transactions; 1166 commit_transaction->t_cpprev->t_cpnext =
1166 commit_transaction->t_cpprev =
1167 commit_transaction->t_cpnext->t_cpprev;
1168 commit_transaction->t_cpnext->t_cpprev =
1169 commit_transaction;
1170 commit_transaction->t_cpprev->t_cpnext =
1171 commit_transaction; 1167 commit_transaction;
1172 }
1173 } 1168 }
1174 spin_unlock(&journal->j_list_lock); 1169 spin_unlock(&journal->j_list_lock);
1175 1170 /* Drop all spin_locks because commit_callback may be block.
1171 * __journal_remove_checkpoint() can not destroy transaction
1172 * under us because it is not marked as T_FINISHED yet */
1176 if (journal->j_commit_callback) 1173 if (journal->j_commit_callback)
1177 journal->j_commit_callback(journal, commit_transaction); 1174 journal->j_commit_callback(journal, commit_transaction);
1178 1175
1179 trace_jbd2_end_commit(journal, commit_transaction); 1176 trace_jbd2_end_commit(journal, commit_transaction);
1180 jbd_debug(1, "JBD2: commit %d complete, head %d\n", 1177 jbd_debug(1, "JBD2: commit %d complete, head %d\n",
1181 journal->j_commit_sequence, journal->j_tail_sequence); 1178 journal->j_commit_sequence, journal->j_tail_sequence);
1182 if (to_free)
1183 jbd2_journal_free_transaction(commit_transaction);
1184 1179
1180 write_lock(&journal->j_state_lock);
1181 spin_lock(&journal->j_list_lock);
1182 commit_transaction->t_state = T_FINISHED;
1183 /* Recheck checkpoint lists after j_list_lock was dropped */
1184 if (commit_transaction->t_checkpoint_list == NULL &&
1185 commit_transaction->t_checkpoint_io_list == NULL) {
1186 __jbd2_journal_drop_transaction(journal, commit_transaction);
1187 jbd2_journal_free_transaction(commit_transaction);
1188 }
1189 spin_unlock(&journal->j_list_lock);
1190 write_unlock(&journal->j_state_lock);
1185 wake_up(&journal->j_wait_done_commit); 1191 wake_up(&journal->j_wait_done_commit);
1186} 1192}
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 8b220f1ab54f..f6c5ba027f4f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -708,6 +708,37 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
708} 708}
709 709
710/* 710/*
711 * When this function returns the transaction corresponding to tid
712 * will be completed. If the transaction has currently running, start
713 * committing that transaction before waiting for it to complete. If
714 * the transaction id is stale, it is by definition already completed,
715 * so just return SUCCESS.
716 */
717int jbd2_complete_transaction(journal_t *journal, tid_t tid)
718{
719 int need_to_wait = 1;
720
721 read_lock(&journal->j_state_lock);
722 if (journal->j_running_transaction &&
723 journal->j_running_transaction->t_tid == tid) {
724 if (journal->j_commit_request != tid) {
725 /* transaction not yet started, so request it */
726 read_unlock(&journal->j_state_lock);
727 jbd2_log_start_commit(journal, tid);
728 goto wait_commit;
729 }
730 } else if (!(journal->j_committing_transaction &&
731 journal->j_committing_transaction->t_tid == tid))
732 need_to_wait = 0;
733 read_unlock(&journal->j_state_lock);
734 if (!need_to_wait)
735 return 0;
736wait_commit:
737 return jbd2_log_wait_commit(journal, tid);
738}
739EXPORT_SYMBOL(jbd2_complete_transaction);
740
741/*
711 * Log buffer allocation routines: 742 * Log buffer allocation routines:
712 */ 743 */
713 744
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 325bc019ed88..10f524c59ea8 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -332,7 +332,6 @@ static handle_t *new_handle(int nblocks)
332 handle_t *handle = jbd2_alloc_handle(GFP_NOFS); 332 handle_t *handle = jbd2_alloc_handle(GFP_NOFS);
333 if (!handle) 333 if (!handle)
334 return NULL; 334 return NULL;
335 memset(handle, 0, sizeof(*handle));
336 handle->h_buffer_credits = nblocks; 335 handle->h_buffer_credits = nblocks;
337 handle->h_ref = 1; 336 handle->h_ref = 1;
338 337
@@ -640,6 +639,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
640 int error; 639 int error;
641 char *frozen_buffer = NULL; 640 char *frozen_buffer = NULL;
642 int need_copy = 0; 641 int need_copy = 0;
642 unsigned long start_lock, time_lock;
643 643
644 if (is_handle_aborted(handle)) 644 if (is_handle_aborted(handle))
645 return -EROFS; 645 return -EROFS;
@@ -655,9 +655,16 @@ repeat:
655 655
656 /* @@@ Need to check for errors here at some point. */ 656 /* @@@ Need to check for errors here at some point. */
657 657
658 start_lock = jiffies;
658 lock_buffer(bh); 659 lock_buffer(bh);
659 jbd_lock_bh_state(bh); 660 jbd_lock_bh_state(bh);
660 661
662 /* If it takes too long to lock the buffer, trace it */
663 time_lock = jbd2_time_diff(start_lock, jiffies);
664 if (time_lock > HZ/10)
665 trace_jbd2_lock_buffer_stall(bh->b_bdev->bd_dev,
666 jiffies_to_msecs(time_lock));
667
661 /* We now hold the buffer lock so it is safe to query the buffer 668 /* We now hold the buffer lock so it is safe to query the buffer
662 * state. Is the buffer dirty? 669 * state. Is the buffer dirty?
663 * 670 *