ext4: don't clear SB_RDONLY when remounting r/w until quota is re-enabled
[platform/kernel/linux-starfive.git] / fs / ext4 / super.c
index d03bf0e..c7bc4a2 100644 (file)
@@ -1048,6 +1048,8 @@ void ext4_mark_group_bitmap_corrupted(struct super_block *sb,
        struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
        int ret;
 
+       if (!grp || !gdp)
+               return;
        if (flags & EXT4_GROUP_INFO_BBITMAP_CORRUPT) {
                ret = ext4_test_and_set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT,
                                            &grp->bb_state);
@@ -1259,7 +1261,7 @@ static void ext4_put_super(struct super_block *sb)
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct ext4_super_block *es = sbi->s_es;
        int aborted = 0;
-       int i, err;
+       int err;
 
        /*
         * Unregister sysfs before destroying jbd2 journal.
@@ -1311,7 +1313,7 @@ static void ext4_put_super(struct super_block *sb)
        ext4_flex_groups_free(sbi);
        ext4_percpu_param_destroy(sbi);
 #ifdef CONFIG_QUOTA
-       for (i = 0; i < EXT4_MAXQUOTAS; i++)
+       for (int i = 0; i < EXT4_MAXQUOTAS; i++)
                kfree(get_qf_name(sb, sbi, i));
 #endif
 
@@ -3238,11 +3240,9 @@ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
        crc = crc16(crc, (__u8 *)gdp, offset);
        offset += sizeof(gdp->bg_checksum); /* skip checksum */
        /* for checksum of struct ext4_group_desc do the rest...*/
-       if (ext4_has_feature_64bit(sb) &&
-           offset < le16_to_cpu(sbi->s_es->s_desc_size))
+       if (ext4_has_feature_64bit(sb) && offset < sbi->s_desc_size)
                crc = crc16(crc, (__u8 *)gdp + offset,
-                           le16_to_cpu(sbi->s_es->s_desc_size) -
-                               offset);
+                           sbi->s_desc_size - offset);
 
 out:
        return cpu_to_le16(crc);
@@ -5196,10 +5196,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        ext4_fsblk_t logical_sb_block;
        struct inode *root;
-       int ret = -ENOMEM;
-       unsigned int i;
        int needs_recovery;
-       int err = 0;
+       int err;
        ext4_group_t first_not_zeroed;
        struct ext4_fs_context *ctx = fc->fs_private;
        int silent = fc->sb_flags & SB_SILENT;
@@ -5212,8 +5210,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
        sbi->s_sectors_written_start =
                part_stat_read(sb->s_bdev, sectors[STAT_WRITE]);
 
-       /* -EINVAL is default */
-       ret = -EINVAL;
        err = ext4_load_super(sb, &logical_sb_block, silent);
        if (err)
                goto out_fail;
@@ -5239,7 +5235,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
         */
        sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
 
-       if (ext4_inode_info_init(sb, es))
+       err = ext4_inode_info_init(sb, es);
+       if (err)
                goto failed_mount;
 
        err = parse_apply_sb_mount_options(sb, ctx);
@@ -5255,10 +5252,12 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
 
        ext4_apply_options(fc, sb);
 
-       if (ext4_encoding_init(sb, es))
+       err = ext4_encoding_init(sb, es);
+       if (err)
                goto failed_mount;
 
-       if (ext4_check_journal_data_mode(sb))
+       err = ext4_check_journal_data_mode(sb);
+       if (err)
                goto failed_mount;
 
        sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
@@ -5267,18 +5266,22 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
        /* i_version is always enabled now */
        sb->s_flags |= SB_I_VERSION;
 
-       if (ext4_check_feature_compatibility(sb, es, silent))
+       err = ext4_check_feature_compatibility(sb, es, silent);
+       if (err)
                goto failed_mount;
 
-       if (ext4_block_group_meta_init(sb, silent))
+       err = ext4_block_group_meta_init(sb, silent);
+       if (err)
                goto failed_mount;
 
        ext4_hash_info_init(sb);
 
-       if (ext4_handle_clustersize(sb))
+       err = ext4_handle_clustersize(sb);
+       if (err)
                goto failed_mount;
 
-       if (ext4_check_geometry(sb, es))
+       err = ext4_check_geometry(sb, es);
+       if (err)
                goto failed_mount;
 
        timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
@@ -5289,8 +5292,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
        if (err)
                goto failed_mount3;
 
-       /* Register extent status tree shrinker */
-       if (ext4_es_register_shrinker(sbi))
+       err = ext4_es_register_shrinker(sbi);
+       if (err)
                goto failed_mount3;
 
        sbi->s_stripe = ext4_get_stripe_size(sbi);
@@ -5329,10 +5332,13 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                          ext4_has_feature_orphan_present(sb) ||
                          ext4_has_feature_journal_needs_recovery(sb));
 
-       if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb))
-               if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
+       if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb)) {
+               err = ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block));
+               if (err)
                        goto failed_mount3a;
+       }
 
+       err = -EINVAL;
        /*
         * The first inode we look at is the journal inode.  Don't try
         * root first: it may be modified in the journal!
@@ -5384,6 +5390,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                if (!sbi->s_ea_block_cache) {
                        ext4_msg(sb, KERN_ERR,
                                 "Failed to create ea_block_cache");
+                       err = -EINVAL;
                        goto failed_mount_wq;
                }
 
@@ -5392,6 +5399,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                        if (!sbi->s_ea_inode_cache) {
                                ext4_msg(sb, KERN_ERR,
                                         "Failed to create ea_inode_cache");
+                               err = -EINVAL;
                                goto failed_mount_wq;
                        }
                }
@@ -5426,7 +5434,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                alloc_workqueue("ext4-rsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
        if (!EXT4_SB(sb)->rsv_conversion_wq) {
                printk(KERN_ERR "EXT4-fs: failed to create workqueue\n");
-               ret = -ENOMEM;
+               err = -ENOMEM;
                goto failed_mount4;
        }
 
@@ -5438,28 +5446,28 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
        root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL);
        if (IS_ERR(root)) {
                ext4_msg(sb, KERN_ERR, "get root inode failed");
-               ret = PTR_ERR(root);
+               err = PTR_ERR(root);
                root = NULL;
                goto failed_mount4;
        }
        if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
                ext4_msg(sb, KERN_ERR, "corrupt root inode, run e2fsck");
                iput(root);
+               err = -EFSCORRUPTED;
                goto failed_mount4;
        }
 
        sb->s_root = d_make_root(root);
        if (!sb->s_root) {
                ext4_msg(sb, KERN_ERR, "get root dentry failed");
-               ret = -ENOMEM;
+               err = -ENOMEM;
                goto failed_mount4;
        }
 
-       ret = ext4_setup_super(sb, es, sb_rdonly(sb));
-       if (ret == -EROFS) {
+       err = ext4_setup_super(sb, es, sb_rdonly(sb));
+       if (err == -EROFS) {
                sb->s_flags |= SB_RDONLY;
-               ret = 0;
-       } else if (ret)
+       } else if (err)
                goto failed_mount4a;
 
        ext4_set_resv_clusters(sb);
@@ -5503,7 +5511,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                sbi->s_journal->j_commit_callback =
                        ext4_journal_commit_callback;
 
-       if (ext4_percpu_param_init(sbi))
+       err = ext4_percpu_param_init(sbi);
+       if (err)
                goto failed_mount6;
 
        if (ext4_has_feature_flex_bg(sb))
@@ -5511,7 +5520,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                        ext4_msg(sb, KERN_ERR,
                               "unable to initialize "
                               "flex_bg meta info!");
-                       ret = -ENOMEM;
+                       err = -ENOMEM;
                        goto failed_mount6;
                }
 
@@ -5628,7 +5637,7 @@ failed_mount:
 #endif
 
 #ifdef CONFIG_QUOTA
-       for (i = 0; i < EXT4_MAXQUOTAS; i++)
+       for (unsigned int i = 0; i < EXT4_MAXQUOTAS; i++)
                kfree(get_qf_name(sb, sbi, i));
 #endif
        fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
@@ -5637,7 +5646,7 @@ failed_mount:
        ext4_blkdev_remove(sbi);
 out_fail:
        sb->s_fs_info = NULL;
-       return err ? err : ret;
+       return err;
 }
 
 static int ext4_fill_super(struct super_block *sb, struct fs_context *fc)
@@ -6378,6 +6387,7 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
        struct ext4_mount_options old_opts;
        ext4_group_t g;
        int err = 0;
+       int enable_rw = 0;
 #ifdef CONFIG_QUOTA
        int enable_quota = 0;
        int i, j;
@@ -6564,13 +6574,13 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
                        if (err)
                                goto restore_opts;
 
-                       sb->s_flags &= ~SB_RDONLY;
-                       if (ext4_has_feature_mmp(sb))
-                               if (ext4_multi_mount_protect(sb,
-                                               le64_to_cpu(es->s_mmp_block))) {
-                                       err = -EROFS;
+                       enable_rw = 1;
+                       if (ext4_has_feature_mmp(sb)) {
+                               err = ext4_multi_mount_protect(sb,
+                                               le64_to_cpu(es->s_mmp_block));
+                               if (err)
                                        goto restore_opts;
-                               }
+                       }
 #ifdef CONFIG_QUOTA
                        enable_quota = 1;
 #endif
@@ -6623,6 +6633,9 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
        if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
                ext4_release_system_zone(sb);
 
+       if (enable_rw)
+               sb->s_flags &= ~SB_RDONLY;
+
        if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
                ext4_stop_mmpd(sbi);