aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-09-16 02:32:43 -0700
committerEric W. Biederman <ebiederm@xmission.com>2012-09-18 01:01:40 -0700
commit431f19744d15531825cdbc8e771b43854b0d005b (patch)
tree1c8927533fad647a9aab4f1e00030ce6bd20bf15
parent74a8a103789465c4e67f38d1abb5cea770002601 (diff)
userns: Convert quota netlink aka quota_send_warning
Modify quota_send_warning to take struct kqid instead a type and identifier pair. When sending netlink broadcasts always convert uids and quota identifiers into the intial user namespace. There is as yet no way to send a netlink broadcast message with different contents to receivers in different namespaces, so for the time being just map all of the identifiers into the initial user namespace which preserves the current behavior. Change the callers of quota_send_warning in gfs2, xfs and dquot to generate a struct kqid to pass to quota send warning. When all of the user namespaces convesions are complete a struct kqid values will be availbe without need for conversion, but a conversion is needed now to avoid needing to convert everything at once. Cc: Ben Myers <bpm@sgi.com> Cc: Alex Elder <elder@kernel.org> Cc: Dave Chinner <david@fromorbit.com> Cc: Jan Kara <jack@suse.cz> Cc: Steven Whitehouse <swhiteho@redhat.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r--fs/gfs2/quota.c12
-rw-r--r--fs/quota/dquot.c2
-rw-r--r--fs/quota/netlink.c10
-rw-r--r--fs/xfs/xfs_trans_dquot.c8
-rw-r--r--include/linux/quota.h4
-rw-r--r--init/Kconfig1
6 files changed, 22 insertions, 15 deletions
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index b3115392d68..d554dfff58e 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1070,8 +1070,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
print_message(qd, "exceeded");
- quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ?
- USRQUOTA : GRPQUOTA, qd->qd_id,
+ quota_send_warning(make_kqid(&init_user_ns,
+ test_bit(QDF_USER, &qd->qd_flags) ?
+ USRQUOTA : GRPQUOTA,
+ qd->qd_id),
sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN);
error = -EDQUOT;
@@ -1081,8 +1083,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
time_after_eq(jiffies, qd->qd_last_warn +
gfs2_tune_get(sdp,
gt_quota_warn_period) * HZ)) {
- quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ?
- USRQUOTA : GRPQUOTA, qd->qd_id,
+ quota_send_warning(make_kqid(&init_user_ns,
+ test_bit(QDF_USER, &qd->qd_flags) ?
+ USRQUOTA : GRPQUOTA,
+ qd->qd_id),
sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN);
error = print_message(qd, "warning");
qd->qd_last_warn = jiffies;
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 7714b169d64..80d33782246 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1236,7 +1236,7 @@ static void flush_warnings(struct dquot_warn *warn)
#ifdef CONFIG_PRINT_QUOTA_WARNING
print_warning(&warn[i]);
#endif
- quota_send_warning(warn[i].w_dq_type, warn[i].w_dq_id,
+ quota_send_warning(make_kqid(&init_user_ns, warn[i].w_dq_type, warn[i].w_dq_id),
warn[i].w_sb->s_dev, warn[i].w_type);
}
}
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index d67908b407d..16e8abb7709 100644
--- a/fs/quota/netlink.c
+++ b/fs/quota/netlink.c
@@ -30,7 +30,7 @@ static struct genl_family quota_genl_family = {
*
*/
-void quota_send_warning(short type, unsigned int id, dev_t dev,
+void quota_send_warning(struct kqid qid, dev_t dev,
const char warntype)
{
static atomic_t seq;
@@ -56,10 +56,11 @@ void quota_send_warning(short type, unsigned int id, dev_t dev,
"VFS: Cannot store netlink header in quota warning.\n");
goto err_out;
}
- ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type);
+ ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, qid.type);
if (ret)
goto attr_err_out;
- ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, id);
+ ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID,
+ from_kqid_munged(&init_user_ns, qid));
if (ret)
goto attr_err_out;
ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
@@ -71,7 +72,8 @@ void quota_send_warning(short type, unsigned int id, dev_t dev,
ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
if (ret)
goto attr_err_out;
- ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
+ ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID,
+ from_kuid_munged(&init_user_ns, current_uid()));
if (ret)
goto attr_err_out;
genlmsg_end(skb, msg_head);
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index bcb60542fcf..0c7fa54f309 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -578,9 +578,11 @@ xfs_quota_warn(
/* no warnings for project quotas - we just return ENOSPC later */
if (dqp->dq_flags & XFS_DQ_PROJ)
return;
- quota_send_warning((dqp->dq_flags & XFS_DQ_USER) ? USRQUOTA : GRPQUOTA,
- be32_to_cpu(dqp->q_core.d_id), mp->m_super->s_dev,
- type);
+ quota_send_warning(make_kqid(&init_user_ns,
+ (dqp->dq_flags & XFS_DQ_USER) ?
+ USRQUOTA : GRPQUOTA,
+ be32_to_cpu(dqp->q_core.d_id)),
+ mp->m_super->s_dev, type);
}
/*
diff --git a/include/linux/quota.h b/include/linux/quota.h
index f96427a949b..8b276042725 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -511,10 +511,10 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
}
#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-extern void quota_send_warning(short type, unsigned int id, dev_t dev,
+extern void quota_send_warning(struct kqid qid, dev_t dev,
const char warntype);
#else
-static inline void quota_send_warning(short type, unsigned int id, dev_t dev,
+static inline void quota_send_warning(struct kqid qid, dev_t dev,
const char warntype)
{
return;
diff --git a/init/Kconfig b/init/Kconfig
index 15bb1dcdebe..9c8aa8c4944 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -928,7 +928,6 @@ config UIDGID_CONVERTED
depends on IMA = n
depends on EVM = n
depends on QUOTA = n
- depends on QUOTA_NETLINK_INTERFACE = n
# Networking
depends on NET_9P = n