diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2012-05-27 07:48:56 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-05-27 07:48:56 -0400 |
commit | 25ed6e8a54df904c875365eebedbd19138a47328 (patch) | |
tree | ac16e78f0d8e0376f40d9259b1095f356d395165 /fs/jbd2 | |
parent | 8f888ef846d4481e24c74b4a91ece771d2bcbcb5 (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.c | 50 |
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); | |||
97 | static void __journal_abort_soft (journal_t *journal, int errno); | 97 | static void __journal_abort_soft (journal_t *journal, int errno); |
98 | static int jbd2_journal_create_slab(size_t slab_size); | 98 | static int jbd2_journal_create_slab(size_t slab_size); |
99 | 99 | ||
100 | /* Checksumming functions */ | ||
101 | int 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 | ||
1418 | out: | 1445 | out: |
@@ -1653,6 +1680,10 @@ int jbd2_journal_check_available_features (journal_t *journal, unsigned long com | |||
1653 | int jbd2_journal_set_features (journal_t *journal, unsigned long compat, | 1680 | int 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 | /* |