Commit 990b6b5b authored by Zhihao Cheng's avatar Zhihao Cheng Committed by Theodore Ts'o

jbd2: add errseq to detect client fs's bdev writeback error

Add errseq in journal, so that JBD2 can detect whether metadata is
successfully written to fs bdev. This patch adds detection in recovery
process to replace original solution(using local variable wb_err).
Signed-off-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
Suggested-by: default avatarJan Kara <jack@suse.cz>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20231213013224.2100050-2-chengzhihao1@huawei.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 2bf5eb2a
......@@ -1534,6 +1534,7 @@ static journal_t *journal_init_common(struct block_device *bdev,
journal->j_fs_dev = fs_dev;
journal->j_blk_offset = start;
journal->j_total_len = len;
jbd2_init_fs_dev_write_error(journal);
err = journal_load_superblock(journal);
if (err)
......
......@@ -289,8 +289,6 @@ int jbd2_journal_recover(journal_t *journal)
journal_superblock_t * sb;
struct recovery_info info;
errseq_t wb_err;
struct address_space *mapping;
memset(&info, 0, sizeof(info));
sb = journal->j_superblock;
......@@ -308,9 +306,6 @@ int jbd2_journal_recover(journal_t *journal)
return 0;
}
wb_err = 0;
mapping = journal->j_fs_dev->bd_inode->i_mapping;
errseq_check_and_advance(&mapping->wb_err, &wb_err);
err = do_one_pass(journal, &info, PASS_SCAN);
if (!err)
err = do_one_pass(journal, &info, PASS_REVOKE);
......@@ -334,7 +329,7 @@ int jbd2_journal_recover(journal_t *journal)
err2 = sync_blockdev(journal->j_fs_dev);
if (!err)
err = err2;
err2 = errseq_check_and_advance(&mapping->wb_err, &wb_err);
err2 = jbd2_check_fs_dev_write_error(journal);
if (!err)
err = err2;
/* Make sure all replayed data is on permanent storage */
......
......@@ -998,6 +998,13 @@ struct journal_s
*/
struct block_device *j_fs_dev;
/**
* @j_fs_dev_wb_err:
*
* Records the errseq of the client fs's backing block device.
*/
errseq_t j_fs_dev_wb_err;
/**
* @j_total_len: Total maximum capacity of the journal region on disk.
*/
......@@ -1698,6 +1705,25 @@ static inline void jbd2_journal_abort_handle(handle_t *handle)
handle->h_aborted = 1;
}
static inline void jbd2_init_fs_dev_write_error(journal_t *journal)
{
struct address_space *mapping = journal->j_fs_dev->bd_inode->i_mapping;
/*
* Save the original wb_err value of client fs's bdev mapping which
* could be used to detect the client fs's metadata async write error.
*/
errseq_check_and_advance(&mapping->wb_err, &journal->j_fs_dev_wb_err);
}
static inline int jbd2_check_fs_dev_write_error(journal_t *journal)
{
struct address_space *mapping = journal->j_fs_dev->bd_inode->i_mapping;
return errseq_check(&mapping->wb_err,
READ_ONCE(journal->j_fs_dev_wb_err));
}
#endif /* __KERNEL__ */
/* Comparison functions for transaction IDs: perform comparisons using
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment