[RFC PATCH 1/2] quota: allow DQF_ROOT_SQUASH on all quota formats
Kitae Yoo <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-ext4,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
ignore_hardlimit() exempts CAP_SYS_RESOURCE holders from enforcement of
hard limits and of soft limits whose grace time expired.
DQF_ROOT_SQUASH disables that exemption, but it has been confined to the
old v1 quota format since the quota format abstraction was introduced,
and commit ca6cb0918e87 ("quota: Verify flags passed to Q_SETINFO")
later made Q_SETINFO reject it explicitly on other formats.
That confinement predates generic project quota support. Project limits
bound the size of a directory tree rather than restrict a user, and are
commonly used for capacity isolation of container volumes and NFS
exports. There the exemption defeats the purpose: knfsd raises
CAP_SYS_RESOURCE for requests mapped to root on no_root_squash exports
(CAP_NFSD_SET), so any remote root write silently exceeds project hard
limits. XFS enforces project limits regardless of capabilities.
Lift the format restriction so the flag can be set per quota type
through Q_SETINFO on journaled quota as well. Existing setups keep their
behaviour: the flag stays clear unless explicitly set, and setting it
was previously rejected with -EINVAL on anything but QFMT_VFS_OLD -
accepting it there is the user-visible ABI change this patch makes.
Signed-off-by: Kitae Yoo <[email protected]>
---
fs/quota/dquot.c | 8 +-------
include/uapi/linux/quota.h | 2 +-
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 9850de3955..e431e72dfe 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1309,8 +1309,7 @@ static int ignore_hardlimit(struct dquot *dquot)
struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
return capable(CAP_SYS_RESOURCE) &&
- (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
- !(info->dqi_flags & DQF_ROOT_SQUASH));
+ !(info->dqi_flags & DQF_ROOT_SQUASH);
}
static int dquot_add_inodes(struct dquot *dquot, qsize_t inodes,
@@ -2900,11 +2899,6 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii)
if (!sb_has_quota_active(sb, type))
return -ESRCH;
mi = sb_dqopt(sb)->info + type;
- if (ii->i_fieldmask & QC_FLAGS) {
- if ((ii->i_flags & QCI_ROOT_SQUASH &&
- mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD))
- return -EINVAL;
- }
spin_lock(&dq_data_lock);
if (ii->i_fieldmask & QC_SPC_TIMER)
mi->dqi_bgrace = ii->i_spc_timelimit;
diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
index 52090105b8..a34f43519a 100644
--- a/include/uapi/linux/quota.h
+++ b/include/uapi/linux/quota.h
@@ -149,7 +149,7 @@ enum {
DQF_PRIVATE
};
-/* Root squash enabled (for v1 quota format) */
+/* Enforce limits also for CAP_SYS_RESOURCE processes */
#define DQF_ROOT_SQUASH (1 << DQF_ROOT_SQUASH_B)
/* Quota stored in a system file */
#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B)
--
2.50.1 (Apple Git-155)