diff options
Diffstat (limited to 'kernel/ucount.c')
-rw-r--r-- | kernel/ucount.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/kernel/ucount.c b/kernel/ucount.c index 62630a40ab3a..b4eeee03934f 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c | |||
@@ -144,7 +144,7 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid) | |||
144 | 144 | ||
145 | new->ns = ns; | 145 | new->ns = ns; |
146 | new->uid = uid; | 146 | new->uid = uid; |
147 | atomic_set(&new->count, 0); | 147 | new->count = 0; |
148 | 148 | ||
149 | spin_lock_irq(&ucounts_lock); | 149 | spin_lock_irq(&ucounts_lock); |
150 | ucounts = find_ucounts(ns, uid, hashent); | 150 | ucounts = find_ucounts(ns, uid, hashent); |
@@ -155,8 +155,10 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid) | |||
155 | ucounts = new; | 155 | ucounts = new; |
156 | } | 156 | } |
157 | } | 157 | } |
158 | if (!atomic_add_unless(&ucounts->count, 1, INT_MAX)) | 158 | if (ucounts->count == INT_MAX) |
159 | ucounts = NULL; | 159 | ucounts = NULL; |
160 | else | ||
161 | ucounts->count += 1; | ||
160 | spin_unlock_irq(&ucounts_lock); | 162 | spin_unlock_irq(&ucounts_lock); |
161 | return ucounts; | 163 | return ucounts; |
162 | } | 164 | } |
@@ -165,13 +167,15 @@ static void put_ucounts(struct ucounts *ucounts) | |||
165 | { | 167 | { |
166 | unsigned long flags; | 168 | unsigned long flags; |
167 | 169 | ||
168 | if (atomic_dec_and_test(&ucounts->count)) { | 170 | spin_lock_irqsave(&ucounts_lock, flags); |
169 | spin_lock_irqsave(&ucounts_lock, flags); | 171 | ucounts->count -= 1; |
172 | if (!ucounts->count) | ||
170 | hlist_del_init(&ucounts->node); | 173 | hlist_del_init(&ucounts->node); |
171 | spin_unlock_irqrestore(&ucounts_lock, flags); | 174 | else |
175 | ucounts = NULL; | ||
176 | spin_unlock_irqrestore(&ucounts_lock, flags); | ||
172 | 177 | ||
173 | kfree(ucounts); | 178 | kfree(ucounts); |
174 | } | ||
175 | } | 179 | } |
176 | 180 | ||
177 | static inline bool atomic_inc_below(atomic_t *v, int u) | 181 | static inline bool atomic_inc_below(atomic_t *v, int u) |