Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 327267
b: refs/heads/master
c: e8a3e47
h: refs/heads/master
i:
  327265: bfad851
  327263: 0aee51d
v: v3
  • Loading branch information
Eric W. Biederman committed Sep 18, 2012
1 parent 53aae45 commit 5e4908c
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f76d207a66c3a53defea67e7d36c3eb1b7d6d61d
refs/heads/master: e8a3e4719b7ec19288c56f22623f537cb78885c1
2 changes: 1 addition & 1 deletion trunk/fs/quota/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ obj-$(CONFIG_QUOTA) += dquot.o
obj-$(CONFIG_QFMT_V1) += quota_v1.o
obj-$(CONFIG_QFMT_V2) += quota_v2.o
obj-$(CONFIG_QUOTA_TREE) += quota_tree.o
obj-$(CONFIG_QUOTACTL) += quota.o
obj-$(CONFIG_QUOTACTL) += quota.o kqid.o
obj-$(CONFIG_QUOTACTL_COMPAT) += compat.o
obj-$(CONFIG_QUOTA_NETLINK_INTERFACE) += netlink.o
132 changes: 132 additions & 0 deletions trunk/fs/quota/kqid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <linux/fs.h>
#include <linux/quota.h>
#include <linux/export.h>

/**
* qid_eq - Test to see if to kquid values are the same
* @left: A qid value
* @right: Another quid value
*
* Return true if the two qid values are equal and false otherwise.
*/
bool qid_eq(struct kqid left, struct kqid right)
{
if (left.type != right.type)
return false;
switch(left.type) {
case USRQUOTA:
return uid_eq(left.uid, right.uid);
case GRPQUOTA:
return gid_eq(left.gid, right.gid);
case PRJQUOTA:
return projid_eq(left.projid, right.projid);
default:
BUG();
}
}
EXPORT_SYMBOL(qid_eq);

/**
* qid_lt - Test to see if one qid value is less than another
* @left: The possibly lesser qid value
* @right: The possibly greater qid value
*
* Return true if left is less than right and false otherwise.
*/
bool qid_lt(struct kqid left, struct kqid right)
{
if (left.type < right.type)
return true;
if (left.type > right.type)
return false;
switch (left.type) {
case USRQUOTA:
return uid_lt(left.uid, right.uid);
case GRPQUOTA:
return gid_lt(left.gid, right.gid);
case PRJQUOTA:
return projid_lt(left.projid, right.projid);
default:
BUG();
}
}
EXPORT_SYMBOL(qid_lt);

/**
* from_kqid - Create a qid from a kqid user-namespace pair.
* @targ: The user namespace we want a qid in.
* @kuid: The kernel internal quota identifier to start with.
*
* Map @kqid into the user-namespace specified by @targ and
* return the resulting qid.
*
* There is always a mapping into the initial user_namespace.
*
* If @kqid has no mapping in @targ (qid_t)-1 is returned.
*/
qid_t from_kqid(struct user_namespace *targ, struct kqid kqid)
{
switch (kqid.type) {
case USRQUOTA:
return from_kuid(targ, kqid.uid);
case GRPQUOTA:
return from_kgid(targ, kqid.gid);
case PRJQUOTA:
return from_kprojid(targ, kqid.projid);
default:
BUG();
}
}
EXPORT_SYMBOL(from_kqid);

/**
* from_kqid_munged - Create a qid from a kqid user-namespace pair.
* @targ: The user namespace we want a qid in.
* @kqid: The kernel internal quota identifier to start with.
*
* Map @kqid into the user-namespace specified by @targ and
* return the resulting qid.
*
* There is always a mapping into the initial user_namespace.
*
* Unlike from_kqid from_kqid_munged never fails and always
* returns a valid projid. This makes from_kqid_munged
* appropriate for use in places where failing to provide
* a qid_t is not a good option.
*
* If @kqid has no mapping in @targ the kqid.type specific
* overflow identifier is returned.
*/
qid_t from_kqid_munged(struct user_namespace *targ, struct kqid kqid)
{
switch (kqid.type) {
case USRQUOTA:
return from_kuid_munged(targ, kqid.uid);
case GRPQUOTA:
return from_kgid_munged(targ, kqid.gid);
case PRJQUOTA:
return from_kprojid_munged(targ, kqid.projid);
default:
BUG();
}
}
EXPORT_SYMBOL(from_kqid_munged);

/**
* qid_valid - Report if a valid value is stored in a kqid.
* @qid: The kernel internal quota identifier to test.
*/
bool qid_valid(struct kqid qid)
{
switch (qid.type) {
case USRQUOTA:
return uid_valid(qid.uid);
case GRPQUOTA:
return gid_valid(qid.gid);
case PRJQUOTA:
return projid_valid(qid.projid);
default:
BUG();
}
}
EXPORT_SYMBOL(qid_valid);
125 changes: 125 additions & 0 deletions trunk/include/linux/quota.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,135 @@ enum {
#include <linux/dqblk_v2.h>

#include <linux/atomic.h>
#include <linux/uidgid.h>
#include <linux/projid.h>

#undef USRQUOTA
#undef GRPQUOTA
enum quota_type {
USRQUOTA = 0, /* element used for user quotas */
GRPQUOTA = 1, /* element used for group quotas */
PRJQUOTA = 2, /* element used for project quotas */
};

typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
typedef long long qsize_t; /* Type in which we store sizes */

struct kqid { /* Type in which we store the quota identifier */
union {
kuid_t uid;
kgid_t gid;
kprojid_t projid;
};
enum quota_type type; /* USRQUOTA (uid) or GRPQUOTA (gid) or PRJQUOTA (projid) */
};

extern bool qid_eq(struct kqid left, struct kqid right);
extern bool qid_lt(struct kqid left, struct kqid right);
extern qid_t from_kqid(struct user_namespace *to, struct kqid qid);
extern qid_t from_kqid_munged(struct user_namespace *to, struct kqid qid);
extern bool qid_valid(struct kqid qid);

/**
* make_kqid - Map a user-namespace, type, qid tuple into a kqid.
* @from: User namespace that the qid is in
* @type: The type of quota
* @qid: Quota identifier
*
* Maps a user-namespace, type qid tuple into a kernel internal
* kqid, and returns that kqid.
*
* When there is no mapping defined for the user-namespace, type,
* qid tuple an invalid kqid is returned. Callers are expected to
* test for and handle handle invalid kqids being returned.
* Invalid kqids may be tested for using qid_valid().
*/
static inline struct kqid make_kqid(struct user_namespace *from,
enum quota_type type, qid_t qid)
{
struct kqid kqid;

kqid.type = type;
switch (type) {
case USRQUOTA:
kqid.uid = make_kuid(from, qid);
break;
case GRPQUOTA:
kqid.gid = make_kgid(from, qid);
break;
case PRJQUOTA:
kqid.projid = make_kprojid(from, qid);
break;
default:
BUG();
}
return kqid;
}

/**
* make_kqid_invalid - Explicitly make an invalid kqid
* @type: The type of quota identifier
*
* Returns an invalid kqid with the specified type.
*/
static inline struct kqid make_kqid_invalid(enum quota_type type)
{
struct kqid kqid;

kqid.type = type;
switch (type) {
case USRQUOTA:
kqid.uid = INVALID_UID;
break;
case GRPQUOTA:
kqid.gid = INVALID_GID;
break;
case PRJQUOTA:
kqid.projid = INVALID_PROJID;
break;
default:
BUG();
}
return kqid;
}

/**
* make_kqid_uid - Make a kqid from a kuid
* @uid: The kuid to make the quota identifier from
*/
static inline struct kqid make_kqid_uid(kuid_t uid)
{
struct kqid kqid;
kqid.type = USRQUOTA;
kqid.uid = uid;
return kqid;
}

/**
* make_kqid_gid - Make a kqid from a kgid
* @gid: The kgid to make the quota identifier from
*/
static inline struct kqid make_kqid_gid(kgid_t gid)
{
struct kqid kqid;
kqid.type = GRPQUOTA;
kqid.gid = gid;
return kqid;
}

/**
* make_kqid_projid - Make a kqid from a projid
* @projid: The kprojid to make the quota identifier from
*/
static inline struct kqid make_kqid_projid(kprojid_t projid)
{
struct kqid kqid;
kqid.type = PRJQUOTA;
kqid.projid = projid;
return kqid;
}


extern spinlock_t dq_data_lock;

/* Maximal numbers of writes for quota operation (insert/delete/update)
Expand Down

0 comments on commit 5e4908c

Please sign in to comment.