1 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
2 index eeb3d05..00f317c 100644
5 @@ -1170,7 +1170,9 @@ struct ext4_super_block {
6 __le32 s_grp_quota_inum; /* inode for tracking group quota */
7 __le32 s_overhead_clusters; /* overhead blocks/clusters in fs */
8 __le32 s_backup_bgs[2]; /* groups with sparse_super2 SBs */
9 - __le32 s_reserved[106]; /* Padding to the end of the block */
10 + __le32 s_padding[6]; /* reserved for upstream usage */
11 + __le32 s_prj_quota_inum; /* inode for tracking project quota */
12 + __le32 s_reserved[99]; /* Padding to the end of the block */
13 __le32 s_checksum; /* crc32c(superblock) */
16 @@ -1185,7 +1187,7 @@ struct ext4_super_block {
17 #define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
19 /* Number of quota types we support */
20 -#define EXT4_MAXQUOTAS 2
21 +#define EXT4_MAXQUOTAS 3
24 * fourth extended-fs super-block data in memory
25 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
26 index 34877ac..9f38b3f 100644
29 @@ -4101,7 +4101,10 @@ static inline void ext4_iget_extra_inode(struct inode *inode,
31 int ext4_get_projid(struct inode *inode, kprojid_t *projid)
33 - if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT))
34 + struct ext4_super_block *sbi = EXT4_SB(inode->i_sb)->s_es;
36 + if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
37 + !sbi->s_prj_quota_inum)
39 *projid = EXT4_I(inode)->i_projid;
41 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
42 index 8189081..6a9d397 100644
45 @@ -1043,8 +1043,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
49 -#define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
50 -#define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
51 +static char *quotatypes[] = INITQFNAMES;
52 +#define QTYPE2NAME(t) (quotatypes[t])
54 static int ext4_write_dquot(struct dquot *dquot);
55 static int ext4_acquire_dquot(struct dquot *dquot);
56 @@ -5101,6 +5101,48 @@ restore_opts:
61 +static int ext4_statfs_project(struct super_block *sb,
62 + kprojid_t projid, struct kstatfs *buf)
65 + struct dquot *dquot;
69 + qid = make_kqid_projid(projid);
70 + dquot = dqget(sb, qid);
72 + return PTR_ERR(dquot);
73 + spin_lock(&dq_data_lock);
75 + limit = dquot->dq_dqb.dqb_bsoftlimit ?
76 + dquot->dq_dqb.dqb_bsoftlimit :
77 + dquot->dq_dqb.dqb_bhardlimit;
78 + if (limit && buf->f_blocks * buf->f_bsize > limit) {
79 + curblock = dquot->dq_dqb.dqb_curspace / buf->f_bsize;
80 + buf->f_blocks = limit / buf->f_bsize;
81 + buf->f_bfree = buf->f_bavail =
82 + (buf->f_blocks > curblock) ?
83 + (buf->f_blocks - curblock) : 0;
86 + limit = dquot->dq_dqb.dqb_isoftlimit ?
87 + dquot->dq_dqb.dqb_isoftlimit :
88 + dquot->dq_dqb.dqb_ihardlimit;
89 + if (limit && buf->f_files > limit) {
90 + buf->f_files = limit;
92 + (buf->f_files > dquot->dq_dqb.dqb_curinodes) ?
93 + (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
96 + spin_unlock(&dq_data_lock);
102 static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
104 struct super_block *sb = dentry->d_sb;
105 @@ -5109,6 +5151,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
106 ext4_fsblk_t overhead = 0, resv_blocks;
109 + struct inode *inode = dentry->d_inode;
110 resv_blocks = EXT4_C2B(sbi, atomic64_read(&sbi->s_resv_clusters));
112 if (!test_opt(sb, MINIX_DF))
113 @@ -5133,6 +5176,11 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
114 buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL;
115 buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL;
118 + if (ext4_test_inode_flag(inode, EXT4_INODE_PROJINHERIT) &&
119 + sb_has_quota_limits_enabled(sb, PRJQUOTA))
120 + ext4_statfs_project(sb, EXT4_I(inode)->i_projid, buf);
125 @@ -5297,7 +5345,8 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
126 struct inode *qf_inode;
127 unsigned long qf_inums[EXT4_MAXQUOTAS] = {
128 le32_to_cpu(EXT4_SB(sb)->s_es->s_usr_quota_inum),
129 - le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
130 + le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
131 + le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
134 BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA));
135 @@ -5325,7 +5374,8 @@ static int ext4_enable_quotas(struct super_block *sb)
137 unsigned long qf_inums[EXT4_MAXQUOTAS] = {
138 le32_to_cpu(EXT4_SB(sb)->s_es->s_usr_quota_inum),
139 - le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
140 + le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
141 + le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
144 sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;