Commit 8595798c authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Theodore Ts'o

jbd2: gate checksum calculations on crc driver presence, not sb flags

Change the journal's checksum functions to gate on whether or not the
crc32c driver is loaded, and gate the loading on the superblock bits.
This prevents a journal crash if someone loads a journal in no-csum
mode and then randomizes the superblock, thus flipping on the feature
bits.
Tested-By: default avatarNikolay Borisov <kernel@kyup.com>
Reported-by: default avatarNikolay Borisov <kernel@kyup.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent b90197b6
...@@ -124,7 +124,7 @@ EXPORT_SYMBOL(__jbd2_debug); ...@@ -124,7 +124,7 @@ EXPORT_SYMBOL(__jbd2_debug);
/* Checksumming functions */ /* Checksumming functions */
static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb) static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb)
{ {
if (!jbd2_journal_has_csum_v2or3(j)) if (!jbd2_journal_has_csum_v2or3_feature(j))
return 1; return 1;
return sb->s_checksum_type == JBD2_CRC32C_CHKSUM; return sb->s_checksum_type == JBD2_CRC32C_CHKSUM;
...@@ -1531,7 +1531,7 @@ static int journal_get_superblock(journal_t *journal) ...@@ -1531,7 +1531,7 @@ static int journal_get_superblock(journal_t *journal)
goto out; goto out;
} }
if (jbd2_journal_has_csum_v2or3(journal) && if (jbd2_journal_has_csum_v2or3_feature(journal) &&
JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) { JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) {
/* Can't have checksum v1 and v2 on at the same time! */ /* Can't have checksum v1 and v2 on at the same time! */
printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 " printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 "
...@@ -1545,7 +1545,7 @@ static int journal_get_superblock(journal_t *journal) ...@@ -1545,7 +1545,7 @@ static int journal_get_superblock(journal_t *journal)
} }
/* Load the checksum driver */ /* Load the checksum driver */
if (jbd2_journal_has_csum_v2or3(journal)) { if (jbd2_journal_has_csum_v2or3_feature(journal)) {
journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
if (IS_ERR(journal->j_chksum_driver)) { if (IS_ERR(journal->j_chksum_driver)) {
printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
......
...@@ -1338,13 +1338,18 @@ static inline int tid_geq(tid_t x, tid_t y) ...@@ -1338,13 +1338,18 @@ static inline int tid_geq(tid_t x, tid_t y)
extern int jbd2_journal_blocks_per_page(struct inode *inode); extern int jbd2_journal_blocks_per_page(struct inode *inode);
extern size_t journal_tag_bytes(journal_t *journal); extern size_t journal_tag_bytes(journal_t *journal);
static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
{
return JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2) ||
JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3);
}
static inline int jbd2_journal_has_csum_v2or3(journal_t *journal) static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
{ {
if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) || WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) &&
JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) journal->j_chksum_driver == NULL);
return 1;
return 0; return journal->j_chksum_driver != NULL;
} }
/* /*
......
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