Whamcloud - gitweb
New tag 2.15.63
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / rhel7.7 / ext4-fix-project-with-unpatched-kernel.patch
1 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
2 index 388b6bcd..111ac5e1 100644
3 --- a/fs/ext4/ext4.h
4 +++ b/fs/ext4/ext4.h
5 @@ -1485,6 +1485,8 @@ struct ext4_sb_info {
6         struct ratelimit_state s_warning_ratelimit_state;
7         struct ratelimit_state s_msg_ratelimit_state;
8         struct dax_device *s_daxdev;
9 +
10 +       bool s_proj_kernel_supported;
11  };
12  
13  static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
14 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
15 index e6566eb9..ac0dd4a7 100644
16 --- a/fs/ext4/inode.c
17 +++ b/fs/ext4/inode.c
18 @@ -4390,6 +4390,17 @@ int ext4_get_projid(struct inode *inode, kprojid_t *projid)
19  {
20         struct ext4_super_block *sbi = EXT4_SB(inode->i_sb)->s_es;
21  
22 +       /*
23 +        * This is tricky and just used to detect whether kernel
24 +        * supports project quota, return error to make sure dquot_initialize()
25 +        * doesn't do anything except calling this function.
26 +        */
27 +       if (inode->i_ino == EXT4_ROOT_INO &&
28 +           !EXT4_SB(inode->i_sb)->s_proj_kernel_supported) {
29 +               EXT4_SB(inode->i_sb)->s_proj_kernel_supported = true;
30 +               return -EINVAL;
31 +       }
32 +
33         if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
34             !sbi->s_prj_quota_inum)
35                 return -EOPNOTSUPP;
36 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
37 index 1c81d178..bb92ea94 100644
38 --- a/fs/ext4/super.c
39 +++ b/fs/ext4/super.c
40 @@ -819,8 +819,11 @@ static inline void ext4_quota_off_umount(struct super_block *sb)
41         int type;
42  
43         /* Use our quota_off function to clear inode flags etc. */
44 -       for (type = 0; type < EXT4_MAXQUOTAS; type++)
45 +       for (type = 0; type < EXT4_MAXQUOTAS; type++) {
46 +               if (!EXT4_SB(sb)->s_proj_kernel_supported && type == PRJQUOTA)
47 +                       continue;
48                 ext4_quota_off(sb, type);
49 +       }
50  }
51  #else
52  static inline void ext4_quota_off_umount(struct super_block *sb)
53 @@ -2430,6 +2433,9 @@ static void ext4_orphan_cleanup(struct super_block *sb,
54         /* Turn off quotas if they were enabled for orphan cleanup */
55         if (quota_update) {
56                 for (i = 0; i < EXT4_MAXQUOTAS; i++) {
57 +                       if (!EXT4_SB(sb)->s_proj_kernel_supported &&
58 +                           i == PRJQUOTA)
59 +                               continue;
60                         if (sb_dqopt(sb)->files[i])
61                                 dquot_quota_off(sb, i);
62                 }
63 @@ -3630,6 +3636,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
64         int err = 0;
65         unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
66         ext4_group_t first_not_zeroed;
67 +       unsigned int quota_flags;
68  
69         if ((data && !orig_data) || !sbi)
70                 goto out_free_base;
71 @@ -4356,6 +4363,14 @@ no_journal:
72                 root = NULL;
73                 goto failed_mount4;
74         }
75 +       /*
76 +        * Enable project usage temporarily to give dquota_initialize() a
77 +        * chance to check whether kernel supports Project quota.
78 +        */
79 +       quota_flags = sb_dqopt(sb)->flags;
80 +       sb_dqopt(sb)->flags |= dquot_state_flag(DQUOT_USAGE_ENABLED, PRJQUOTA);
81 +       dquot_initialize(root);
82 +       sb_dqopt(sb)->flags = quota_flags;
83         if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
84                 ext4_msg(sb, KERN_ERR, "corrupt root inode, run e2fsck");
85                 iput(root);
86 @@ -5671,6 +5686,10 @@ static int ext4_enable_quotas(struct super_block *sb)
87  
88         sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
89         for (type = 0; type < EXT4_MAXQUOTAS; type++) {
90 +
91 +               if (!EXT4_SB(sb)->s_proj_kernel_supported && type == PRJQUOTA)
92 +                       continue;
93 +
94                 if (qf_inums[type]) {
95                         err = ext4_quota_enable(sb, type, QFMT_VFS_V1,
96                                                 DQUOT_USAGE_ENABLED);