|
@@ -2127,7 +2127,21 @@ static void ext3_free_data(handle_t *handle, struct inode *inode,
|
|
|
|
|
|
if (this_bh) {
|
|
if (this_bh) {
|
|
BUFFER_TRACE(this_bh, "call ext3_journal_dirty_metadata");
|
|
BUFFER_TRACE(this_bh, "call ext3_journal_dirty_metadata");
|
|
- ext3_journal_dirty_metadata(handle, this_bh);
|
|
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The buffer head should have an attached journal head at this
|
|
|
|
+ * point. However, if the data is corrupted and an indirect
|
|
|
|
+ * block pointed to itself, it would have been detached when
|
|
|
|
+ * the block was cleared. Check for this instead of OOPSing.
|
|
|
|
+ */
|
|
|
|
+ if (bh2jh(this_bh))
|
|
|
|
+ ext3_journal_dirty_metadata(handle, this_bh);
|
|
|
|
+ else
|
|
|
|
+ ext3_error(inode->i_sb, "ext3_free_data",
|
|
|
|
+ "circular indirect block detected, "
|
|
|
|
+ "inode=%lu, block=%llu",
|
|
|
|
+ inode->i_ino,
|
|
|
|
+ (unsigned long long)this_bh->b_blocknr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|