1 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
2 index 388b6bcd..111ac5e1 100644
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;
10 + bool s_proj_kernel_supported;
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
18 @@ -4390,6 +4390,17 @@ int ext4_get_projid(struct inode *inode, kprojid_t *projid)
20 struct ext4_super_block *sbi = EXT4_SB(inode->i_sb)->s_es;
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.
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;
33 if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
34 !sbi->s_prj_quota_inum)
36 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
37 index 1c81d178..bb92ea94 100644
40 @@ -819,8 +819,11 @@ static inline void ext4_quota_off_umount(struct super_block *sb)
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)
48 ext4_quota_off(sb, type);
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 */
56 for (i = 0; i < EXT4_MAXQUOTAS; i++) {
57 + if (!EXT4_SB(sb)->s_proj_kernel_supported &&
60 if (sb_dqopt(sb)->files[i])
61 dquot_quota_off(sb, i);
63 @@ -3630,6 +3636,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
65 unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
66 ext4_group_t first_not_zeroed;
67 + unsigned int quota_flags;
69 if ((data && !orig_data) || !sbi)
71 @@ -4356,6 +4363,14 @@ no_journal:
76 + * Enable project usage temporarily to give dquota_initialize() a
77 + * chance to check whether kernel supports Project quota.
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");
86 @@ -5671,6 +5686,10 @@ static int ext4_enable_quotas(struct super_block *sb)
88 sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
89 for (type = 0; type < EXT4_MAXQUOTAS; type++) {
91 + if (!EXT4_SB(sb)->s_proj_kernel_supported && type == PRJQUOTA)
95 err = ext4_quota_enable(sb, type, QFMT_VFS_V1,