]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/ucount.c
Merge tag 'pm-4.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[karo-tx-linux.git] / kernel / ucount.c
index 95c6336fc2b33c6ea47611e9f9974d8521bc08fc..b4eeee03934fe8f083b70e9907be0721759bc3be 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/stat.h>
 #include <linux/sysctl.h>
 #include <linux/slab.h>
+#include <linux/cred.h>
 #include <linux/hash.h>
 #include <linux/user_namespace.h>
 
@@ -57,7 +58,7 @@ static struct ctl_table_root set_root = {
 
 static int zero = 0;
 static int int_max = INT_MAX;
-#define UCOUNT_ENTRY(name)                             \
+#define UCOUNT_ENTRY(name)                             \
        {                                               \
                .procname       = name,                 \
                .maxlen         = sizeof(int),          \
@@ -74,6 +75,10 @@ static struct ctl_table user_table[] = {
        UCOUNT_ENTRY("max_net_namespaces"),
        UCOUNT_ENTRY("max_mnt_namespaces"),
        UCOUNT_ENTRY("max_cgroup_namespaces"),
+#ifdef CONFIG_INOTIFY_USER
+       UCOUNT_ENTRY("max_inotify_instances"),
+       UCOUNT_ENTRY("max_inotify_watches"),
+#endif
        { }
 };
 #endif /* CONFIG_SYSCTL */
@@ -139,7 +144,7 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
 
                new->ns = ns;
                new->uid = uid;
-               atomic_set(&new->count, 0);
+               new->count = 0;
 
                spin_lock_irq(&ucounts_lock);
                ucounts = find_ucounts(ns, uid, hashent);
@@ -150,8 +155,10 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
                        ucounts = new;
                }
        }
-       if (!atomic_add_unless(&ucounts->count, 1, INT_MAX))
+       if (ucounts->count == INT_MAX)
                ucounts = NULL;
+       else
+               ucounts->count += 1;
        spin_unlock_irq(&ucounts_lock);
        return ucounts;
 }
@@ -160,13 +167,15 @@ static void put_ucounts(struct ucounts *ucounts)
 {
        unsigned long flags;
 
-       if (atomic_dec_and_test(&ucounts->count)) {
-               spin_lock_irqsave(&ucounts_lock, flags);
+       spin_lock_irqsave(&ucounts_lock, flags);
+       ucounts->count -= 1;
+       if (!ucounts->count)
                hlist_del_init(&ucounts->node);
-               spin_unlock_irqrestore(&ucounts_lock, flags);
+       else
+               ucounts = NULL;
+       spin_unlock_irqrestore(&ucounts_lock, flags);
 
-               kfree(ucounts);
-       }
+       kfree(ucounts);
 }
 
 static inline bool atomic_inc_below(atomic_t *v, int u)