>From e749e83627c35c683114fea32695e581a487e560 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 23 Apr 2010 02:12:32 +0200 Subject: [PATCH] ext4: Send barrier before updating journal superblock after checkpointing We have to send a disk barrier after we have finished checkpointing and before we update the journal superblock and thus effectively remove transactions from the journal. Otherwise the write of journal superblock can be reordered before writes of checkpointed journal blocks and thus in case of crash these blocks needn't be on the platter leading to filesystem corruption. Signed-off-by: Jan Kara --- fs/jbd2/checkpoint.c | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 30beb11..b2de17f 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -519,17 +519,16 @@ int jbd2_cleanup_journal_tail(journal_t *journal) spin_unlock(&journal->j_state_lock); /* - * If there is an external journal, we need to make sure that - * any data blocks that were recently written out --- perhaps - * by jbd2_log_do_checkpoint() --- are flushed out before we - * drop the transactions from the external journal. It's - * unlikely this will be necessary, especially with a - * appropriately sized journal, but we need this to guarantee - * correctness. Fortunately jbd2_cleanup_journal_tail() - * doesn't get called all that often. + * We need to make sure that any data blocks that were recently written + * out --- perhaps by jbd2_log_do_checkpoint() --- are flushed out + * before we drop the transactions from the journal. Otherwise journal + * superblock write could be reordered before writeout of data and thus + * we could corrupt the filesystem in case of crash. It's unlikely this + * will be necessary, especially with a appropriately sized journal, + * but we need this to guarantee correctness. Fortunately + * jbd2_cleanup_journal_tail() doesn't get called all that often. */ - if ((journal->j_fs_dev != journal->j_dev) && - (journal->j_flags & JBD2_BARRIER)) + if (journal->j_flags & JBD2_BARRIER) blkdev_issue_flush(journal->j_fs_dev, NULL); if (!(journal->j_flags & JBD2_ABORT)) jbd2_journal_update_superblock(journal, 1); -- 1.6.4.2