[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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.