aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 15:51:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 15:51:21 -0500
commitac69e0928054ff29a5049902fb477f9c7605c773 (patch)
tree05be6b9285186823452e0adeffe40e1dfee6e354 /fs/jbd
parent9e203936eac786f9268d6a13e6442d2accef1829 (diff)
parent302bf2f3259948c93361d501b04a5ed69c3bd4f8 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: ext2/3/4: delete unneeded includes of module.h ext{3,4}: Fix potential race when setversion ioctl updates inode udf: Mark LVID buffer as uptodate before marking it dirty ext3: Don't warn from writepage when readonly inode is spotted after error jbd: Remove j_barrier mutex reiserfs: Force inode evictions before umount to avoid crash reiserfs: Fix quota mount option parsing udf: Treat symlink component of type 2 as / udf: Fix deadlock when converting file from in-ICB one to normal one udf: Cleanup calling convention of inode_getblk() ext2: Fix error handling on inode bitmap corruption ext3: Fix error handling on inode bitmap corruption ext3: replace ll_rw_block with other functions ext3: NULL dereference in ext3_evict_inode() jbd: clear revoked flag on buffers before a new transaction started ext3: call ext3_mark_recovery_complete() when recovery is really needed
Diffstat (limited to 'fs/jbd')
-rw-r--r--fs/jbd/commit.c6
-rw-r--r--fs/jbd/journal.c1
-rw-r--r--fs/jbd/revoke.c34
-rw-r--r--fs/jbd/transaction.c38
4 files changed, 62 insertions, 17 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 8799207df058..f2b9a571f4cf 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -392,6 +392,12 @@ void journal_commit_transaction(journal_t *journal)
392 jbd_debug (3, "JBD: commit phase 1\n"); 392 jbd_debug (3, "JBD: commit phase 1\n");
393 393
394 /* 394 /*
395 * Clear revoked flag to reflect there is no revoked buffers
396 * in the next transaction which is going to be started.
397 */
398 journal_clear_buffer_revoked_flags(journal);
399
400 /*
395 * Switch to a new revoke table. 401 * Switch to a new revoke table.
396 */ 402 */
397 journal_switch_revoke_table(journal); 403 journal_switch_revoke_table(journal);
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index a96cff0c5f1d..59c09f9541b5 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -721,7 +721,6 @@ static journal_t * journal_init_common (void)
721 init_waitqueue_head(&journal->j_wait_checkpoint); 721 init_waitqueue_head(&journal->j_wait_checkpoint);
722 init_waitqueue_head(&journal->j_wait_commit); 722 init_waitqueue_head(&journal->j_wait_commit);
723 init_waitqueue_head(&journal->j_wait_updates); 723 init_waitqueue_head(&journal->j_wait_updates);
724 mutex_init(&journal->j_barrier);
725 mutex_init(&journal->j_checkpoint_mutex); 724 mutex_init(&journal->j_checkpoint_mutex);
726 spin_lock_init(&journal->j_revoke_lock); 725 spin_lock_init(&journal->j_revoke_lock);
727 spin_lock_init(&journal->j_list_lock); 726 spin_lock_init(&journal->j_list_lock);
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index 305a90763154..25c713e7071c 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -47,6 +47,10 @@
47 * overwriting the new data. We don't even need to clear the revoke 47 * overwriting the new data. We don't even need to clear the revoke
48 * bit here. 48 * bit here.
49 * 49 *
50 * We cache revoke status of a buffer in the current transaction in b_states
51 * bits. As the name says, revokevalid flag indicates that the cached revoke
52 * status of a buffer is valid and we can rely on the cached status.
53 *
50 * Revoke information on buffers is a tri-state value: 54 * Revoke information on buffers is a tri-state value:
51 * 55 *
52 * RevokeValid clear: no cached revoke status, need to look it up 56 * RevokeValid clear: no cached revoke status, need to look it up
@@ -479,6 +483,36 @@ int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
479 return did_revoke; 483 return did_revoke;
480} 484}
481 485
486/*
487 * journal_clear_revoked_flags clears revoked flag of buffers in
488 * revoke table to reflect there is no revoked buffer in the next
489 * transaction which is going to be started.
490 */
491void journal_clear_buffer_revoked_flags(journal_t *journal)
492{
493 struct jbd_revoke_table_s *revoke = journal->j_revoke;
494 int i = 0;
495
496 for (i = 0; i < revoke->hash_size; i++) {
497 struct list_head *hash_list;
498 struct list_head *list_entry;
499 hash_list = &revoke->hash_table[i];
500
501 list_for_each(list_entry, hash_list) {
502 struct jbd_revoke_record_s *record;
503 struct buffer_head *bh;
504 record = (struct jbd_revoke_record_s *)list_entry;
505 bh = __find_get_block(journal->j_fs_dev,
506 record->blocknr,
507 journal->j_blocksize);
508 if (bh) {
509 clear_buffer_revoked(bh);
510 __brelse(bh);
511 }
512 }
513 }
514}
515
482/* journal_switch_revoke table select j_revoke for next transaction 516/* journal_switch_revoke table select j_revoke for next transaction
483 * we do not want to suspend any processing until all revokes are 517 * we do not want to suspend any processing until all revokes are
484 * written -bzzz 518 * written -bzzz
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 7e59c6e66f9b..7fce94b04bc3 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -426,17 +426,34 @@ int journal_restart(handle_t *handle, int nblocks)
426 * void journal_lock_updates () - establish a transaction barrier. 426 * void journal_lock_updates () - establish a transaction barrier.
427 * @journal: Journal to establish a barrier on. 427 * @journal: Journal to establish a barrier on.
428 * 428 *
429 * This locks out any further updates from being started, and blocks 429 * This locks out any further updates from being started, and blocks until all
430 * until all existing updates have completed, returning only once the 430 * existing updates have completed, returning only once the journal is in a
431 * journal is in a quiescent state with no updates running. 431 * quiescent state with no updates running.
432 * 432 *
433 * The journal lock should not be held on entry. 433 * We do not use simple mutex for synchronization as there are syscalls which
434 * want to return with filesystem locked and that trips up lockdep. Also
435 * hibernate needs to lock filesystem but locked mutex then blocks hibernation.
436 * Since locking filesystem is rare operation, we use simple counter and
437 * waitqueue for locking.
434 */ 438 */
435void journal_lock_updates(journal_t *journal) 439void journal_lock_updates(journal_t *journal)
436{ 440{
437 DEFINE_WAIT(wait); 441 DEFINE_WAIT(wait);
438 442
443wait:
444 /* Wait for previous locked operation to finish */
445 wait_event(journal->j_wait_transaction_locked,
446 journal->j_barrier_count == 0);
447
439 spin_lock(&journal->j_state_lock); 448 spin_lock(&journal->j_state_lock);
449 /*
450 * Check reliably under the lock whether we are the ones winning the race
451 * and locking the journal
452 */
453 if (journal->j_barrier_count > 0) {
454 spin_unlock(&journal->j_state_lock);
455 goto wait;
456 }
440 ++journal->j_barrier_count; 457 ++journal->j_barrier_count;
441 458
442 /* Wait until there are no running updates */ 459 /* Wait until there are no running updates */
@@ -460,14 +477,6 @@ void journal_lock_updates(journal_t *journal)
460 spin_lock(&journal->j_state_lock); 477 spin_lock(&journal->j_state_lock);
461 } 478 }
462 spin_unlock(&journal->j_state_lock); 479 spin_unlock(&journal->j_state_lock);
463
464 /*
465 * We have now established a barrier against other normal updates, but
466 * we also need to barrier against other journal_lock_updates() calls
467 * to make sure that we serialise special journal-locked operations
468 * too.
469 */
470 mutex_lock(&journal->j_barrier);
471} 480}
472 481
473/** 482/**
@@ -475,14 +484,11 @@ void journal_lock_updates(journal_t *journal)
475 * @journal: Journal to release the barrier on. 484 * @journal: Journal to release the barrier on.
476 * 485 *
477 * Release a transaction barrier obtained with journal_lock_updates(). 486 * Release a transaction barrier obtained with journal_lock_updates().
478 *
479 * Should be called without the journal lock held.
480 */ 487 */
481void journal_unlock_updates (journal_t *journal) 488void journal_unlock_updates (journal_t *journal)
482{ 489{
483 J_ASSERT(journal->j_barrier_count != 0); 490 J_ASSERT(journal->j_barrier_count != 0);
484 491
485 mutex_unlock(&journal->j_barrier);
486 spin_lock(&journal->j_state_lock); 492 spin_lock(&journal->j_state_lock);
487 --journal->j_barrier_count; 493 --journal->j_barrier_count;
488 spin_unlock(&journal->j_state_lock); 494 spin_unlock(&journal->j_state_lock);