jbd2/ocfs2: Fix block checksumming when a buffer is used in several transactions
authorJan Kara <jack@suse.cz>
Wed, 14 Jul 2010 05:56:33 +0000 (07:56 +0200)
committerJoel Becker <joel.becker@oracle.com>
Thu, 15 Jul 2010 22:17:47 +0000 (15:17 -0700)
commit13ceef099edd2b70c5a6f3a9ef5d6d97cda2e096
tree5d65c397e9e85abe11a6fb0ebf3a69e8a4e91e0d
parenta39953dd95ff10e311083d94f4f95c348cb22464
jbd2/ocfs2: Fix block checksumming when a buffer is used in several transactions

OCFS2 uses t_commit trigger to compute and store checksum of the just
committed blocks. When a buffer has b_frozen_data, checksum is computed
for it instead of b_data but this can result in an old checksum being
written to the filesystem in the following scenario:

1) transaction1 is opened
2) handle1 is opened
3) journal_access(handle1, bh)
    - This sets jh->b_transaction to transaction1
4) modify(bh)
5) journal_dirty(handle1, bh)
6) handle1 is closed
7) start committing transaction1, opening transaction2
8) handle2 is opened
9) journal_access(handle2, bh)
    - This copies off b_frozen_data to make it safe for transaction1 to commit.
      jh->b_next_transaction is set to transaction2.
10) jbd2_journal_write_metadata() checksums b_frozen_data
11) the journal correctly writes b_frozen_data to the disk journal
12) handle2 is closed
    - There was no dirty call for the bh on handle2, so it is never queued for
      any more journal operation
13) Checkpointing finally happens, and it just spools the bh via normal buffer
writeback.  This will write b_data, which was never triggered on and thus
contains a wrong (old) checksum.

This patch fixes the problem by calling the trigger at the moment data is
frozen for journal commit - i.e., either when b_frozen_data is created by
do_get_write_access or just before we write a buffer to the log if
b_frozen_data does not exist. We also rename the trigger to t_frozen as
that better describes when it is called.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/ocfs2/journal.c
include/linux/jbd2.h