[Devel] [PATCH rh7] quota: translate [ug]id relative to sb->s_user_ns

Konstantin Khorenko khorenko at virtuozzo.com
Tue Jun 27 11:57:59 MSK 2017


For filesystems mounted from a user namespace on-disk ids should
be translated relative to s_users_ns rather than init_user_ns.

https://jira.sw.ru/browse/PSBM-40075

Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 fs/quota/dquot.c      |  4 ++--
 fs/quota/netlink.c    |  4 ++--
 fs/quota/quota_tree.c | 23 +++++++++++------------
 fs/quota/quota_v1.c   |  4 ++--
 fs/quota/quota_v2.c   |  8 ++++----
 5 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index df89720..5191a72 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -251,7 +251,7 @@ static void __dquot_initialize(struct inode *inode, int type);
 static inline unsigned int
 hashfn(const struct super_block *sb, struct kqid qid)
 {
-	unsigned int id = from_kqid(&init_user_ns, qid);
+	unsigned int id = from_kqid(sb->s_user_ns, qid);
 	int type = qid.type;
 	unsigned long tmp;
 
@@ -732,7 +732,7 @@ void dqput(struct dquot *dquot)
 	if (!atomic_read(&dquot->dq_count)) {
 		quota_error(dquot->dq_sb, "trying to free free dquot of %s %d",
 			    quotatypes[dquot->dq_id.type],
-			    from_kqid(&init_user_ns, dquot->dq_id));
+			    from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id));
 		BUG();
 	}
 #endif
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index 72d2917..ca1f661 100644
--- a/fs/quota/netlink.c
+++ b/fs/quota/netlink.c
@@ -72,7 +72,7 @@ void quota_send_warning(struct kqid qid, dev_t dev,
 	if (ret)
 		goto attr_err_out;
 	ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID,
-			  from_kqid_munged(&init_user_ns, qid));
+			  from_kqid_munged(current_user_ns(), qid));
 	if (ret)
 		goto attr_err_out;
 	ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
@@ -85,7 +85,7 @@ void quota_send_warning(struct kqid qid, dev_t dev,
 	if (ret)
 		goto attr_err_out;
 	ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID,
-			  from_kuid_munged(&init_user_ns, current_uid()));
+			  from_kuid_munged(current_user_ns(), current_uid()));
 	if (ret)
 		goto attr_err_out;
 	genlmsg_end(skb, msg_head);
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c
index d65877f..50bcd6b 100644
--- a/fs/quota/quota_tree.c
+++ b/fs/quota/quota_tree.c
@@ -22,10 +22,10 @@ MODULE_LICENSE("GPL");
 
 #define __QUOTA_QT_PARANOIA
 
-static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
+static int get_index(struct qtree_mem_dqinfo *info, struct dquot *dquot, int depth)
 {
 	unsigned int epb = info->dqi_usable_bs >> 2;
-	qid_t id = from_kqid(&init_user_ns, qid);
+	qid_t id = from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id);
 
 	depth = info->dqi_qtree_depth - depth - 1;
 	while (depth--)
@@ -314,7 +314,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 		}
 	}
 	ref = (__le32 *)buf;
-	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
+	newblk = le32_to_cpu(ref[get_index(info, dquot, depth)]);
 	if (!newblk)
 		newson = 1;
 	if (depth == info->dqi_qtree_depth - 1) {
@@ -323,7 +323,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 			quota_error(dquot->dq_sb, "Inserting already present "
 				    "quota entry (block %u)",
 				    le32_to_cpu(ref[get_index(info,
-						dquot->dq_id, depth)]));
+						dquot, depth)]));
 			ret = -EIO;
 			goto out_buf;
 		}
@@ -333,8 +333,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 		ret = do_insert_tree(info, dquot, &newblk, depth+1);
 	}
 	if (newson && ret >= 0) {
-		ref[get_index(info, dquot->dq_id, depth)] =
-							cpu_to_le32(newblk);
+		ref[get_index(info, dquot, depth)] = cpu_to_le32(newblk);
 		ret = write_blk(info, *treeblk, buf);
 	} else if (newact && ret < 0) {
 		put_free_dqblk(info, buf, *treeblk);
@@ -473,7 +472,7 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 			    *blk);
 		goto out_buf;
 	}
-	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
+	newblk = le32_to_cpu(ref[get_index(info, dquot, depth)]);
 	if (depth == info->dqi_qtree_depth - 1) {
 		ret = free_dqentry(info, dquot, newblk);
 		newblk = 0;
@@ -482,7 +481,7 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 	}
 	if (ret >= 0 && !newblk) {
 		int i;
-		ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0);
+		ref[get_index(info, dquot, depth)] = cpu_to_le32(0);
 		/* Block got empty? */
 		for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++)
 			;
@@ -541,7 +540,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
 	if (i == qtree_dqstr_in_blk(info)) {
 		quota_error(dquot->dq_sb,
 			    "Quota for id %u referenced but not present",
-			    from_kqid(&init_user_ns, dquot->dq_id));
+			    from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id));
 		ret = -EIO;
 		goto out_buf;
 	} else {
@@ -570,7 +569,7 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
 		goto out_buf;
 	}
 	ret = 0;
-	blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
+	blk = le32_to_cpu(ref[get_index(info, dquot, depth)]);
 	if (!blk)	/* No reference? */
 		goto out_buf;
 	if (depth < info->dqi_qtree_depth - 1)
@@ -611,7 +610,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 			if (offset < 0)
 				quota_error(sb,"Can't read quota structure "
 					    "for id %u",
-					    from_kqid(&init_user_ns,
+					    from_kqid(sb->s_user_ns,
 						      dquot->dq_id));
 			dquot->dq_off = 0;
 			set_bit(DQ_FAKE_B, &dquot->dq_flags);
@@ -630,7 +629,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 		if (ret >= 0)
 			ret = -EIO;
 		quota_error(sb, "Error while reading quota structure for id %u",
-			    from_kqid(&init_user_ns, dquot->dq_id));
+			    from_kqid(sb->s_user_ns, dquot->dq_id));
 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
 		kfree(ddquot);
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c
index 469c684..3709bce 100644
--- a/fs/quota/quota_v1.c
+++ b/fs/quota/quota_v1.c
@@ -64,7 +64,7 @@ static int v1_read_dqblk(struct dquot *dquot)
 	memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
 	dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk,
 			sizeof(struct v1_disk_dqblk),
-			v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));
+			v1_dqoff(from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id)));
 
 	v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
 	if (dquot->dq_dqb.dqb_bhardlimit == 0 &&
@@ -95,7 +95,7 @@ static int v1_commit_dqblk(struct dquot *dquot)
 	if (sb_dqopt(dquot->dq_sb)->files[type])
 		ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
 			(char *)&dqblk, sizeof(struct v1_disk_dqblk),
-			v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));
+			v1_dqoff(from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id)));
 	if (ret != sizeof(struct v1_disk_dqblk)) {
 		quota_error(dquot->dq_sb, "dquota write failed");
 		if (ret >= 0)
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index 02751ec..c6eca0c 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -206,7 +206,7 @@ static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
 	d->dqb_bsoftlimit = cpu_to_le32(v2_stoqb(m->dqb_bsoftlimit));
 	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
 	d->dqb_btime = cpu_to_le64(m->dqb_btime);
-	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
+	d->dqb_id = cpu_to_le32(from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id));
 	if (qtree_entry_unused(info, dp))
 		d->dqb_itime = cpu_to_le64(1);
 }
@@ -219,7 +219,7 @@ static int v2r0_is_id(void *dp, struct dquot *dquot)
 
 	if (qtree_entry_unused(info, dp))
 		return 0;
-	return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
+	return qid_eq(make_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id.type,
 				le32_to_cpu(d->dqb_id)),
 		      dquot->dq_id);
 }
@@ -259,7 +259,7 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
 	d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
 	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
 	d->dqb_btime = cpu_to_le64(m->dqb_btime);
-	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
+	d->dqb_id = cpu_to_le32(from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id));
 	if (qtree_entry_unused(info, dp))
 		d->dqb_itime = cpu_to_le64(1);
 }
@@ -272,7 +272,7 @@ static int v2r1_is_id(void *dp, struct dquot *dquot)
 
 	if (qtree_entry_unused(info, dp))
 		return 0;
-	return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
+	return qid_eq(make_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id.type,
 				le32_to_cpu(d->dqb_id)),
 		      dquot->dq_id);
 }
-- 
1.8.3.1



More information about the Devel mailing list