diff options
author | Jan Kara <jack@suse.cz> | 2016-09-05 23:08:16 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2016-09-05 23:08:16 -0400 |
commit | 49da939272f417ff94c40f132a308748b46efe68 (patch) | |
tree | e4389c240b9e8168ddc7cd0eb5de3015ca005421 /fs/ext4 | |
parent | 93e3b4e6631d2a74a8cf7429138096862ff9f452 (diff) |
ext4: enable quota enforcement based on mount options
When quota information is stored in quota files, we enable only quota
accounting on mount and enforcement is enabled only in response to
Q_QUOTAON quotactl. To make ext4 behavior consistent with XFS, we add a
possibility to enable quota enforcement on mount by specifying
corresponding quota mount option (usrquota, grpquota, prjquota).
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4.h | 12 | ||||
-rw-r--r-- | fs/ext4/super.c | 34 |
2 files changed, 33 insertions, 13 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ea31931386ec..0c2bf4444548 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1117,9 +1117,15 @@ struct ext4_inode_info { | |||
1117 | #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ | 1117 | #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ |
1118 | #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ | 1118 | #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ |
1119 | #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ | 1119 | #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ |
1120 | #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ | 1120 | #define EXT4_MOUNT_QUOTA 0x40000 /* Some quota option set */ |
1121 | #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ | 1121 | #define EXT4_MOUNT_USRQUOTA 0x80000 /* "old" user quota, |
1122 | #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ | 1122 | * enable enforcement for hidden |
1123 | * quota files */ | ||
1124 | #define EXT4_MOUNT_GRPQUOTA 0x100000 /* "old" group quota, enable | ||
1125 | * enforcement for hidden quota | ||
1126 | * files */ | ||
1127 | #define EXT4_MOUNT_PRJQUOTA 0x200000 /* Enable project quota | ||
1128 | * enforcement */ | ||
1123 | #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */ | 1129 | #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */ |
1124 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 1130 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
1125 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 1131 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3ec8708989ca..5819b0e8ff66 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1267,7 +1267,7 @@ enum { | |||
1267 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 1267 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
1268 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1268 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
1269 | Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, | 1269 | Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, |
1270 | Opt_usrquota, Opt_grpquota, Opt_i_version, Opt_dax, | 1270 | Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax, |
1271 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, | 1271 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, |
1272 | Opt_lazytime, Opt_nolazytime, | 1272 | Opt_lazytime, Opt_nolazytime, |
1273 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, | 1273 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
@@ -1327,6 +1327,7 @@ static const match_table_t tokens = { | |||
1327 | {Opt_noquota, "noquota"}, | 1327 | {Opt_noquota, "noquota"}, |
1328 | {Opt_quota, "quota"}, | 1328 | {Opt_quota, "quota"}, |
1329 | {Opt_usrquota, "usrquota"}, | 1329 | {Opt_usrquota, "usrquota"}, |
1330 | {Opt_prjquota, "prjquota"}, | ||
1330 | {Opt_barrier, "barrier=%u"}, | 1331 | {Opt_barrier, "barrier=%u"}, |
1331 | {Opt_barrier, "barrier"}, | 1332 | {Opt_barrier, "barrier"}, |
1332 | {Opt_nobarrier, "nobarrier"}, | 1333 | {Opt_nobarrier, "nobarrier"}, |
@@ -1546,8 +1547,11 @@ static const struct mount_opts { | |||
1546 | MOPT_SET | MOPT_Q}, | 1547 | MOPT_SET | MOPT_Q}, |
1547 | {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA, | 1548 | {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA, |
1548 | MOPT_SET | MOPT_Q}, | 1549 | MOPT_SET | MOPT_Q}, |
1550 | {Opt_prjquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_PRJQUOTA, | ||
1551 | MOPT_SET | MOPT_Q}, | ||
1549 | {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA | | 1552 | {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA | |
1550 | EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q}, | 1553 | EXT4_MOUNT_GRPQUOTA | EXT4_MOUNT_PRJQUOTA), |
1554 | MOPT_CLEAR | MOPT_Q}, | ||
1551 | {Opt_usrjquota, 0, MOPT_Q}, | 1555 | {Opt_usrjquota, 0, MOPT_Q}, |
1552 | {Opt_grpjquota, 0, MOPT_Q}, | 1556 | {Opt_grpjquota, 0, MOPT_Q}, |
1553 | {Opt_offusrjquota, 0, MOPT_Q}, | 1557 | {Opt_offusrjquota, 0, MOPT_Q}, |
@@ -1836,13 +1840,17 @@ static int parse_options(char *options, struct super_block *sb, | |||
1836 | return 0; | 1840 | return 0; |
1837 | } | 1841 | } |
1838 | #ifdef CONFIG_QUOTA | 1842 | #ifdef CONFIG_QUOTA |
1839 | if (ext4_has_feature_quota(sb) && | 1843 | /* |
1840 | (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) { | 1844 | * We do the test below only for project quotas. 'usrquota' and |
1841 | ext4_msg(sb, KERN_INFO, "Quota feature enabled, usrquota and grpquota " | 1845 | * 'grpquota' mount options are allowed even without quota feature |
1842 | "mount options ignored."); | 1846 | * to support legacy quotas in quota files. |
1843 | clear_opt(sb, USRQUOTA); | 1847 | */ |
1844 | clear_opt(sb, GRPQUOTA); | 1848 | if (test_opt(sb, PRJQUOTA) && !ext4_has_feature_project(sb)) { |
1845 | } else if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1849 | ext4_msg(sb, KERN_ERR, "Project quota feature not enabled. " |
1850 | "Cannot enable project quota enforcement."); | ||
1851 | return 0; | ||
1852 | } | ||
1853 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | ||
1846 | if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) | 1854 | if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) |
1847 | clear_opt(sb, USRQUOTA); | 1855 | clear_opt(sb, USRQUOTA); |
1848 | 1856 | ||
@@ -5250,12 +5258,18 @@ static int ext4_enable_quotas(struct super_block *sb) | |||
5250 | le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum), | 5258 | le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum), |
5251 | le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum) | 5259 | le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum) |
5252 | }; | 5260 | }; |
5261 | bool quota_mopt[EXT4_MAXQUOTAS] = { | ||
5262 | test_opt(sb, USRQUOTA), | ||
5263 | test_opt(sb, GRPQUOTA), | ||
5264 | test_opt(sb, PRJQUOTA), | ||
5265 | }; | ||
5253 | 5266 | ||
5254 | sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE; | 5267 | sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE; |
5255 | for (type = 0; type < EXT4_MAXQUOTAS; type++) { | 5268 | for (type = 0; type < EXT4_MAXQUOTAS; type++) { |
5256 | if (qf_inums[type]) { | 5269 | if (qf_inums[type]) { |
5257 | err = ext4_quota_enable(sb, type, QFMT_VFS_V1, | 5270 | err = ext4_quota_enable(sb, type, QFMT_VFS_V1, |
5258 | DQUOT_USAGE_ENABLED); | 5271 | DQUOT_USAGE_ENABLED | |
5272 | (quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0)); | ||
5259 | if (err) { | 5273 | if (err) { |
5260 | ext4_warning(sb, | 5274 | ext4_warning(sb, |
5261 | "Failed to enable quota tracking " | 5275 | "Failed to enable quota tracking " |