Commit 1a06d420 authored by Eric W. Biederman's avatar Eric W. Biederman

userns: Convert quota

Now that the type changes are done, here is the final set of
changes to make the quota code work when user namespaces are enabled.

Small cleanups and fixes to make the code build when user namespaces
are enabled.

Cc: Jan Kara <jack@suse.cz>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 7b9c7321
...@@ -253,8 +253,10 @@ static qsize_t inode_get_rsv_space(struct inode *inode); ...@@ -253,8 +253,10 @@ static qsize_t inode_get_rsv_space(struct inode *inode);
static void __dquot_initialize(struct inode *inode, int type); static void __dquot_initialize(struct inode *inode, int type);
static inline unsigned int static inline unsigned int
hashfn(const struct super_block *sb, unsigned int id, int type) hashfn(const struct super_block *sb, struct kqid qid)
{ {
unsigned int id = from_kqid(&init_user_ns, qid);
int type = qid.type;
unsigned long tmp; unsigned long tmp;
tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type); tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
...@@ -267,7 +269,7 @@ hashfn(const struct super_block *sb, unsigned int id, int type) ...@@ -267,7 +269,7 @@ hashfn(const struct super_block *sb, unsigned int id, int type)
static inline void insert_dquot_hash(struct dquot *dquot) static inline void insert_dquot_hash(struct dquot *dquot)
{ {
struct hlist_head *head; struct hlist_head *head;
head = dquot_hash + hashfn(dquot->dq_sb, from_kqid(&init_user_ns, dquot->dq_id), dquot->dq_id.type); head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id);
hlist_add_head(&dquot->dq_hash, head); hlist_add_head(&dquot->dq_hash, head);
} }
...@@ -277,9 +279,8 @@ static inline void remove_dquot_hash(struct dquot *dquot) ...@@ -277,9 +279,8 @@ static inline void remove_dquot_hash(struct dquot *dquot)
} }
static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
unsigned int id, int type) struct kqid qid)
{ {
struct kqid qid = make_kqid(&init_user_ns, type, id);
struct hlist_node *node; struct hlist_node *node;
struct dquot *dquot; struct dquot *dquot;
...@@ -816,7 +817,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) ...@@ -816,7 +817,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
INIT_LIST_HEAD(&dquot->dq_dirty); INIT_LIST_HEAD(&dquot->dq_dirty);
init_waitqueue_head(&dquot->dq_wait_unused); init_waitqueue_head(&dquot->dq_wait_unused);
dquot->dq_sb = sb; dquot->dq_sb = sb;
dquot->dq_id.type = type; dquot->dq_id = make_kqid_invalid(type);
atomic_set(&dquot->dq_count, 1); atomic_set(&dquot->dq_count, 1);
return dquot; return dquot;
...@@ -832,28 +833,26 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) ...@@ -832,28 +833,26 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
*/ */
struct dquot *dqget(struct super_block *sb, struct kqid qid) struct dquot *dqget(struct super_block *sb, struct kqid qid)
{ {
unsigned int type = qid.type; unsigned int hashent = hashfn(sb, qid);
unsigned int id = from_kqid(&init_user_ns, qid);
unsigned int hashent = hashfn(sb, id, type);
struct dquot *dquot = NULL, *empty = NULL; struct dquot *dquot = NULL, *empty = NULL;
if (!sb_has_quota_active(sb, type)) if (!sb_has_quota_active(sb, qid.type))
return NULL; return NULL;
we_slept: we_slept:
spin_lock(&dq_list_lock); spin_lock(&dq_list_lock);
spin_lock(&dq_state_lock); spin_lock(&dq_state_lock);
if (!sb_has_quota_active(sb, type)) { if (!sb_has_quota_active(sb, qid.type)) {
spin_unlock(&dq_state_lock); spin_unlock(&dq_state_lock);
spin_unlock(&dq_list_lock); spin_unlock(&dq_list_lock);
goto out; goto out;
} }
spin_unlock(&dq_state_lock); spin_unlock(&dq_state_lock);
dquot = find_dquot(hashent, sb, id, type); dquot = find_dquot(hashent, sb, qid);
if (!dquot) { if (!dquot) {
if (!empty) { if (!empty) {
spin_unlock(&dq_list_lock); spin_unlock(&dq_list_lock);
empty = get_empty_dquot(sb, type); empty = get_empty_dquot(sb, qid.type);
if (!empty) if (!empty)
schedule(); /* Try to wait for a moment... */ schedule(); /* Try to wait for a moment... */
goto we_slept; goto we_slept;
...@@ -1158,7 +1157,7 @@ static int need_print_warning(struct dquot_warn *warn) ...@@ -1158,7 +1157,7 @@ static int need_print_warning(struct dquot_warn *warn)
switch (warn->w_dq_id.type) { switch (warn->w_dq_id.type) {
case USRQUOTA: case USRQUOTA:
return current_fsuid() == warn->w_dq_id.uid; return uid_eq(current_fsuid(), warn->w_dq_id.uid);
case GRPQUOTA: case GRPQUOTA:
return in_group_p(warn->w_dq_id.gid); return in_group_p(warn->w_dq_id.gid);
} }
...@@ -1898,9 +1897,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) ...@@ -1898,9 +1897,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
if (!dquot_active(inode)) if (!dquot_active(inode))
return 0; return 0;
if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) if (iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid))
transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(iattr->ia_uid)); transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(iattr->ia_uid));
if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) if (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))
transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(iattr->ia_gid)); transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(iattr->ia_gid));
ret = __dquot_transfer(inode, transfer_to); ret = __dquot_transfer(inode, transfer_to);
......
...@@ -927,7 +927,6 @@ config UIDGID_CONVERTED ...@@ -927,7 +927,6 @@ config UIDGID_CONVERTED
# Features # Features
depends on IMA = n depends on IMA = n
depends on EVM = n depends on EVM = n
depends on QUOTA = n
# Networking # Networking
depends on NET_9P = n depends on NET_9P = n
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment