aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd
diff options
context:
space:
mode:
authorHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>2008-10-18 23:27:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 11:52:37 -0400
commit885e353c7427db7b60692789741b34e605b0b69b (patch)
tree9b6787c07b02e7abd41a0db9575d799bcb5eaf3a /fs/jbd
parentd1645e526a1e5842c9ac433d73419ba886676cf3 (diff)
jbd: don't dirty original metadata buffer on abort
Currently, original metadata buffers are dirtied when they are unfiled whether the journal has aborted or not. Eventually these buffers will be written-back to the filesystem by pdflush. This means some metadata buffers are written to the filesystem without journaling if the journal aborts. So if both journal abort and system crash happen at the same time, the filesystem would become inconsistent state. Additionally, replaying journaled metadata can overwrite the latest metadata on the filesystem partly. Because, if the journal aborts, journaled metadata are preserved and replayed during the next mount not to lose uncheckpointed metadata. This would also break the consistency of the filesystem. This patch prevents original metadata buffers from being dirtied on abort by clearing BH_JBDDirty flag from those buffers. Thus, no metadata buffers are written to the filesystem without journaling. Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Acked-by: Jan Kara <jack@suse.cz> Cc: <linux-ext4@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/jbd')
-rw-r--r--fs/jbd/commit.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index f1ea861b9929..d6a6659f3e46 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -518,9 +518,10 @@ void journal_commit_transaction(journal_t *journal)
518 jh = commit_transaction->t_buffers; 518 jh = commit_transaction->t_buffers;
519 519
520 /* If we're in abort mode, we just un-journal the buffer and 520 /* If we're in abort mode, we just un-journal the buffer and
521 release it for background writing. */ 521 release it. */
522 522
523 if (is_journal_aborted(journal)) { 523 if (is_journal_aborted(journal)) {
524 clear_buffer_jbddirty(jh2bh(jh));
524 JBUFFER_TRACE(jh, "journal is aborting: refile"); 525 JBUFFER_TRACE(jh, "journal is aborting: refile");
525 journal_refile_buffer(journal, jh); 526 journal_refile_buffer(journal, jh);
526 /* If that was the last one, we need to clean up 527 /* If that was the last one, we need to clean up
@@ -855,6 +856,8 @@ restart_loop:
855 if (buffer_jbddirty(bh)) { 856 if (buffer_jbddirty(bh)) {
856 JBUFFER_TRACE(jh, "add to new checkpointing trans"); 857 JBUFFER_TRACE(jh, "add to new checkpointing trans");
857 __journal_insert_checkpoint(jh, commit_transaction); 858 __journal_insert_checkpoint(jh, commit_transaction);
859 if (is_journal_aborted(journal))
860 clear_buffer_jbddirty(bh);
858 JBUFFER_TRACE(jh, "refile for checkpoint writeback"); 861 JBUFFER_TRACE(jh, "refile for checkpoint writeback");
859 __journal_refile_buffer(jh); 862 __journal_refile_buffer(jh);
860 jbd_unlock_bh_state(bh); 863 jbd_unlock_bh_state(bh);