Skip to content

Commit 990b6b5

Browse files
Zhihao Chengtytso
authored andcommitted
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: Zhihao Cheng <[email protected]> Suggested-by: Jan Kara <[email protected]> Reviewed-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 2bf5eb2 commit 990b6b5

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

fs/jbd2/journal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,7 @@ static journal_t *journal_init_common(struct block_device *bdev,
15341534
journal->j_fs_dev = fs_dev;
15351535
journal->j_blk_offset = start;
15361536
journal->j_total_len = len;
1537+
jbd2_init_fs_dev_write_error(journal);
15371538

15381539
err = journal_load_superblock(journal);
15391540
if (err)

fs/jbd2/recovery.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,6 @@ int jbd2_journal_recover(journal_t *journal)
289289
journal_superblock_t * sb;
290290

291291
struct recovery_info info;
292-
errseq_t wb_err;
293-
struct address_space *mapping;
294292

295293
memset(&info, 0, sizeof(info));
296294
sb = journal->j_superblock;
@@ -308,9 +306,6 @@ int jbd2_journal_recover(journal_t *journal)
308306
return 0;
309307
}
310308

311-
wb_err = 0;
312-
mapping = journal->j_fs_dev->bd_inode->i_mapping;
313-
errseq_check_and_advance(&mapping->wb_err, &wb_err);
314309
err = do_one_pass(journal, &info, PASS_SCAN);
315310
if (!err)
316311
err = do_one_pass(journal, &info, PASS_REVOKE);
@@ -334,7 +329,7 @@ int jbd2_journal_recover(journal_t *journal)
334329
err2 = sync_blockdev(journal->j_fs_dev);
335330
if (!err)
336331
err = err2;
337-
err2 = errseq_check_and_advance(&mapping->wb_err, &wb_err);
332+
err2 = jbd2_check_fs_dev_write_error(journal);
338333
if (!err)
339334
err = err2;
340335
/* Make sure all replayed data is on permanent storage */

include/linux/jbd2.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,13 @@ struct journal_s
998998
*/
999999
struct block_device *j_fs_dev;
10001000

1001+
/**
1002+
* @j_fs_dev_wb_err:
1003+
*
1004+
* Records the errseq of the client fs's backing block device.
1005+
*/
1006+
errseq_t j_fs_dev_wb_err;
1007+
10011008
/**
10021009
* @j_total_len: Total maximum capacity of the journal region on disk.
10031010
*/
@@ -1698,6 +1705,25 @@ static inline void jbd2_journal_abort_handle(handle_t *handle)
16981705
handle->h_aborted = 1;
16991706
}
17001707

1708+
static inline void jbd2_init_fs_dev_write_error(journal_t *journal)
1709+
{
1710+
struct address_space *mapping = journal->j_fs_dev->bd_inode->i_mapping;
1711+
1712+
/*
1713+
* Save the original wb_err value of client fs's bdev mapping which
1714+
* could be used to detect the client fs's metadata async write error.
1715+
*/
1716+
errseq_check_and_advance(&mapping->wb_err, &journal->j_fs_dev_wb_err);
1717+
}
1718+
1719+
static inline int jbd2_check_fs_dev_write_error(journal_t *journal)
1720+
{
1721+
struct address_space *mapping = journal->j_fs_dev->bd_inode->i_mapping;
1722+
1723+
return errseq_check(&mapping->wb_err,
1724+
READ_ONCE(journal->j_fs_dev_wb_err));
1725+
}
1726+
17011727
#endif /* __KERNEL__ */
17021728

17031729
/* Comparison functions for transaction IDs: perform comparisons using

0 commit comments

Comments
 (0)