aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-09-16 08:45:30 -0400
committerEric W. Biederman <ebiederm@xmission.com>2012-09-18 04:01:42 -0400
commit1a06d420ce9d60b98f5bdf5fd6e4200abfbd3c35 (patch)
tree8e574d87e556f9079caad0eb06299d8b518a97e6 /fs/quota
parent7b9c7321ca6b13d2baeb82b3c9c9f78e9885bcf5 (diff)
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: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/quota')
-rw-r--r--fs/quota/dquot.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index f3db8456dc8a..c4564d0a4a9b 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -253,8 +253,10 @@ static qsize_t inode_get_rsv_space(struct inode *inode);
253static void __dquot_initialize(struct inode *inode, int type); 253static void __dquot_initialize(struct inode *inode, int type);
254 254
255static inline unsigned int 255static inline unsigned int
256hashfn(const struct super_block *sb, unsigned int id, int type) 256hashfn(const struct super_block *sb, struct kqid qid)
257{ 257{
258 unsigned int id = from_kqid(&init_user_ns, qid);
259 int type = qid.type;
258 unsigned long tmp; 260 unsigned long tmp;
259 261
260 tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type); 262 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)
267static inline void insert_dquot_hash(struct dquot *dquot) 269static inline void insert_dquot_hash(struct dquot *dquot)
268{ 270{
269 struct hlist_head *head; 271 struct hlist_head *head;
270 head = dquot_hash + hashfn(dquot->dq_sb, from_kqid(&init_user_ns, dquot->dq_id), dquot->dq_id.type); 272 head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id);
271 hlist_add_head(&dquot->dq_hash, head); 273 hlist_add_head(&dquot->dq_hash, head);
272} 274}
273 275
@@ -277,9 +279,8 @@ static inline void remove_dquot_hash(struct dquot *dquot)
277} 279}
278 280
279static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, 281static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
280 unsigned int id, int type) 282 struct kqid qid)
281{ 283{
282 struct kqid qid = make_kqid(&init_user_ns, type, id);
283 struct hlist_node *node; 284 struct hlist_node *node;
284 struct dquot *dquot; 285 struct dquot *dquot;
285 286
@@ -816,7 +817,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
816 INIT_LIST_HEAD(&dquot->dq_dirty); 817 INIT_LIST_HEAD(&dquot->dq_dirty);
817 init_waitqueue_head(&dquot->dq_wait_unused); 818 init_waitqueue_head(&dquot->dq_wait_unused);
818 dquot->dq_sb = sb; 819 dquot->dq_sb = sb;
819 dquot->dq_id.type = type; 820 dquot->dq_id = make_kqid_invalid(type);
820 atomic_set(&dquot->dq_count, 1); 821 atomic_set(&dquot->dq_count, 1);
821 822
822 return dquot; 823 return dquot;
@@ -832,28 +833,26 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
832 */ 833 */
833struct dquot *dqget(struct super_block *sb, struct kqid qid) 834struct dquot *dqget(struct super_block *sb, struct kqid qid)
834{ 835{
835 unsigned int type = qid.type; 836 unsigned int hashent = hashfn(sb, qid);
836 unsigned int id = from_kqid(&init_user_ns, qid);
837 unsigned int hashent = hashfn(sb, id, type);
838 struct dquot *dquot = NULL, *empty = NULL; 837 struct dquot *dquot = NULL, *empty = NULL;
839 838
840 if (!sb_has_quota_active(sb, type)) 839 if (!sb_has_quota_active(sb, qid.type))
841 return NULL; 840 return NULL;
842we_slept: 841we_slept:
843 spin_lock(&dq_list_lock); 842 spin_lock(&dq_list_lock);
844 spin_lock(&dq_state_lock); 843 spin_lock(&dq_state_lock);
845 if (!sb_has_quota_active(sb, type)) { 844 if (!sb_has_quota_active(sb, qid.type)) {
846 spin_unlock(&dq_state_lock); 845 spin_unlock(&dq_state_lock);
847 spin_unlock(&dq_list_lock); 846 spin_unlock(&dq_list_lock);
848 goto out; 847 goto out;
849 } 848 }
850 spin_unlock(&dq_state_lock); 849 spin_unlock(&dq_state_lock);
851 850
852 dquot = find_dquot(hashent, sb, id, type); 851 dquot = find_dquot(hashent, sb, qid);
853 if (!dquot) { 852 if (!dquot) {
854 if (!empty) { 853 if (!empty) {
855 spin_unlock(&dq_list_lock); 854 spin_unlock(&dq_list_lock);
856 empty = get_empty_dquot(sb, type); 855 empty = get_empty_dquot(sb, qid.type);
857 if (!empty) 856 if (!empty)
858 schedule(); /* Try to wait for a moment... */ 857 schedule(); /* Try to wait for a moment... */
859 goto we_slept; 858 goto we_slept;
@@ -1158,7 +1157,7 @@ static int need_print_warning(struct dquot_warn *warn)
1158 1157
1159 switch (warn->w_dq_id.type) { 1158 switch (warn->w_dq_id.type) {
1160 case USRQUOTA: 1159 case USRQUOTA:
1161 return current_fsuid() == warn->w_dq_id.uid; 1160 return uid_eq(current_fsuid(), warn->w_dq_id.uid);
1162 case GRPQUOTA: 1161 case GRPQUOTA:
1163 return in_group_p(warn->w_dq_id.gid); 1162 return in_group_p(warn->w_dq_id.gid);
1164 } 1163 }
@@ -1898,9 +1897,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
1898 if (!dquot_active(inode)) 1897 if (!dquot_active(inode))
1899 return 0; 1898 return 0;
1900 1899
1901 if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) 1900 if (iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid))
1902 transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(iattr->ia_uid)); 1901 transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(iattr->ia_uid));
1903 if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) 1902 if (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))
1904 transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(iattr->ia_gid)); 1903 transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(iattr->ia_gid));
1905 1904
1906 ret = __dquot_transfer(inode, transfer_to); 1905 ret = __dquot_transfer(inode, transfer_to);