diff options
Diffstat (limited to 'fs/jbd2/journal.c')
-rw-r--r-- | fs/jbd2/journal.c | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 67b8e303946c..19d74d86d99c 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(__jbd2_debug); | |||
124 | /* Checksumming functions */ | 124 | /* Checksumming functions */ |
125 | static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb) | 125 | static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb) |
126 | { | 126 | { |
127 | if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | 127 | if (!jbd2_journal_has_csum_v2or3(j)) |
128 | return 1; | 128 | return 1; |
129 | 129 | ||
130 | return sb->s_checksum_type == JBD2_CRC32C_CHKSUM; | 130 | return sb->s_checksum_type == JBD2_CRC32C_CHKSUM; |
@@ -145,7 +145,7 @@ static __be32 jbd2_superblock_csum(journal_t *j, journal_superblock_t *sb) | |||
145 | 145 | ||
146 | static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb) | 146 | static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb) |
147 | { | 147 | { |
148 | if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | 148 | if (!jbd2_journal_has_csum_v2or3(j)) |
149 | return 1; | 149 | return 1; |
150 | 150 | ||
151 | return sb->s_checksum == jbd2_superblock_csum(j, sb); | 151 | return sb->s_checksum == jbd2_superblock_csum(j, sb); |
@@ -153,7 +153,7 @@ static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb) | |||
153 | 153 | ||
154 | static void jbd2_superblock_csum_set(journal_t *j, journal_superblock_t *sb) | 154 | static void jbd2_superblock_csum_set(journal_t *j, journal_superblock_t *sb) |
155 | { | 155 | { |
156 | if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | 156 | if (!jbd2_journal_has_csum_v2or3(j)) |
157 | return; | 157 | return; |
158 | 158 | ||
159 | sb->s_checksum = jbd2_superblock_csum(j, sb); | 159 | sb->s_checksum = jbd2_superblock_csum(j, sb); |
@@ -1522,21 +1522,29 @@ static int journal_get_superblock(journal_t *journal) | |||
1522 | goto out; | 1522 | goto out; |
1523 | } | 1523 | } |
1524 | 1524 | ||
1525 | if (JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM) && | 1525 | if (jbd2_journal_has_csum_v2or3(journal) && |
1526 | JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) { | 1526 | JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) { |
1527 | /* Can't have checksum v1 and v2 on at the same time! */ | 1527 | /* Can't have checksum v1 and v2 on at the same time! */ |
1528 | printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2 " | 1528 | printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2 " |
1529 | "at the same time!\n"); | 1529 | "at the same time!\n"); |
1530 | goto out; | 1530 | goto out; |
1531 | } | 1531 | } |
1532 | 1532 | ||
1533 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) && | ||
1534 | JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) { | ||
1535 | /* Can't have checksum v2 and v3 at the same time! */ | ||
1536 | printk(KERN_ERR "JBD2: Can't enable checksumming v2 and v3 " | ||
1537 | "at the same time!\n"); | ||
1538 | goto out; | ||
1539 | } | ||
1540 | |||
1533 | if (!jbd2_verify_csum_type(journal, sb)) { | 1541 | if (!jbd2_verify_csum_type(journal, sb)) { |
1534 | printk(KERN_ERR "JBD2: Unknown checksum type\n"); | 1542 | printk(KERN_ERR "JBD2: Unknown checksum type\n"); |
1535 | goto out; | 1543 | goto out; |
1536 | } | 1544 | } |
1537 | 1545 | ||
1538 | /* Load the checksum driver */ | 1546 | /* Load the checksum driver */ |
1539 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) { | 1547 | if (jbd2_journal_has_csum_v2or3(journal)) { |
1540 | journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); | 1548 | journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); |
1541 | if (IS_ERR(journal->j_chksum_driver)) { | 1549 | if (IS_ERR(journal->j_chksum_driver)) { |
1542 | printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); | 1550 | printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); |
@@ -1553,7 +1561,7 @@ static int journal_get_superblock(journal_t *journal) | |||
1553 | } | 1561 | } |
1554 | 1562 | ||
1555 | /* Precompute checksum seed for all metadata */ | 1563 | /* Precompute checksum seed for all metadata */ |
1556 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | 1564 | if (jbd2_journal_has_csum_v2or3(journal)) |
1557 | journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, | 1565 | journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, |
1558 | sizeof(sb->s_uuid)); | 1566 | sizeof(sb->s_uuid)); |
1559 | 1567 | ||
@@ -1813,8 +1821,14 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, | |||
1813 | if (!jbd2_journal_check_available_features(journal, compat, ro, incompat)) | 1821 | if (!jbd2_journal_check_available_features(journal, compat, ro, incompat)) |
1814 | return 0; | 1822 | return 0; |
1815 | 1823 | ||
1816 | /* Asking for checksumming v2 and v1? Only give them v2. */ | 1824 | /* If enabling v2 checksums, turn on v3 instead */ |
1817 | if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V2 && | 1825 | if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V2) { |
1826 | incompat &= ~JBD2_FEATURE_INCOMPAT_CSUM_V2; | ||
1827 | incompat |= JBD2_FEATURE_INCOMPAT_CSUM_V3; | ||
1828 | } | ||
1829 | |||
1830 | /* Asking for checksumming v3 and v1? Only give them v3. */ | ||
1831 | if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V3 && | ||
1818 | compat & JBD2_FEATURE_COMPAT_CHECKSUM) | 1832 | compat & JBD2_FEATURE_COMPAT_CHECKSUM) |
1819 | compat &= ~JBD2_FEATURE_COMPAT_CHECKSUM; | 1833 | compat &= ~JBD2_FEATURE_COMPAT_CHECKSUM; |
1820 | 1834 | ||
@@ -1823,8 +1837,8 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, | |||
1823 | 1837 | ||
1824 | sb = journal->j_superblock; | 1838 | sb = journal->j_superblock; |
1825 | 1839 | ||
1826 | /* If enabling v2 checksums, update superblock */ | 1840 | /* If enabling v3 checksums, update superblock */ |
1827 | if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V2)) { | 1841 | if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) { |
1828 | sb->s_checksum_type = JBD2_CRC32C_CHKSUM; | 1842 | sb->s_checksum_type = JBD2_CRC32C_CHKSUM; |
1829 | sb->s_feature_compat &= | 1843 | sb->s_feature_compat &= |
1830 | ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); | 1844 | ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); |
@@ -1842,8 +1856,7 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, | |||
1842 | } | 1856 | } |
1843 | 1857 | ||
1844 | /* Precompute checksum seed for all metadata */ | 1858 | /* Precompute checksum seed for all metadata */ |
1845 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, | 1859 | if (jbd2_journal_has_csum_v2or3(journal)) |
1846 | JBD2_FEATURE_INCOMPAT_CSUM_V2)) | ||
1847 | journal->j_csum_seed = jbd2_chksum(journal, ~0, | 1860 | journal->j_csum_seed = jbd2_chksum(journal, ~0, |
1848 | sb->s_uuid, | 1861 | sb->s_uuid, |
1849 | sizeof(sb->s_uuid)); | 1862 | sizeof(sb->s_uuid)); |
@@ -1852,7 +1865,8 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, | |||
1852 | /* If enabling v1 checksums, downgrade superblock */ | 1865 | /* If enabling v1 checksums, downgrade superblock */ |
1853 | if (COMPAT_FEATURE_ON(JBD2_FEATURE_COMPAT_CHECKSUM)) | 1866 | if (COMPAT_FEATURE_ON(JBD2_FEATURE_COMPAT_CHECKSUM)) |
1854 | sb->s_feature_incompat &= | 1867 | sb->s_feature_incompat &= |
1855 | ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2); | 1868 | ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2 | |
1869 | JBD2_FEATURE_INCOMPAT_CSUM_V3); | ||
1856 | 1870 | ||
1857 | sb->s_feature_compat |= cpu_to_be32(compat); | 1871 | sb->s_feature_compat |= cpu_to_be32(compat); |
1858 | sb->s_feature_ro_compat |= cpu_to_be32(ro); | 1872 | sb->s_feature_ro_compat |= cpu_to_be32(ro); |
@@ -2165,16 +2179,20 @@ int jbd2_journal_blocks_per_page(struct inode *inode) | |||
2165 | */ | 2179 | */ |
2166 | size_t journal_tag_bytes(journal_t *journal) | 2180 | size_t journal_tag_bytes(journal_t *journal) |
2167 | { | 2181 | { |
2168 | journal_block_tag_t tag; | 2182 | size_t sz; |
2169 | size_t x = 0; | 2183 | |
2184 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) | ||
2185 | return sizeof(journal_block_tag3_t); | ||
2186 | |||
2187 | sz = sizeof(journal_block_tag_t); | ||
2170 | 2188 | ||
2171 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | 2189 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) |
2172 | x += sizeof(tag.t_checksum); | 2190 | sz += sizeof(__u16); |
2173 | 2191 | ||
2174 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) | 2192 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) |
2175 | return x + JBD2_TAG_SIZE64; | 2193 | return sz; |
2176 | else | 2194 | else |
2177 | return x + JBD2_TAG_SIZE32; | 2195 | return sz - sizeof(__u32); |
2178 | } | 2196 | } |
2179 | 2197 | ||
2180 | /* | 2198 | /* |