aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 13:12:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 13:12:15 -0400
commit4edebed86690eb8db9af3ab85baf4a34e73266cc (patch)
tree8ab144b08f490f239fa62be52470860c9311664d /fs/ext4/super.c
parent51eab603f5c86dd1eae4c525df3e7f7eeab401d6 (diff)
parent5e44f8c374dc4f8eadf61cd18b2c0d46bc87c1b7 (diff)
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull Ext4 updates from Theodore Ts'o: "The major new feature added in this update is Darrick J Wong's metadata checksum feature, which adds crc32 checksums to ext4's metadata fields. There is also the usual set of cleanups and bug fixes." * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (44 commits) ext4: hole-punch use truncate_pagecache_range jbd2: use kmem_cache_zalloc wrapper instead of flag ext4: remove mb_groups before tearing down the buddy_cache ext4: add ext4_mb_unload_buddy in the error path ext4: don't trash state flags in EXT4_IOC_SETFLAGS ext4: let getattr report the right blocks in delalloc+bigalloc ext4: add missing save_error_info() to ext4_error() ext4: add debugging trigger for ext4_error() ext4: protect group inode free counting with group lock ext4: use consistent ssize_t type in ext4_file_write() ext4: fix format flag in ext4_ext_binsearch_idx() ext4: cleanup in ext4_discard_allocated_blocks() ext4: return ENOMEM when mounts fail due to lack of memory ext4: remove redundundant "(char *) bh->b_data" casts ext4: disallow hard-linked directory in ext4_lookup ext4: fix potential integer overflow in alloc_flex_gd() ext4: remove needs_recovery in ext4_mb_init() ext4: force ro mount if ext4_setup_super() fails ext4: fix potential NULL dereference in ext4_free_inodes_counts() ext4/jbd2: add metadata checksumming to the list of supported features ...
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c253
1 files changed, 210 insertions, 43 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 35b5954489ee..eb7aa3e4ef05 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -112,6 +112,48 @@ static struct file_system_type ext3_fs_type = {
112#define IS_EXT3_SB(sb) (0) 112#define IS_EXT3_SB(sb) (0)
113#endif 113#endif
114 114
115static int ext4_verify_csum_type(struct super_block *sb,
116 struct ext4_super_block *es)
117{
118 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
119 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
120 return 1;
121
122 return es->s_checksum_type == EXT4_CRC32C_CHKSUM;
123}
124
125static __le32 ext4_superblock_csum(struct super_block *sb,
126 struct ext4_super_block *es)
127{
128 struct ext4_sb_info *sbi = EXT4_SB(sb);
129 int offset = offsetof(struct ext4_super_block, s_checksum);
130 __u32 csum;
131
132 csum = ext4_chksum(sbi, ~0, (char *)es, offset);
133
134 return cpu_to_le32(csum);
135}
136
137int ext4_superblock_csum_verify(struct super_block *sb,
138 struct ext4_super_block *es)
139{
140 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
141 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
142 return 1;
143
144 return es->s_checksum == ext4_superblock_csum(sb, es);
145}
146
147void ext4_superblock_csum_set(struct super_block *sb,
148 struct ext4_super_block *es)
149{
150 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
151 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
152 return;
153
154 es->s_checksum = ext4_superblock_csum(sb, es);
155}
156
115void *ext4_kvmalloc(size_t size, gfp_t flags) 157void *ext4_kvmalloc(size_t size, gfp_t flags)
116{ 158{
117 void *ret; 159 void *ret;
@@ -497,6 +539,7 @@ void __ext4_error(struct super_block *sb, const char *function,
497 printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n", 539 printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n",
498 sb->s_id, function, line, current->comm, &vaf); 540 sb->s_id, function, line, current->comm, &vaf);
499 va_end(args); 541 va_end(args);
542 save_error_info(sb, function, line);
500 543
501 ext4_handle_error(sb); 544 ext4_handle_error(sb);
502} 545}
@@ -905,6 +948,8 @@ static void ext4_put_super(struct super_block *sb)
905 unlock_super(sb); 948 unlock_super(sb);
906 kobject_put(&sbi->s_kobj); 949 kobject_put(&sbi->s_kobj);
907 wait_for_completion(&sbi->s_kobj_unregister); 950 wait_for_completion(&sbi->s_kobj_unregister);
951 if (sbi->s_chksum_driver)
952 crypto_free_shash(sbi->s_chksum_driver);
908 kfree(sbi->s_blockgroup_lock); 953 kfree(sbi->s_blockgroup_lock);
909 kfree(sbi); 954 kfree(sbi);
910} 955}
@@ -1922,43 +1967,69 @@ failed:
1922 return 0; 1967 return 0;
1923} 1968}
1924 1969
1925__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, 1970static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
1926 struct ext4_group_desc *gdp) 1971 struct ext4_group_desc *gdp)
1927{ 1972{
1973 int offset;
1928 __u16 crc = 0; 1974 __u16 crc = 0;
1975 __le32 le_group = cpu_to_le32(block_group);
1929 1976
1930 if (sbi->s_es->s_feature_ro_compat & 1977 if ((sbi->s_es->s_feature_ro_compat &
1931 cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { 1978 cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))) {
1932 int offset = offsetof(struct ext4_group_desc, bg_checksum); 1979 /* Use new metadata_csum algorithm */
1933 __le32 le_group = cpu_to_le32(block_group); 1980 __u16 old_csum;
1934 1981 __u32 csum32;
1935 crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); 1982
1936 crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); 1983 old_csum = gdp->bg_checksum;
1937 crc = crc16(crc, (__u8 *)gdp, offset); 1984 gdp->bg_checksum = 0;
1938 offset += sizeof(gdp->bg_checksum); /* skip checksum */ 1985 csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group,
1939 /* for checksum of struct ext4_group_desc do the rest...*/ 1986 sizeof(le_group));
1940 if ((sbi->s_es->s_feature_incompat & 1987 csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp,
1941 cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) && 1988 sbi->s_desc_size);
1942 offset < le16_to_cpu(sbi->s_es->s_desc_size)) 1989 gdp->bg_checksum = old_csum;
1943 crc = crc16(crc, (__u8 *)gdp + offset, 1990
1944 le16_to_cpu(sbi->s_es->s_desc_size) - 1991 crc = csum32 & 0xFFFF;
1945 offset); 1992 goto out;
1946 } 1993 }
1947 1994
1995 /* old crc16 code */
1996 offset = offsetof(struct ext4_group_desc, bg_checksum);
1997
1998 crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
1999 crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
2000 crc = crc16(crc, (__u8 *)gdp, offset);
2001 offset += sizeof(gdp->bg_checksum); /* skip checksum */
2002 /* for checksum of struct ext4_group_desc do the rest...*/
2003 if ((sbi->s_es->s_feature_incompat &
2004 cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
2005 offset < le16_to_cpu(sbi->s_es->s_desc_size))
2006 crc = crc16(crc, (__u8 *)gdp + offset,
2007 le16_to_cpu(sbi->s_es->s_desc_size) -
2008 offset);
2009
2010out:
1948 return cpu_to_le16(crc); 2011 return cpu_to_le16(crc);
1949} 2012}
1950 2013
1951int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, 2014int ext4_group_desc_csum_verify(struct super_block *sb, __u32 block_group,
1952 struct ext4_group_desc *gdp) 2015 struct ext4_group_desc *gdp)
1953{ 2016{
1954 if ((sbi->s_es->s_feature_ro_compat & 2017 if (ext4_has_group_desc_csum(sb) &&
1955 cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) && 2018 (gdp->bg_checksum != ext4_group_desc_csum(EXT4_SB(sb),
1956 (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp))) 2019 block_group, gdp)))
1957 return 0; 2020 return 0;
1958 2021
1959 return 1; 2022 return 1;
1960} 2023}
1961 2024
2025void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group,
2026 struct ext4_group_desc *gdp)
2027{
2028 if (!ext4_has_group_desc_csum(sb))
2029 return;
2030 gdp->bg_checksum = ext4_group_desc_csum(EXT4_SB(sb), block_group, gdp);
2031}
2032
1962/* Called at mount-time, super-block is locked */ 2033/* Called at mount-time, super-block is locked */
1963static int ext4_check_descriptors(struct super_block *sb, 2034static int ext4_check_descriptors(struct super_block *sb,
1964 ext4_group_t *first_not_zeroed) 2035 ext4_group_t *first_not_zeroed)
@@ -2013,7 +2084,7 @@ static int ext4_check_descriptors(struct super_block *sb,
2013 return 0; 2084 return 0;
2014 } 2085 }
2015 ext4_lock_group(sb, i); 2086 ext4_lock_group(sb, i);
2016 if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { 2087 if (!ext4_group_desc_csum_verify(sb, i, gdp)) {
2017 ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2088 ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
2018 "Checksum for group %u failed (%u!=%u)", 2089 "Checksum for group %u failed (%u!=%u)",
2019 i, le16_to_cpu(ext4_group_desc_csum(sbi, i, 2090 i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
@@ -2417,6 +2488,23 @@ static ssize_t sbi_ui_store(struct ext4_attr *a,
2417 return count; 2488 return count;
2418} 2489}
2419 2490
2491static ssize_t trigger_test_error(struct ext4_attr *a,
2492 struct ext4_sb_info *sbi,
2493 const char *buf, size_t count)
2494{
2495 int len = count;
2496
2497 if (!capable(CAP_SYS_ADMIN))
2498 return -EPERM;
2499
2500 if (len && buf[len-1] == '\n')
2501 len--;
2502
2503 if (len)
2504 ext4_error(sbi->s_sb, "%.*s", len, buf);
2505 return count;
2506}
2507
2420#define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \ 2508#define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \
2421static struct ext4_attr ext4_attr_##_name = { \ 2509static struct ext4_attr ext4_attr_##_name = { \
2422 .attr = {.name = __stringify(_name), .mode = _mode }, \ 2510 .attr = {.name = __stringify(_name), .mode = _mode }, \
@@ -2447,6 +2535,7 @@ EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
2447EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); 2535EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
2448EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); 2536EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
2449EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump); 2537EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump);
2538EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
2450 2539
2451static struct attribute *ext4_attrs[] = { 2540static struct attribute *ext4_attrs[] = {
2452 ATTR_LIST(delayed_allocation_blocks), 2541 ATTR_LIST(delayed_allocation_blocks),
@@ -2461,6 +2550,7 @@ static struct attribute *ext4_attrs[] = {
2461 ATTR_LIST(mb_stream_req), 2550 ATTR_LIST(mb_stream_req),
2462 ATTR_LIST(mb_group_prealloc), 2551 ATTR_LIST(mb_group_prealloc),
2463 ATTR_LIST(max_writeback_mb_bump), 2552 ATTR_LIST(max_writeback_mb_bump),
2553 ATTR_LIST(trigger_fs_error),
2464 NULL, 2554 NULL,
2465}; 2555};
2466 2556
@@ -2957,6 +3047,44 @@ static void ext4_destroy_lazyinit_thread(void)
2957 kthread_stop(ext4_lazyinit_task); 3047 kthread_stop(ext4_lazyinit_task);
2958} 3048}
2959 3049
3050static int set_journal_csum_feature_set(struct super_block *sb)
3051{
3052 int ret = 1;
3053 int compat, incompat;
3054 struct ext4_sb_info *sbi = EXT4_SB(sb);
3055
3056 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3057 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
3058 /* journal checksum v2 */
3059 compat = 0;
3060 incompat = JBD2_FEATURE_INCOMPAT_CSUM_V2;
3061 } else {
3062 /* journal checksum v1 */
3063 compat = JBD2_FEATURE_COMPAT_CHECKSUM;
3064 incompat = 0;
3065 }
3066
3067 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
3068 ret = jbd2_journal_set_features(sbi->s_journal,
3069 compat, 0,
3070 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT |
3071 incompat);
3072 } else if (test_opt(sb, JOURNAL_CHECKSUM)) {
3073 ret = jbd2_journal_set_features(sbi->s_journal,
3074 compat, 0,
3075 incompat);
3076 jbd2_journal_clear_features(sbi->s_journal, 0, 0,
3077 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
3078 } else {
3079 jbd2_journal_clear_features(sbi->s_journal,
3080 JBD2_FEATURE_COMPAT_CHECKSUM, 0,
3081 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT |
3082 JBD2_FEATURE_INCOMPAT_CSUM_V2);
3083 }
3084
3085 return ret;
3086}
3087
2960static int ext4_fill_super(struct super_block *sb, void *data, int silent) 3088static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2961{ 3089{
2962 char *orig_data = kstrdup(data, GFP_KERNEL); 3090 char *orig_data = kstrdup(data, GFP_KERNEL);
@@ -2993,6 +3121,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2993 goto out_free_orig; 3121 goto out_free_orig;
2994 } 3122 }
2995 sb->s_fs_info = sbi; 3123 sb->s_fs_info = sbi;
3124 sbi->s_sb = sb;
2996 sbi->s_mount_opt = 0; 3125 sbi->s_mount_opt = 0;
2997 sbi->s_resuid = make_kuid(&init_user_ns, EXT4_DEF_RESUID); 3126 sbi->s_resuid = make_kuid(&init_user_ns, EXT4_DEF_RESUID);
2998 sbi->s_resgid = make_kgid(&init_user_ns, EXT4_DEF_RESGID); 3127 sbi->s_resgid = make_kgid(&init_user_ns, EXT4_DEF_RESGID);
@@ -3032,13 +3161,54 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3032 * Note: s_es must be initialized as soon as possible because 3161 * Note: s_es must be initialized as soon as possible because
3033 * some ext4 macro-instructions depend on its value 3162 * some ext4 macro-instructions depend on its value
3034 */ 3163 */
3035 es = (struct ext4_super_block *) (((char *)bh->b_data) + offset); 3164 es = (struct ext4_super_block *) (bh->b_data + offset);
3036 sbi->s_es = es; 3165 sbi->s_es = es;
3037 sb->s_magic = le16_to_cpu(es->s_magic); 3166 sb->s_magic = le16_to_cpu(es->s_magic);
3038 if (sb->s_magic != EXT4_SUPER_MAGIC) 3167 if (sb->s_magic != EXT4_SUPER_MAGIC)
3039 goto cantfind_ext4; 3168 goto cantfind_ext4;
3040 sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written); 3169 sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);
3041 3170
3171 /* Warn if metadata_csum and gdt_csum are both set. */
3172 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3173 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
3174 EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
3175 ext4_warning(sb, KERN_INFO "metadata_csum and uninit_bg are "
3176 "redundant flags; please run fsck.");
3177
3178 /* Check for a known checksum algorithm */
3179 if (!ext4_verify_csum_type(sb, es)) {
3180 ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
3181 "unknown checksum algorithm.");
3182 silent = 1;
3183 goto cantfind_ext4;
3184 }
3185
3186 /* Load the checksum driver */
3187 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3188 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
3189 sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
3190 if (IS_ERR(sbi->s_chksum_driver)) {
3191 ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
3192 ret = PTR_ERR(sbi->s_chksum_driver);
3193 sbi->s_chksum_driver = NULL;
3194 goto failed_mount;
3195 }
3196 }
3197
3198 /* Check superblock checksum */
3199 if (!ext4_superblock_csum_verify(sb, es)) {
3200 ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
3201 "invalid superblock checksum. Run e2fsck?");
3202 silent = 1;
3203 goto cantfind_ext4;
3204 }
3205
3206 /* Precompute checksum seed for all metadata */
3207 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
3208 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
3209 sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
3210 sizeof(es->s_uuid));
3211
3042 /* Set defaults before we parse the mount options */ 3212 /* Set defaults before we parse the mount options */
3043 def_mount_opts = le32_to_cpu(es->s_default_mount_opts); 3213 def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
3044 set_opt(sb, INIT_INODE_TABLE); 3214 set_opt(sb, INIT_INODE_TABLE);
@@ -3200,7 +3370,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3200 "Can't read superblock on 2nd try"); 3370 "Can't read superblock on 2nd try");
3201 goto failed_mount; 3371 goto failed_mount;
3202 } 3372 }
3203 es = (struct ext4_super_block *)(((char *)bh->b_data) + offset); 3373 es = (struct ext4_super_block *)(bh->b_data + offset);
3204 sbi->s_es = es; 3374 sbi->s_es = es;
3205 if (es->s_magic != cpu_to_le16(EXT4_SUPER_MAGIC)) { 3375 if (es->s_magic != cpu_to_le16(EXT4_SUPER_MAGIC)) {
3206 ext4_msg(sb, KERN_ERR, 3376 ext4_msg(sb, KERN_ERR,
@@ -3392,6 +3562,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3392 GFP_KERNEL); 3562 GFP_KERNEL);
3393 if (sbi->s_group_desc == NULL) { 3563 if (sbi->s_group_desc == NULL) {
3394 ext4_msg(sb, KERN_ERR, "not enough memory"); 3564 ext4_msg(sb, KERN_ERR, "not enough memory");
3565 ret = -ENOMEM;
3395 goto failed_mount; 3566 goto failed_mount;
3396 } 3567 }
3397 3568
@@ -3449,6 +3620,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3449 } 3620 }
3450 if (err) { 3621 if (err) {
3451 ext4_msg(sb, KERN_ERR, "insufficient memory"); 3622 ext4_msg(sb, KERN_ERR, "insufficient memory");
3623 ret = err;
3452 goto failed_mount3; 3624 goto failed_mount3;
3453 } 3625 }
3454 3626
@@ -3506,26 +3678,17 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3506 goto no_journal; 3678 goto no_journal;
3507 } 3679 }
3508 3680
3509 if (ext4_blocks_count(es) > 0xffffffffULL && 3681 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT) &&
3510 !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, 3682 !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0,
3511 JBD2_FEATURE_INCOMPAT_64BIT)) { 3683 JBD2_FEATURE_INCOMPAT_64BIT)) {
3512 ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); 3684 ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature");
3513 goto failed_mount_wq; 3685 goto failed_mount_wq;
3514 } 3686 }
3515 3687
3516 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { 3688 if (!set_journal_csum_feature_set(sb)) {
3517 jbd2_journal_set_features(sbi->s_journal, 3689 ext4_msg(sb, KERN_ERR, "Failed to set journal checksum "
3518 JBD2_FEATURE_COMPAT_CHECKSUM, 0, 3690 "feature set");
3519 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); 3691 goto failed_mount_wq;
3520 } else if (test_opt(sb, JOURNAL_CHECKSUM)) {
3521 jbd2_journal_set_features(sbi->s_journal,
3522 JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
3523 jbd2_journal_clear_features(sbi->s_journal, 0, 0,
3524 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
3525 } else {
3526 jbd2_journal_clear_features(sbi->s_journal,
3527 JBD2_FEATURE_COMPAT_CHECKSUM, 0,
3528 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
3529 } 3692 }
3530 3693
3531 /* We have now updated the journal if required, so we can 3694 /* We have now updated the journal if required, so we can
@@ -3606,7 +3769,8 @@ no_journal:
3606 goto failed_mount4; 3769 goto failed_mount4;
3607 } 3770 }
3608 3771
3609 ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY); 3772 if (ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY))
3773 sb->s_flags |= MS_RDONLY;
3610 3774
3611 /* determine the minimum size of new large inodes, if present */ 3775 /* determine the minimum size of new large inodes, if present */
3612 if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) { 3776 if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
@@ -3641,7 +3805,7 @@ no_journal:
3641 } 3805 }
3642 3806
3643 ext4_ext_init(sb); 3807 ext4_ext_init(sb);
3644 err = ext4_mb_init(sb, needs_recovery); 3808 err = ext4_mb_init(sb);
3645 if (err) { 3809 if (err) {
3646 ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", 3810 ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
3647 err); 3811 err);
@@ -3724,6 +3888,8 @@ failed_mount2:
3724 brelse(sbi->s_group_desc[i]); 3888 brelse(sbi->s_group_desc[i]);
3725 ext4_kvfree(sbi->s_group_desc); 3889 ext4_kvfree(sbi->s_group_desc);
3726failed_mount: 3890failed_mount:
3891 if (sbi->s_chksum_driver)
3892 crypto_free_shash(sbi->s_chksum_driver);
3727 if (sbi->s_proc) { 3893 if (sbi->s_proc) {
3728 remove_proc_entry("options", sbi->s_proc); 3894 remove_proc_entry("options", sbi->s_proc);
3729 remove_proc_entry(sb->s_id, ext4_proc_root); 3895 remove_proc_entry(sb->s_id, ext4_proc_root);
@@ -3847,7 +4013,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
3847 goto out_bdev; 4013 goto out_bdev;
3848 } 4014 }
3849 4015
3850 es = (struct ext4_super_block *) (((char *)bh->b_data) + offset); 4016 es = (struct ext4_super_block *) (bh->b_data + offset);
3851 if ((le16_to_cpu(es->s_magic) != EXT4_SUPER_MAGIC) || 4017 if ((le16_to_cpu(es->s_magic) != EXT4_SUPER_MAGIC) ||
3852 !(le32_to_cpu(es->s_feature_incompat) & 4018 !(le32_to_cpu(es->s_feature_incompat) &
3853 EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)) { 4019 EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)) {
@@ -4039,6 +4205,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
4039 &EXT4_SB(sb)->s_freeinodes_counter)); 4205 &EXT4_SB(sb)->s_freeinodes_counter));
4040 sb->s_dirt = 0; 4206 sb->s_dirt = 0;
4041 BUFFER_TRACE(sbh, "marking dirty"); 4207 BUFFER_TRACE(sbh, "marking dirty");
4208 ext4_superblock_csum_set(sb, es);
4042 mark_buffer_dirty(sbh); 4209 mark_buffer_dirty(sbh);
4043 if (sync) { 4210 if (sync) {
4044 error = sync_dirty_buffer(sbh); 4211 error = sync_dirty_buffer(sbh);
@@ -4333,7 +4500,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
4333 struct ext4_group_desc *gdp = 4500 struct ext4_group_desc *gdp =
4334 ext4_get_group_desc(sb, g, NULL); 4501 ext4_get_group_desc(sb, g, NULL);
4335 4502
4336 if (!ext4_group_desc_csum_verify(sbi, g, gdp)) { 4503 if (!ext4_group_desc_csum_verify(sb, g, gdp)) {
4337 ext4_msg(sb, KERN_ERR, 4504 ext4_msg(sb, KERN_ERR,
4338 "ext4_remount: Checksum for group %u failed (%u!=%u)", 4505 "ext4_remount: Checksum for group %u failed (%u!=%u)",
4339 g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)), 4506 g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),