|
@@ -666,23 +666,24 @@ static int __ocfs2_journal_access(handle_t *handle,
|
|
|
/* we can safely remove this assertion after testing. */
|
|
|
if (!buffer_uptodate(bh)) {
|
|
|
mlog(ML_ERROR, "giving me a buffer that's not uptodate!\n");
|
|
|
- mlog(ML_ERROR, "b_blocknr=%llu\n",
|
|
|
- (unsigned long long)bh->b_blocknr);
|
|
|
+ mlog(ML_ERROR, "b_blocknr=%llu, b_state=0x%lx\n",
|
|
|
+ (unsigned long long)bh->b_blocknr, bh->b_state);
|
|
|
|
|
|
lock_buffer(bh);
|
|
|
/*
|
|
|
- * A previous attempt to write this buffer head failed.
|
|
|
- * Nothing we can do but to retry the write and hope for
|
|
|
- * the best.
|
|
|
+ * A previous transaction with a couple of buffer heads fail
|
|
|
+ * to checkpoint, so all the bhs are marked as BH_Write_EIO.
|
|
|
+ * For current transaction, the bh is just among those error
|
|
|
+ * bhs which previous transaction handle. We can't just clear
|
|
|
+ * its BH_Write_EIO and reuse directly, since other bhs are
|
|
|
+ * not written to disk yet and that will cause metadata
|
|
|
+ * inconsistency. So we should set fs read-only to avoid
|
|
|
+ * further damage.
|
|
|
*/
|
|
|
if (buffer_write_io_error(bh) && !buffer_uptodate(bh)) {
|
|
|
- clear_buffer_write_io_error(bh);
|
|
|
- set_buffer_uptodate(bh);
|
|
|
- }
|
|
|
-
|
|
|
- if (!buffer_uptodate(bh)) {
|
|
|
unlock_buffer(bh);
|
|
|
- return -EIO;
|
|
|
+ return ocfs2_error(osb->sb, "A previous attempt to "
|
|
|
+ "write this buffer head failed\n");
|
|
|
}
|
|
|
unlock_buffer(bh);
|
|
|
}
|