Skip to content

Commit

Permalink
jbd2: add fast_commit space check
Browse files Browse the repository at this point in the history
If JBD2_FEATURE_INCOMPAT_FAST_COMMIT bit is set, it means the journal
have fast commit records need to recover, so the fast commit size
should not be too large, and the leftover normal journal size should
never less than JBD2_MIN_JOURNAL_BLOCKS. If it happens, the
journal->j_last is likely to be wrong and will probably lead to
incorrect journal recovery. So add a check into the
journal_check_superblock(), and drop the pointless check when
initializing the fastcommit parameters.

Signed-off-by: Zhang Yi <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Theodore Ts'o <[email protected]>
  • Loading branch information
zhangyi089 authored and tytso committed Aug 15, 2023
1 parent 054d9c8 commit 0dbc759
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions fs/jbd2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,7 @@ static void journal_fail_superblock(journal_t *journal)
static int journal_check_superblock(journal_t *journal)
{
journal_superblock_t *sb = journal->j_superblock;
int num_fc_blks;
int err = -EINVAL;

if (sb->s_header.h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER) ||
Expand Down Expand Up @@ -1389,6 +1390,15 @@ static int journal_check_superblock(journal_t *journal)
return err;
}

num_fc_blks = jbd2_has_feature_fast_commit(journal) ?
jbd2_journal_get_num_fc_blks(sb) : 0;
if (be32_to_cpu(sb->s_maxlen) < JBD2_MIN_JOURNAL_BLOCKS ||
be32_to_cpu(sb->s_maxlen) - JBD2_MIN_JOURNAL_BLOCKS < num_fc_blks) {
printk(KERN_ERR "JBD2: journal file too short %u,%d\n",
be32_to_cpu(sb->s_maxlen), num_fc_blks);
return err;
}

if (jbd2_has_feature_csum2(journal) &&
jbd2_has_feature_csum3(journal)) {
/* Can't have checksum v2 and v3 at the same time! */
Expand Down Expand Up @@ -1454,7 +1464,6 @@ static int journal_load_superblock(journal_t *journal)
int err;
struct buffer_head *bh;
journal_superblock_t *sb;
int num_fc_blocks;

bh = getblk_unmovable(journal->j_dev, journal->j_blk_offset,
journal->j_blocksize);
Expand Down Expand Up @@ -1492,9 +1501,8 @@ static int journal_load_superblock(journal_t *journal)

if (jbd2_has_feature_fast_commit(journal)) {
journal->j_fc_last = be32_to_cpu(sb->s_maxlen);
num_fc_blocks = jbd2_journal_get_num_fc_blks(sb);
if (journal->j_last - num_fc_blocks >= JBD2_MIN_JOURNAL_BLOCKS)
journal->j_last = journal->j_fc_last - num_fc_blocks;
journal->j_last = journal->j_fc_last -
jbd2_journal_get_num_fc_blks(sb);
journal->j_fc_first = journal->j_last + 1;
journal->j_fc_off = 0;
}
Expand Down

0 comments on commit 0dbc759

Please sign in to comment.