]> Git Repo - linux.git/commitdiff
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Mon, 1 May 2023 18:00:04 +0000 (11:00 -0700)
committerLinus Torvalds <[email protected]>
Mon, 1 May 2023 18:00:04 +0000 (11:00 -0700)
Pull ext4 fixes from Ted Ts'o:
 "Some ext4 regression and bug fixes"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: clean up error handling in __ext4_fill_super()
  ext4: reflect error codes from ext4_multi_mount_protect() to its callers
  ext4: fix lost error code reporting in __ext4_fill_super()
  ext4: fix unused iterator variable warnings
  ext4: fix use-after-free read in ext4_find_extent for bigalloc + inline
  ext4: fix i_disksize exceeding i_size problem in paritally written case

1  2 
fs/ext4/inode.c
fs/ext4/super.c

diff --combined fs/ext4/inode.c
index ffbbd9626bd88105be735a2527c5f7006e097870,1cfbb929c694516cc5cdafcd259a287248b378f6..0d5ba922e411f88f05a3e698bd62bfd988e514cd
@@@ -1162,8 -1162,8 +1162,8 @@@ static int ext4_write_begin(struct fil
  retry_grab:
        folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
                                        mapping_gfp_mask(mapping));
 -      if (!folio)
 -              return -ENOMEM;
 +      if (IS_ERR(folio))
 +              return PTR_ERR(folio);
        /*
         * The same as page allocation, we prealloc buffer heads before
         * starting the handle.
@@@ -2906,8 -2906,8 +2906,8 @@@ static int ext4_da_write_begin(struct f
  retry:
        folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
                        mapping_gfp_mask(mapping));
 -      if (!folio)
 -              return -ENOMEM;
 +      if (IS_ERR(folio))
 +              return PTR_ERR(folio);
  
        /* In case writeback began while the folio was unlocked */
        folio_wait_stable(folio);
@@@ -2982,6 -2982,9 +2982,9 @@@ static int ext4_da_write_end(struct fil
            ext4_has_inline_data(inode))
                return ext4_write_inline_data_end(inode, pos, len, copied, page);
  
+       if (unlikely(copied < len) && !PageUptodate(page))
+               copied = 0;
        start = pos & (PAGE_SIZE - 1);
        end = start + copied - 1;
  
@@@ -3618,8 -3621,8 +3621,8 @@@ static int __ext4_block_zero_page_range
        folio = __filemap_get_folio(mapping, from >> PAGE_SHIFT,
                                    FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
                                    mapping_gfp_constraint(mapping, ~__GFP_FS));
 -      if (!folio)
 -              return -ENOMEM;
 +      if (IS_ERR(folio))
 +              return PTR_ERR(folio);
  
        blocksize = inode->i_sb->s_blocksize;
  
@@@ -5201,7 -5204,7 +5204,7 @@@ static void ext4_wait_for_tail_page_com
        while (1) {
                struct folio *folio = filemap_lock_folio(inode->i_mapping,
                                      inode->i_size >> PAGE_SHIFT);
 -              if (!folio)
 +              if (IS_ERR(folio))
                        return;
                ret = __ext4_journalled_invalidate_folio(folio, offset,
                                                folio_size(folio) - offset);
diff --combined fs/ext4/super.c
index d03bf0ecf505283c48cd25c9ec261f0c1411f3ee,39f00f05f981cb9654d427e170c1e3ebac76cb89..d39f386e9baf6ad0daad9d5a5c4f69c5172e78aa
@@@ -1259,7 -1259,7 +1259,7 @@@ static void ext4_put_super(struct super
        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.
        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
  
@@@ -2554,7 -2554,7 +2554,7 @@@ static void ext4_apply_quota_options(st
                        qname = rcu_replace_pointer(sbi->s_qf_names[i], qname,
                                                lockdep_is_held(&sb->s_umount));
                        if (qname)
 -                              kfree_rcu(qname);
 +                              kfree_rcu_mightsleep(qname);
                }
        }
  
@@@ -5196,10 -5196,8 +5196,8 @@@ static int __ext4_fill_super(struct fs_
        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;
        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;
         */
        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);
  
        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) |
        /* 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);
        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);
                          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!
                if (!sbi->s_ea_block_cache) {
                        ext4_msg(sb, KERN_ERR,
                                 "Failed to create ea_block_cache");
+                       err = -EINVAL;
                        goto failed_mount_wq;
                }
  
                        if (!sbi->s_ea_inode_cache) {
                                ext4_msg(sb, KERN_ERR,
                                         "Failed to create ea_inode_cache");
+                               err = -EINVAL;
                                goto failed_mount_wq;
                        }
                }
                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;
        }
  
        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);
                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))
                        ext4_msg(sb, KERN_ERR,
                               "unable to initialize "
                               "flex_bg meta info!");
-                       ret = -ENOMEM;
+                       err = -ENOMEM;
                        goto failed_mount6;
                }
  
@@@ -5628,7 -5637,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);
        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)
@@@ -6565,12 -6574,12 +6574,12 @@@ static int __ext4_remount(struct fs_con
                                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;
+                       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
This page took 0.103545 seconds and 4 git commands to generate.