userns: Convert quota netlink aka quota_send_warning
authorEric W. Biederman <ebiederm@xmission.com>
Sun, 16 Sep 2012 09:32:43 +0000 (02:32 -0700)
committerEric W. Biederman <ebiederm@xmission.com>
Tue, 18 Sep 2012 08:01:40 +0000 (01:01 -0700)
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>
fs/gfs2/quota.c
fs/quota/dquot.c
fs/quota/netlink.c
fs/xfs/xfs_trans_dquot.c
include/linux/quota.h
init/Kconfig

index b3115392d68f6cd3cf3acf7fc071ab7367d16ef2..d554dfff58e3186a50ff7039aa8e795355924af6 100644 (file)
@@ -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;
index 7714b169d6467c96b388d8d890deae63344e2190..80d337822462180b6b5c290a42cfc7d1394d3fef 100644 (file)
@@ -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);
        }
 }
index d67908b407d99dbad1f3f91a1e0c561cbab60768..16e8abb7709ba04fb1bcc1520573acf568e68eb9 100644 (file)
@@ -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);
index bcb60542fcf18bdbcfef1633dcbaac355485e66d..0c7fa54f309e1da36012a924905e5226f147f4c4 100644 (file)
@@ -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);
 }
 
 /*
index f96427a949b2baabd3d82c0419d71d35fb2997b0..8b2760427252e469572dbb7b40bb5bd10ac34700 100644 (file)
@@ -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;
index 15bb1dcdebef340e439aac06fafe78214e58b921..9c8aa8c494433e392bfd46843d90b6edcee36384 100644 (file)
@@ -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