From: Stephen Tweedie This patch improves ext3's ability to deal with corruption on-disk. If we try to delete a metadata block twice, we confuse ext3's internal revoke error-checking, resulting in a BUG(). But this can occur in practice due to a corrupt indirect block, so we should attempt to fail gracefully. Downgrade the assert failure to a JH_EXPECT_BH failure, and return EIO when it occurs. This is easily reproduced with a sample ext3 fs image containing an inode which references the same indirect block more than once. Deleting that inode will BUG() an unfixed kernel with: Assertion failure in journal_revoke() at fs/jbd/revoke.c:379: "!buffer_revoked(bh)" With the fix, ext3 recovers gracefully. Signed-off-by: Stephen Tweedie Signed-off-by: Andrew Morton --- 25-akpm/fs/jbd/revoke.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) diff -puN fs/jbd/revoke.c~ext3-handle-attempted-double-delete-of-metadata fs/jbd/revoke.c --- 25/fs/jbd/revoke.c~ext3-handle-attempted-double-delete-of-metadata Fri Nov 19 16:18:54 2004 +++ 25-akpm/fs/jbd/revoke.c Fri Nov 19 16:18:54 2004 @@ -376,7 +376,12 @@ int journal_revoke(handle_t *handle, uns first having the revoke cancelled: it's illegal to free a block twice without allocating it in between! */ if (bh) { - J_ASSERT_BH(bh, !buffer_revoked(bh)); + if (!J_EXPECT_BH(bh, !buffer_revoked(bh), + "inconsistent data on disk")) { + if (!bh_in) + brelse(bh); + return -EIO; + } set_buffer_revoked(bh); set_buffer_revokevalid(bh); if (bh_in) { _