aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2012-05-27 07:48:56 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-05-27 07:48:56 -0400
commit25ed6e8a54df904c875365eebedbd19138a47328 (patch)
treeac16e78f0d8e0376f40d9259b1095f356d395165 /fs/jbd2
parent8f888ef846d4481e24c74b4a91ece771d2bcbcb5 (diff)
jbd2: enable journal clients to enable v2 checksumming
Add in the necessary code so that journal clients can enable the new journal checksumming features. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2')
-rw-r--r--fs/jbd2/journal.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 1afb701622b0..63175f9391ab 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -97,6 +97,15 @@ EXPORT_SYMBOL(jbd2_inode_cache);
97static void __journal_abort_soft (journal_t *journal, int errno); 97static void __journal_abort_soft (journal_t *journal, int errno);
98static int jbd2_journal_create_slab(size_t slab_size); 98static int jbd2_journal_create_slab(size_t slab_size);
99 99
100/* Checksumming functions */
101int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb)
102{
103 if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
104 return 1;
105
106 return sb->s_checksum_type == JBD2_CRC32C_CHKSUM;
107}
108
100/* 109/*
101 * Helper function used to manage commit timeouts 110 * Helper function used to manage commit timeouts
102 */ 111 */
@@ -1376,6 +1385,9 @@ static int journal_get_superblock(journal_t *journal)
1376 } 1385 }
1377 } 1386 }
1378 1387
1388 if (buffer_verified(bh))
1389 return 0;
1390
1379 sb = journal->j_superblock; 1391 sb = journal->j_superblock;
1380 1392
1381 err = -EINVAL; 1393 err = -EINVAL;
@@ -1413,6 +1425,21 @@ static int journal_get_superblock(journal_t *journal)
1413 goto out; 1425 goto out;
1414 } 1426 }
1415 1427
1428 if (JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM) &&
1429 JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) {
1430 /* Can't have checksum v1 and v2 on at the same time! */
1431 printk(KERN_ERR "JBD: Can't enable checksumming v1 and v2 "
1432 "at the same time!\n");
1433 goto out;
1434 }
1435
1436 if (!jbd2_verify_csum_type(journal, sb)) {
1437 printk(KERN_ERR "JBD: Unknown checksum type\n");
1438 goto out;
1439 }
1440
1441 set_buffer_verified(bh);
1442
1416 return 0; 1443 return 0;
1417 1444
1418out: 1445out:
@@ -1653,6 +1680,10 @@ int jbd2_journal_check_available_features (journal_t *journal, unsigned long com
1653int jbd2_journal_set_features (journal_t *journal, unsigned long compat, 1680int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
1654 unsigned long ro, unsigned long incompat) 1681 unsigned long ro, unsigned long incompat)
1655{ 1682{
1683#define INCOMPAT_FEATURE_ON(f) \
1684 ((incompat & (f)) && !(sb->s_feature_incompat & cpu_to_be32(f)))
1685#define COMPAT_FEATURE_ON(f) \
1686 ((compat & (f)) && !(sb->s_feature_compat & cpu_to_be32(f)))
1656 journal_superblock_t *sb; 1687 journal_superblock_t *sb;
1657 1688
1658 if (jbd2_journal_check_used_features(journal, compat, ro, incompat)) 1689 if (jbd2_journal_check_used_features(journal, compat, ro, incompat))
@@ -1661,16 +1692,35 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
1661 if (!jbd2_journal_check_available_features(journal, compat, ro, incompat)) 1692 if (!jbd2_journal_check_available_features(journal, compat, ro, incompat))
1662 return 0; 1693 return 0;
1663 1694
1695 /* Asking for checksumming v2 and v1? Only give them v2. */
1696 if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V2 &&
1697 compat & JBD2_FEATURE_COMPAT_CHECKSUM)
1698 compat &= ~JBD2_FEATURE_COMPAT_CHECKSUM;
1699
1664 jbd_debug(1, "Setting new features 0x%lx/0x%lx/0x%lx\n", 1700 jbd_debug(1, "Setting new features 0x%lx/0x%lx/0x%lx\n",
1665 compat, ro, incompat); 1701 compat, ro, incompat);
1666 1702
1667 sb = journal->j_superblock; 1703 sb = journal->j_superblock;
1668 1704
1705 /* If enabling v2 checksums, update superblock */
1706 if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V2)) {
1707 sb->s_checksum_type = JBD2_CRC32C_CHKSUM;
1708 sb->s_feature_compat &=
1709 ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
1710 }
1711
1712 /* If enabling v1 checksums, downgrade superblock */
1713 if (COMPAT_FEATURE_ON(JBD2_FEATURE_COMPAT_CHECKSUM))
1714 sb->s_feature_incompat &=
1715 ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2);
1716
1669 sb->s_feature_compat |= cpu_to_be32(compat); 1717 sb->s_feature_compat |= cpu_to_be32(compat);
1670 sb->s_feature_ro_compat |= cpu_to_be32(ro); 1718 sb->s_feature_ro_compat |= cpu_to_be32(ro);
1671 sb->s_feature_incompat |= cpu_to_be32(incompat); 1719 sb->s_feature_incompat |= cpu_to_be32(incompat);
1672 1720
1673 return 1; 1721 return 1;
1722#undef COMPAT_FEATURE_ON
1723#undef INCOMPAT_FEATURE_ON
1674} 1724}
1675 1725
1676/* 1726/*