Skip to content

Commit 0dbc759

Browse files
zhangyi089tytso
authored andcommitted
jbd2: add fast_commit space check
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]>
1 parent 054d9c8 commit 0dbc759

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

fs/jbd2/journal.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,7 @@ static void journal_fail_superblock(journal_t *journal)
13471347
static int journal_check_superblock(journal_t *journal)
13481348
{
13491349
journal_superblock_t *sb = journal->j_superblock;
1350+
int num_fc_blks;
13501351
int err = -EINVAL;
13511352

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

1393+
num_fc_blks = jbd2_has_feature_fast_commit(journal) ?
1394+
jbd2_journal_get_num_fc_blks(sb) : 0;
1395+
if (be32_to_cpu(sb->s_maxlen) < JBD2_MIN_JOURNAL_BLOCKS ||
1396+
be32_to_cpu(sb->s_maxlen) - JBD2_MIN_JOURNAL_BLOCKS < num_fc_blks) {
1397+
printk(KERN_ERR "JBD2: journal file too short %u,%d\n",
1398+
be32_to_cpu(sb->s_maxlen), num_fc_blks);
1399+
return err;
1400+
}
1401+
13921402
if (jbd2_has_feature_csum2(journal) &&
13931403
jbd2_has_feature_csum3(journal)) {
13941404
/* Can't have checksum v2 and v3 at the same time! */
@@ -1454,7 +1464,6 @@ static int journal_load_superblock(journal_t *journal)
14541464
int err;
14551465
struct buffer_head *bh;
14561466
journal_superblock_t *sb;
1457-
int num_fc_blocks;
14581467

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

14931502
if (jbd2_has_feature_fast_commit(journal)) {
14941503
journal->j_fc_last = be32_to_cpu(sb->s_maxlen);
1495-
num_fc_blocks = jbd2_journal_get_num_fc_blks(sb);
1496-
if (journal->j_last - num_fc_blocks >= JBD2_MIN_JOURNAL_BLOCKS)
1497-
journal->j_last = journal->j_fc_last - num_fc_blocks;
1504+
journal->j_last = journal->j_fc_last -
1505+
jbd2_journal_get_num_fc_blks(sb);
14981506
journal->j_fc_first = journal->j_last + 1;
14991507
journal->j_fc_off = 0;
15001508
}

0 commit comments

Comments
 (0)