]> 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]>
Sun, 22 Dec 2019 18:41:48 +0000 (10:41 -0800)
committerLinus Torvalds <[email protected]>
Sun, 22 Dec 2019 18:41:48 +0000 (10:41 -0800)
Pull ext4 bug fixes from Ted Ts'o:
 "Ext4 bug fixes, including a regression fix"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: clarify impact of 'commit' mount option
  ext4: fix unused-but-set-variable warning in ext4_add_entry()
  jbd2: fix kernel-doc notation warning
  ext4: use RCU API in debug_print_tree
  ext4: validate the debug_want_extra_isize mount option at parse time
  ext4: reserve revoke credits in __ext4_new_inode
  ext4: unlock on error in ext4_expand_extra_isize()
  ext4: optimize __ext4_check_dir_entry()
  ext4: check for directory entries too close to block end
  ext4: fix ext4_empty_dir() for directories with holes

1  2 
fs/ext4/inode.c
fs/ext4/super.c
include/linux/jbd2.h

diff --combined fs/ext4/inode.c
index 28f28de0c1b67e116228f3413bd322bb681f5074,16e72621e9952fc502d469f0a6cb2a4bc40ae4f7..629a25d999f07d17977783439162163dd4f89d7a
@@@ -5385,15 -5385,12 +5385,15 @@@ int ext4_getattr(const struct path *pat
                stat->attributes |= STATX_ATTR_IMMUTABLE;
        if (flags & EXT4_NODUMP_FL)
                stat->attributes |= STATX_ATTR_NODUMP;
 +      if (flags & EXT4_VERITY_FL)
 +              stat->attributes |= STATX_ATTR_VERITY;
  
        stat->attributes_mask |= (STATX_ATTR_APPEND |
                                  STATX_ATTR_COMPRESSED |
                                  STATX_ATTR_ENCRYPTED |
                                  STATX_ATTR_IMMUTABLE |
 -                                STATX_ATTR_NODUMP);
 +                                STATX_ATTR_NODUMP |
 +                                STATX_ATTR_VERITY);
  
        generic_fillattr(inode, stat);
        return 0;
@@@ -5692,7 -5689,7 +5692,7 @@@ int ext4_expand_extra_isize(struct inod
        error = ext4_journal_get_write_access(handle, iloc->bh);
        if (error) {
                brelse(iloc->bh);
-               goto out_stop;
+               goto out_unlock;
        }
  
        error = __ext4_expand_extra_isize(inode, new_extra_isize, iloc,
        if (!error)
                error = rc;
  
+ out_unlock:
        ext4_write_unlock_xattr(inode, &no_expand);
- out_stop:
        ext4_journal_stop(handle);
        return error;
  }
diff --combined fs/ext4/super.c
index 1d82b56d9b11f362b35582ab0f804a5ca44f0189,46b6d5b150ac9f665341a11968c292f24e32e249..2937a8873fe135efc165e4ba954ef2855e362696
@@@ -1345,18 -1345,6 +1345,18 @@@ static bool ext4_dummy_context(struct i
        return DUMMY_ENCRYPTION_ENABLED(EXT4_SB(inode->i_sb));
  }
  
 +static bool ext4_has_stable_inodes(struct super_block *sb)
 +{
 +      return ext4_has_feature_stable_inodes(sb);
 +}
 +
 +static void ext4_get_ino_and_lblk_bits(struct super_block *sb,
 +                                     int *ino_bits_ret, int *lblk_bits_ret)
 +{
 +      *ino_bits_ret = 8 * sizeof(EXT4_SB(sb)->s_es->s_inodes_count);
 +      *lblk_bits_ret = 8 * sizeof(ext4_lblk_t);
 +}
 +
  static const struct fscrypt_operations ext4_cryptops = {
        .key_prefix             = "ext4:",
        .get_context            = ext4_get_context,
        .dummy_context          = ext4_dummy_context,
        .empty_dir              = ext4_empty_dir,
        .max_namelen            = EXT4_NAME_LEN,
 +      .has_stable_inodes      = ext4_has_stable_inodes,
 +      .get_ino_and_lblk_bits  = ext4_get_ino_and_lblk_bits,
  };
  #endif
  
@@@ -1900,6 -1886,13 +1900,13 @@@ static int handle_mount_opt(struct supe
                }
                sbi->s_commit_interval = HZ * arg;
        } else if (token == Opt_debug_want_extra_isize) {
+               if ((arg & 1) ||
+                   (arg < 4) ||
+                   (arg > (sbi->s_inode_size - EXT4_GOOD_OLD_INODE_SIZE))) {
+                       ext4_msg(sb, KERN_ERR,
+                                "Invalid want_extra_isize %d", arg);
+                       return -1;
+               }
                sbi->s_want_extra_isize = arg;
        } else if (token == Opt_max_batch_time) {
                sbi->s_max_batch_time = arg;
@@@ -3554,40 -3547,6 +3561,6 @@@ int ext4_calculate_overhead(struct supe
        return 0;
  }
  
- static void ext4_clamp_want_extra_isize(struct super_block *sb)
- {
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       struct ext4_super_block *es = sbi->s_es;
-       unsigned def_extra_isize = sizeof(struct ext4_inode) -
-                                               EXT4_GOOD_OLD_INODE_SIZE;
-       if (sbi->s_inode_size == EXT4_GOOD_OLD_INODE_SIZE) {
-               sbi->s_want_extra_isize = 0;
-               return;
-       }
-       if (sbi->s_want_extra_isize < 4) {
-               sbi->s_want_extra_isize = def_extra_isize;
-               if (ext4_has_feature_extra_isize(sb)) {
-                       if (sbi->s_want_extra_isize <
-                           le16_to_cpu(es->s_want_extra_isize))
-                               sbi->s_want_extra_isize =
-                                       le16_to_cpu(es->s_want_extra_isize);
-                       if (sbi->s_want_extra_isize <
-                           le16_to_cpu(es->s_min_extra_isize))
-                               sbi->s_want_extra_isize =
-                                       le16_to_cpu(es->s_min_extra_isize);
-               }
-       }
-       /* Check if enough inode space is available */
-       if ((sbi->s_want_extra_isize > sbi->s_inode_size) ||
-           (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize >
-                                                       sbi->s_inode_size)) {
-               sbi->s_want_extra_isize = def_extra_isize;
-               ext4_msg(sb, KERN_INFO,
-                        "required extra inode space not available");
-       }
- }
  static void ext4_set_resv_clusters(struct super_block *sb)
  {
        ext4_fsblk_t resv_clusters;
@@@ -3795,6 -3754,68 +3768,68 @@@ static int ext4_fill_super(struct super
         */
        sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
  
+       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;
+       } else {
+               sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
+               sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
+               if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) {
+                       ext4_msg(sb, KERN_ERR, "invalid first ino: %u",
+                                sbi->s_first_ino);
+                       goto failed_mount;
+               }
+               if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) ||
+                   (!is_power_of_2(sbi->s_inode_size)) ||
+                   (sbi->s_inode_size > blocksize)) {
+                       ext4_msg(sb, KERN_ERR,
+                              "unsupported inode size: %d",
+                              sbi->s_inode_size);
+                       goto failed_mount;
+               }
+               /*
+                * i_atime_extra is the last extra field available for
+                * [acm]times in struct ext4_inode. Checking for that
+                * field should suffice to ensure we have extra space
+                * for all three.
+                */
+               if (sbi->s_inode_size >= offsetof(struct ext4_inode, i_atime_extra) +
+                       sizeof(((struct ext4_inode *)0)->i_atime_extra)) {
+                       sb->s_time_gran = 1;
+                       sb->s_time_max = EXT4_EXTRA_TIMESTAMP_MAX;
+               } else {
+                       sb->s_time_gran = NSEC_PER_SEC;
+                       sb->s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX;
+               }
+               sb->s_time_min = EXT4_TIMESTAMP_MIN;
+       }
+       if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
+               sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
+                       EXT4_GOOD_OLD_INODE_SIZE;
+               if (ext4_has_feature_extra_isize(sb)) {
+                       unsigned v, max = (sbi->s_inode_size -
+                                          EXT4_GOOD_OLD_INODE_SIZE);
+                       v = le16_to_cpu(es->s_want_extra_isize);
+                       if (v > max) {
+                               ext4_msg(sb, KERN_ERR,
+                                        "bad s_want_extra_isize: %d", v);
+                               goto failed_mount;
+                       }
+                       if (sbi->s_want_extra_isize < v)
+                               sbi->s_want_extra_isize = v;
+                       v = le16_to_cpu(es->s_min_extra_isize);
+                       if (v > max) {
+                               ext4_msg(sb, KERN_ERR,
+                                        "bad s_min_extra_isize: %d", v);
+                               goto failed_mount;
+                       }
+                       if (sbi->s_want_extra_isize < v)
+                               sbi->s_want_extra_isize = v;
+               }
+       }
        if (sbi->s_es->s_mount_opts[0]) {
                char *s_mount_opts = kstrndup(sbi->s_es->s_mount_opts,
                                              sizeof(sbi->s_es->s_mount_opts),
                                                      has_huge_files);
        sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
  
-       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;
-       } else {
-               sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
-               sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
-               if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) {
-                       ext4_msg(sb, KERN_ERR, "invalid first ino: %u",
-                                sbi->s_first_ino);
-                       goto failed_mount;
-               }
-               if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) ||
-                   (!is_power_of_2(sbi->s_inode_size)) ||
-                   (sbi->s_inode_size > blocksize)) {
-                       ext4_msg(sb, KERN_ERR,
-                              "unsupported inode size: %d",
-                              sbi->s_inode_size);
-                       goto failed_mount;
-               }
-               /*
-                * i_atime_extra is the last extra field available for [acm]times in
-                * struct ext4_inode. Checking for that field should suffice to ensure
-                * we have extra space for all three.
-                */
-               if (sbi->s_inode_size >= offsetof(struct ext4_inode, i_atime_extra) +
-                       sizeof(((struct ext4_inode *)0)->i_atime_extra)) {
-                       sb->s_time_gran = 1;
-                       sb->s_time_max = EXT4_EXTRA_TIMESTAMP_MAX;
-               } else {
-                       sb->s_time_gran = NSEC_PER_SEC;
-                       sb->s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX;
-               }
-               sb->s_time_min = EXT4_TIMESTAMP_MIN;
-       }
        sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
        if (ext4_has_feature_64bit(sb)) {
                if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
@@@ -4517,8 -4502,6 +4516,6 @@@ no_journal
        } else if (ret)
                goto failed_mount4a;
  
-       ext4_clamp_want_extra_isize(sb);
        ext4_set_resv_clusters(sb);
  
        err = ext4_setup_system_zone(sb);
@@@ -5306,8 -5289,6 +5303,6 @@@ static int ext4_remount(struct super_bl
                goto restore_opts;
        }
  
-       ext4_clamp_want_extra_isize(sb);
        if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^
            test_opt(sb, JOURNAL_CHECKSUM)) {
                ext4_msg(sb, KERN_ERR, "changing journal_checksum "
@@@ -5834,7 -5815,7 +5829,7 @@@ static int ext4_quota_enable(struct sup
        /* Don't account quota for quota files to avoid recursion */
        qf_inode->i_flags |= S_NOQUOTA;
        lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA);
 -      err = dquot_enable(qf_inode, type, format_id, flags);
 +      err = dquot_load_quota_inode(qf_inode, type, format_id, flags);
        if (err)
                lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL);
        iput(qf_inode);
diff --combined include/linux/jbd2.h
index 29dce6ff6bae88fd8c367a47b0fca1eb0f790481,89bf48a8179857ff674ecd493f9c9b21bda5456a..ce44b687d02ba16d0b10334cf02b3400b2ee2b4a
@@@ -457,7 -457,7 +457,7 @@@ struct jbd2_revoke_table_s
   * @h_journal: Which journal handle belongs to - used iff h_reserved set.
   * @h_rsv_handle: Handle reserved for finishing the logical operation.
   * @h_total_credits: Number of remaining buffers we are allowed to add to
-       journal. These are dirty buffers and revoke descriptor blocks.
+  *    journal. These are dirty buffers and revoke descriptor blocks.
   * @h_revoke_credits: Number of remaining revoke records available for handle
   * @h_ref: Reference count on this handle.
   * @h_err: Field for caller's use to track errors through large fs operations.
@@@ -1169,7 -1169,7 +1169,7 @@@ struct journal_
  #define jbd2_might_wait_for_commit(j) \
        do { \
                rwsem_acquire(&j->j_trans_commit_map, 0, 0, _THIS_IP_); \
 -              rwsem_release(&j->j_trans_commit_map, 1, _THIS_IP_); \
 +              rwsem_release(&j->j_trans_commit_map, _THIS_IP_); \
        } while (0)
  
  /* journal feature predicate functions */
This page took 0.135739 seconds and 4 git commands to generate.