aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd')
-rw-r--r--fs/jbd/checkpoint.c15
-rw-r--r--fs/jbd/commit.c10
-rw-r--r--fs/jbd/transaction.c2
3 files changed, 15 insertions, 12 deletions
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 47552d4a6324..a5432bbbfb88 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -347,7 +347,8 @@ restart:
347 break; 347 break;
348 } 348 }
349 retry = __process_buffer(journal, jh, bhs,&batch_count); 349 retry = __process_buffer(journal, jh, bhs,&batch_count);
350 if (!retry && lock_need_resched(&journal->j_list_lock)){ 350 if (!retry && (need_resched() ||
351 spin_needbreak(&journal->j_list_lock))) {
351 spin_unlock(&journal->j_list_lock); 352 spin_unlock(&journal->j_list_lock);
352 retry = 1; 353 retry = 1;
353 break; 354 break;
@@ -602,15 +603,15 @@ int __journal_remove_checkpoint(struct journal_head *jh)
602 603
603 /* 604 /*
604 * There is one special case to worry about: if we have just pulled the 605 * There is one special case to worry about: if we have just pulled the
605 * buffer off a committing transaction's forget list, then even if the 606 * buffer off a running or committing transaction's checkpoing list,
606 * checkpoint list is empty, the transaction obviously cannot be 607 * then even if the checkpoint list is empty, the transaction obviously
607 * dropped! 608 * cannot be dropped!
608 * 609 *
609 * The locking here around j_committing_transaction is a bit sleazy. 610 * The locking here around t_state is a bit sleazy.
610 * See the comment at the end of journal_commit_transaction(). 611 * See the comment at the end of journal_commit_transaction().
611 */ 612 */
612 if (transaction == journal->j_committing_transaction) { 613 if (transaction->t_state != T_FINISHED) {
613 JBUFFER_TRACE(jh, "belongs to committing transaction"); 614 JBUFFER_TRACE(jh, "belongs to running/committing transaction");
614 goto out; 615 goto out;
615 } 616 }
616 617
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 8f1f2aa5fb39..31853eb65b4c 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -265,7 +265,7 @@ write_out_data:
265 put_bh(bh); 265 put_bh(bh);
266 } 266 }
267 267
268 if (lock_need_resched(&journal->j_list_lock)) { 268 if (need_resched() || spin_needbreak(&journal->j_list_lock)) {
269 spin_unlock(&journal->j_list_lock); 269 spin_unlock(&journal->j_list_lock);
270 goto write_out_data; 270 goto write_out_data;
271 } 271 }
@@ -858,10 +858,10 @@ restart_loop:
858 } 858 }
859 spin_unlock(&journal->j_list_lock); 859 spin_unlock(&journal->j_list_lock);
860 /* 860 /*
861 * This is a bit sleazy. We borrow j_list_lock to protect 861 * This is a bit sleazy. We use j_list_lock to protect transition
862 * journal->j_committing_transaction in __journal_remove_checkpoint. 862 * of a transaction into T_FINISHED state and calling
863 * Really, __journal_remove_checkpoint should be using j_state_lock but 863 * __journal_drop_transaction(). Otherwise we could race with
864 * it's a bit hassle to hold that across __journal_remove_checkpoint 864 * other checkpointing code processing the transaction...
865 */ 865 */
866 spin_lock(&journal->j_state_lock); 866 spin_lock(&journal->j_state_lock);
867 spin_lock(&journal->j_list_lock); 867 spin_lock(&journal->j_list_lock);
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 08ff6c7028cc..038ed7436199 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -288,10 +288,12 @@ handle_t *journal_start(journal_t *journal, int nblocks)
288 jbd_free_handle(handle); 288 jbd_free_handle(handle);
289 current->journal_info = NULL; 289 current->journal_info = NULL;
290 handle = ERR_PTR(err); 290 handle = ERR_PTR(err);
291 goto out;
291 } 292 }
292 293
293 lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_); 294 lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_);
294 295
296out:
295 return handle; 297 return handle;
296} 298}
297 299