Whamcloud - gitweb
d0b3cef27f47352cb197c64d879599c498e94d32
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / rhel7 / ext4-projid-quotas.patch
1 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
2 index eeb3d05..00f317c 100644
3 --- a/fs/ext4/ext4.h
4 +++ b/fs/ext4/ext4.h
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) */
14  };
15  
16 @@ -1185,7 +1187,7 @@ struct ext4_super_block {
17  #define EXT4_MF_FS_ABORTED     0x0002  /* Fatal error detected */
18  
19  /* Number of quota types we support */
20 -#define EXT4_MAXQUOTAS 2
21 +#define EXT4_MAXQUOTAS 3
22  
23  /*
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
27 --- a/fs/ext4/inode.c
28 +++ b/fs/ext4/inode.c
29 @@ -4101,7 +4101,10 @@ static inline void ext4_iget_extra_inode(struct inode *inode,
30  
31  int ext4_get_projid(struct inode *inode, kprojid_t *projid)
32  {
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;
35 +
36 +       if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
37 +           !sbi->s_prj_quota_inum)
38                 return -EOPNOTSUPP;
39         *projid = EXT4_I(inode)->i_projid;
40         return 0;
41 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
42 index 8189081..6a9d397 100644
43 --- a/fs/ext4/super.c
44 +++ b/fs/ext4/super.c
45 @@ -1043,8 +1043,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
46  }
47  
48  #ifdef CONFIG_QUOTA
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])
53  
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:
57         return err;
58  }
59  
60 +#ifdef CONFIG_QUOTA
61 +static int ext4_statfs_project(struct super_block *sb,
62 +                              kprojid_t projid, struct kstatfs *buf)
63 +{
64 +       struct kqid qid;
65 +       struct dquot *dquot;
66 +       u64 limit;
67 +       u64 curblock;
68 +
69 +       qid = make_kqid_projid(projid);
70 +       dquot = dqget(sb, qid);
71 +       if (IS_ERR(dquot))
72 +               return PTR_ERR(dquot);
73 +       spin_lock(&dq_data_lock);
74 +
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;
84 +       }
85 +
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;
91 +               buf->f_ffree =
92 +                       (buf->f_files > dquot->dq_dqb.dqb_curinodes) ?
93 +                        (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
94 +       }
95 +
96 +       spin_unlock(&dq_data_lock);
97 +       dqput(dquot);
98 +       return 0;
99 +}
100 +#endif
101 +
102  static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
103  {
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;
107         u64 fsid;
108         s64 bfree;
109 +       struct inode *inode = dentry->d_inode;
110         resv_blocks = EXT4_C2B(sbi, atomic64_read(&sbi->s_resv_clusters));
111  
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;
116  
117 +#ifdef CONFIG_QUOTA
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);
121 +#endif
122         return 0;
123  }
124  
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)
132         };
133  
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)
136         int type, err = 0;
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)
142         };
143  
144         sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;