Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Feb 2020 19:12:06 +0000 (11:12 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Feb 2020 19:12:06 +0000 (11:12 -0800)
Pull ext4 fixes from Ted Ts'o:
 "Miscellaneous ext4 bug fixes (all stable fodder)"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: improve explanation of a mount failure caused by a misconfigured kernel
  jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer
  jbd2: move the clearing of b_modified flag to the journal_unmap_buffer()
  ext4: add cond_resched() to ext4_protect_reserved_inode
  ext4: fix checksum errors with indexed dirs
  ext4: fix support for inode sizes > 1024 bytes
  ext4: simplify checking quota limits in ext4_statfs()
  ext4: don't assume that mmp_nodename/bdevname have NUL

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

diff --combined fs/ext4/inode.c
@@@ -2867,7 -2867,7 +2867,7 @@@ static int ext4_dax_writepages(struct a
        percpu_down_read(&sbi->s_journal_flag_rwsem);
        trace_ext4_writepages(inode, wbc);
  
 -      ret = dax_writeback_mapping_range(mapping, inode->i_sb->s_bdev, wbc);
 +      ret = dax_writeback_mapping_range(mapping, sbi->s_daxdev, wbc);
        trace_ext4_writepages_result(inode, wbc, ret,
                                     nr_to_write - wbc->nr_to_write);
        percpu_up_read(&sbi->s_journal_flag_rwsem);
@@@ -4644,6 -4644,18 +4644,18 @@@ struct inode *__ext4_iget(struct super_
                ret = -EFSCORRUPTED;
                goto bad_inode;
        }
+       /*
+        * If dir_index is not enabled but there's dir with INDEX flag set,
+        * we'd normally treat htree data as empty space. But with metadata
+        * checksumming that corrupts checksums so forbid that.
+        */
+       if (!ext4_has_feature_dir_index(sb) && ext4_has_metadata_csum(sb) &&
+           ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) {
+               ext4_error_inode(inode, function, line, 0,
+                        "iget: Dir with htree data on filesystem without dir_index feature.");
+               ret = -EFSCORRUPTED;
+               goto bad_inode;
+       }
        ei->i_disksize = inode->i_size;
  #ifdef CONFIG_QUOTA
        ei->i_reserved_quota = 0;
diff --combined fs/ext4/super.c
@@@ -3009,17 -3009,11 +3009,11 @@@ static int ext4_feature_set_ok(struct s
                return 0;
        }
  
- #ifndef CONFIG_QUOTA
-       if (ext4_has_feature_quota(sb) && !readonly) {
+ #if !defined(CONFIG_QUOTA) || !defined(CONFIG_QFMT_V2)
+       if (!readonly && (ext4_has_feature_quota(sb) ||
+                         ext4_has_feature_project(sb))) {
                ext4_msg(sb, KERN_ERR,
-                        "Filesystem with quota feature cannot be mounted RDWR "
-                        "without CONFIG_QUOTA");
-               return 0;
-       }
-       if (ext4_has_feature_project(sb) && !readonly) {
-               ext4_msg(sb, KERN_ERR,
-                        "Filesystem with project quota feature cannot be mounted RDWR "
-                        "without CONFIG_QUOTA");
+                        "The kernel was not built with CONFIG_QUOTA and CONFIG_QFMT_V2");
                return 0;
        }
  #endif  /* CONFIG_QUOTA */
@@@ -3814,6 -3808,15 +3808,15 @@@ static int ext4_fill_super(struct super
         */
        sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
  
+       blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
+       if (blocksize < EXT4_MIN_BLOCK_SIZE ||
+           blocksize > EXT4_MAX_BLOCK_SIZE) {
+               ext4_msg(sb, KERN_ERR,
+                      "Unsupported filesystem blocksize %d (%d log_block_size)",
+                        blocksize, le32_to_cpu(es->s_log_block_size));
+               goto failed_mount;
+       }
        if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) {
                sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE;
                sbi->s_first_ino = EXT4_GOOD_OLD_FIRST_INO;
                        ext4_msg(sb, KERN_ERR,
                               "unsupported inode size: %d",
                               sbi->s_inode_size);
+                       ext4_msg(sb, KERN_ERR, "blocksize: %d", blocksize);
                        goto failed_mount;
                }
                /*
        if (!ext4_feature_set_ok(sb, (sb_rdonly(sb))))
                goto failed_mount;
  
-       blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
-       if (blocksize < EXT4_MIN_BLOCK_SIZE ||
-           blocksize > EXT4_MAX_BLOCK_SIZE) {
-               ext4_msg(sb, KERN_ERR,
-                      "Unsupported filesystem blocksize %d (%d log_block_size)",
-                        blocksize, le32_to_cpu(es->s_log_block_size));
-               goto failed_mount;
-       }
        if (le32_to_cpu(es->s_log_block_size) >
            (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
                ext4_msg(sb, KERN_ERR,
@@@ -5585,10 -5581,7 +5581,7 @@@ static int ext4_statfs_project(struct s
                return PTR_ERR(dquot);
        spin_lock(&dquot->dq_dqb_lock);
  
-       limit = 0;
-       if (dquot->dq_dqb.dqb_bsoftlimit &&
-           (!limit || dquot->dq_dqb.dqb_bsoftlimit < limit))
-               limit = dquot->dq_dqb.dqb_bsoftlimit;
+       limit = dquot->dq_dqb.dqb_bsoftlimit;
        if (dquot->dq_dqb.dqb_bhardlimit &&
            (!limit || dquot->dq_dqb.dqb_bhardlimit < limit))
                limit = dquot->dq_dqb.dqb_bhardlimit;
                         (buf->f_blocks - curblock) : 0;
        }
  
-       limit = 0;
-       if (dquot->dq_dqb.dqb_isoftlimit &&
-           (!limit || dquot->dq_dqb.dqb_isoftlimit < limit))
-               limit = dquot->dq_dqb.dqb_isoftlimit;
+       limit = dquot->dq_dqb.dqb_isoftlimit;
        if (dquot->dq_dqb.dqb_ihardlimit &&
            (!limit || dquot->dq_dqb.dqb_ihardlimit < limit))
                limit = dquot->dq_dqb.dqb_ihardlimit;
@@@ -6043,7 -6033,7 +6033,7 @@@ static ssize_t ext4_quota_write(struct 
                bh = ext4_bread(handle, inode, blk,
                                EXT4_GET_BLOCKS_CREATE |
                                EXT4_GET_BLOCKS_METADATA_NOFAIL);
 -      } while (IS_ERR(bh) && (PTR_ERR(bh) == -ENOSPC) &&
 +      } while (PTR_ERR(bh) == -ENOSPC &&
                 ext4_should_retry_alloc(inode->i_sb, &retries));
        if (IS_ERR(bh))
                return PTR_ERR(bh);