ext4: fix jbd2 handle extension in ext4_ext_truncate_extend_restart()
authorTheodore Ts'o <tytso@mit.edu>
Tue, 26 Apr 2016 03:13:17 +0000 (23:13 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 26 Apr 2016 03:13:17 +0000 (23:13 -0400)
commit7b8081912d75df1d910d6969f0a374b66ef242bf
tree4bb558bb911daa64cb61061cb4e81b2129df5b2e
parentee0876bc69ee8d24d524fb2e9e41e3682aaebb11
ext4: fix jbd2 handle extension in ext4_ext_truncate_extend_restart()

The function jbd2_journal_extend() takes as its argument the number of
new credits to be added to the handle.  We weren't taking into account
the currently unused handle credits; worse, we would try to extend the
handle by N credits when it had N credits available.

In the case where jbd2_journal_extend() fails because the transaction
is too large, when jbd2_journal_restart() gets called, the N credits
owned by the handle gets returned to the transaction, and the
transaction commit is asynchronously requested, and then
start_this_handle() will be able to successfully attach the handle to
the current transaction since the required credits are now available.

This is mostly harmless, but since ext4_ext_truncate_extend_restart()
returns EAGAIN, the truncate machinery will once again try to call
ext4_ext_truncate_extend_restart(), which will do the above sequence
over and over again until the transaction has committed.

This was found while I was debugging a lockup in caused by running
xfstests generic/074 in the data=journal case.  I'm still not sure why
we ended up looping forever, which suggests there may still be another
bug hiding in the transaction accounting machinery, but this commit
prevents us from looping in the first place.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/extents.c