netns xfrm: fix "ip xfrm state|policy count" misreport
[safe/jmp/linux-2.6] / fs / eventpoll.c
index a89f370..bd056a5 100644 (file)
@@ -98,7 +98,7 @@ struct epoll_filefd {
 struct nested_call_node {
        struct list_head llink;
        void *cookie;
-       int cpu;
+       void *ctx;
 };
 
 /*
@@ -251,10 +251,10 @@ ctl_table epoll_table[] = {
                .data           = &max_user_watches,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
                .extra1         = &zero,
        },
-       { .ctl_name = 0 }
+       { }
 };
 #endif /* CONFIG_SYSCTL */
 
@@ -317,17 +317,17 @@ static void ep_nested_calls_init(struct nested_calls *ncalls)
  * @nproc: Nested call core function pointer.
  * @priv: Opaque data to be passed to the @nproc callback.
  * @cookie: Cookie to be used to identify this nested call.
+ * @ctx: This instance context.
  *
  * Returns: Returns the code returned by the @nproc callback, or -1 if
  *          the maximum recursion limit has been exceeded.
  */
 static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
                          int (*nproc)(void *, void *, int), void *priv,
-                         void *cookie)
+                         void *cookie, void *ctx)
 {
        int error, call_nests = 0;
        unsigned long flags;
-       int this_cpu = get_cpu();
        struct list_head *lsthead = &ncalls->tasks_call_list;
        struct nested_call_node *tncur;
        struct nested_call_node tnode;
@@ -340,7 +340,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
         * very much limited.
         */
        list_for_each_entry(tncur, lsthead, llink) {
-               if (tncur->cpu == this_cpu &&
+               if (tncur->ctx == ctx &&
                    (tncur->cookie == cookie || ++call_nests > max_nests)) {
                        /*
                         * Ops ... loop detected or maximum nest level reached.
@@ -352,7 +352,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
        }
 
        /* Add the current task and cookie to the list */
-       tnode.cpu = this_cpu;
+       tnode.ctx = ctx;
        tnode.cookie = cookie;
        list_add(&tnode.llink, lsthead);
 
@@ -364,10 +364,9 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
        /* Remove the current task from the list */
        spin_lock_irqsave(&ncalls->lock, flags);
        list_del(&tnode.llink);
- out_unlock:
+out_unlock:
        spin_unlock_irqrestore(&ncalls->lock, flags);
 
-       put_cpu();
        return error;
 }
 
@@ -408,8 +407,12 @@ static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests)
  */
 static void ep_poll_safewake(wait_queue_head_t *wq)
 {
+       int this_cpu = get_cpu();
+
        ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS,
-                      ep_poll_wakeup_proc, NULL, wq);
+                      ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu);
+
+       put_cpu();
 }
 
 /*
@@ -663,7 +666,7 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
         * could re-enter here.
         */
        pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS,
-                                  ep_poll_readyevents_proc, ep, ep);
+                                  ep_poll_readyevents_proc, ep, ep, current);
 
        return pollflags != -1 ? pollflags : 0;
 }
@@ -1203,7 +1206,7 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
         * a file structure and a free file descriptor.
         */
        error = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep,
-                                flags & O_CLOEXEC);
+                                O_RDWR | (flags & O_CLOEXEC));
        if (error < 0)
                ep_free(ep);
 
@@ -1212,7 +1215,7 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
 
 SYSCALL_DEFINE1(epoll_create, int, size)
 {
-       if (size < 0)
+       if (size <= 0)
                return -EINVAL;
 
        return sys_epoll_create1(0);