jbd: Fix assertion failure in commit code due to lacking transaction credits
authorJan Kara <jack@suse.cz>
Wed, 11 Jul 2012 21:16:25 +0000 (23:16 +0200)
committerPaul Gortmaker <paul.gortmaker@windriver.com>
Mon, 10 Feb 2014 21:11:26 +0000 (16:11 -0500)
commit2d15ac56c76d8c78eb46b45831c4eed1ba5d500e
tree10d037ccdc4996c890e4129069de1c6f6ad974f0
parent7ea27a8916dccec0b5854266febb09414c3de588
jbd: Fix assertion failure in commit code due to lacking transaction credits

commit 09e05d4805e6c524c1af74e524e5d0528bb3fef3 upstream.

ext3 users of data=journal mode with blocksize < pagesize were occasionally
hitting assertion failure in journal_commit_transaction() checking whether the
transaction has at least as many credits reserved as buffers attached.  The
core of the problem is that when a file gets truncated, buffers that still need
checkpointing or that are attached to the committing transaction are left with
buffer_mapped set. When this happens to buffers beyond i_size attached to a
page stradding i_size, subsequent write extending the file will see these
buffers and as they are mapped (but underlying blocks were freed) things go
awry from here.

The assertion failure just coincidentally (and in this case luckily as we would
start corrupting filesystem) triggers due to journal_head not being properly
cleaned up as well.

Under some rare circumstances this bug could even hit data=ordered mode users.
There the assertion won't trigger and we would end up corrupting the
filesystem.

We fix the problem by unmapping buffers if possible (in lots of cases we just
need a buffer attached to a transaction as a place holder but it must not be
written out anyway). And in one case, we just have to bite the bullet and wait
for transaction commit to finish.

Reviewed-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
fs/jbd/commit.c
fs/jbd/transaction.c