jbd2: store more accurate errno in superblock when possible
When jbd2_journal_abort() is called, the provided error code is stored in the journal superblock. Some existing calls hard-code -EIO even when the actual failure is not I/O related. This patch updates those calls to pass more accurate error codes, allowing the superblock to record the true cause of failure. This helps improve diagnostics and debugging clarity when analyzing journal aborts. Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Message-ID: <20251031210501.7337-1-wen.gang.wang@oracle.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>pull/1354/merge
parent
986835bf4d
commit
80d05f640a
|
|
@ -698,7 +698,7 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
|
|||
WARN_ON_ONCE(1);
|
||||
|
||||
if (!continue_fs && !ext4_emergency_ro(sb) && journal)
|
||||
jbd2_journal_abort(journal, -EIO);
|
||||
jbd2_journal_abort(journal, -error);
|
||||
|
||||
if (!bdev_read_only(sb->s_bdev)) {
|
||||
save_error_info(sb, error, ino, block, func, line);
|
||||
|
|
@ -5843,7 +5843,7 @@ static int ext4_journal_bmap(journal_t *journal, sector_t *block)
|
|||
ext4_msg(journal->j_inode->i_sb, KERN_CRIT,
|
||||
"journal bmap failed: block %llu ret %d\n",
|
||||
*block, ret);
|
||||
jbd2_journal_abort(journal, ret ? ret : -EIO);
|
||||
jbd2_journal_abort(journal, ret ? ret : -EFSCORRUPTED);
|
||||
return ret;
|
||||
}
|
||||
*block = map.m_pblk;
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ __releases(&journal->j_state_lock)
|
|||
"journal space in %s\n", __func__,
|
||||
journal->j_devname);
|
||||
WARN_ON(1);
|
||||
jbd2_journal_abort(journal, -EIO);
|
||||
jbd2_journal_abort(journal, -ENOSPC);
|
||||
}
|
||||
write_lock(&journal->j_state_lock);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -937,8 +937,8 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
|
|||
printk(KERN_ALERT "%s: journal block not found "
|
||||
"at offset %lu on %s\n",
|
||||
__func__, blocknr, journal->j_devname);
|
||||
jbd2_journal_abort(journal, ret ? ret : -EFSCORRUPTED);
|
||||
err = -EIO;
|
||||
jbd2_journal_abort(journal, err);
|
||||
} else {
|
||||
*retp = block;
|
||||
}
|
||||
|
|
@ -1859,8 +1859,9 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
|
|||
|
||||
if (is_journal_aborted(journal))
|
||||
return -EIO;
|
||||
if (jbd2_check_fs_dev_write_error(journal)) {
|
||||
jbd2_journal_abort(journal, -EIO);
|
||||
ret = jbd2_check_fs_dev_write_error(journal);
|
||||
if (ret) {
|
||||
jbd2_journal_abort(journal, ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -2157,9 +2158,11 @@ int jbd2_journal_destroy(journal_t *journal)
|
|||
* failed to write back to the original location, otherwise the
|
||||
* filesystem may become inconsistent.
|
||||
*/
|
||||
if (!is_journal_aborted(journal) &&
|
||||
jbd2_check_fs_dev_write_error(journal))
|
||||
jbd2_journal_abort(journal, -EIO);
|
||||
if (!is_journal_aborted(journal)) {
|
||||
int ret = jbd2_check_fs_dev_write_error(journal);
|
||||
if (ret)
|
||||
jbd2_journal_abort(journal, ret);
|
||||
}
|
||||
|
||||
if (journal->j_sb_buffer) {
|
||||
if (!is_journal_aborted(journal)) {
|
||||
|
|
|
|||
|
|
@ -1219,7 +1219,8 @@ int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
|
|||
return -EROFS;
|
||||
|
||||
journal = handle->h_transaction->t_journal;
|
||||
if (jbd2_check_fs_dev_write_error(journal)) {
|
||||
rc = jbd2_check_fs_dev_write_error(journal);
|
||||
if (rc) {
|
||||
/*
|
||||
* If the fs dev has writeback errors, it may have failed
|
||||
* to async write out metadata buffers in the background.
|
||||
|
|
@ -1227,7 +1228,7 @@ int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
|
|||
* it out again, which may lead to on-disk filesystem
|
||||
* inconsistency. Aborting journal can avoid it happen.
|
||||
*/
|
||||
jbd2_journal_abort(journal, -EIO);
|
||||
jbd2_journal_abort(journal, rc);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue