diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/quota/dquot.c | 29 |
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); | |||
253 | static void __dquot_initialize(struct inode *inode, int type); | 253 | static void __dquot_initialize(struct inode *inode, int type); |
254 | 254 | ||
255 | static inline unsigned int | 255 | static inline unsigned int |
256 | hashfn(const struct super_block *sb, unsigned int id, int type) | 256 | hashfn(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) | |||
267 | static inline void insert_dquot_hash(struct dquot *dquot) | 269 | static 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 | ||
279 | static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, | 281 | static 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 | */ |
833 | struct dquot *dqget(struct super_block *sb, struct kqid qid) | 834 | struct 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; |
842 | we_slept: | 841 | we_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); |