+/*
+ * Called under kevent_user->ready_lock, so updates are always protected.
+ */
+int kevent_user_ring_add_event(struct kevent *k)
+{
+       unsigned int pidx, off;
+       struct kevent_mring *ring, *copy_ring;
+       
+       ring = k->user->pring[0];
+
+       if ((ring->kidx + 1 == ring->uidx) ||
+                       ((ring->kidx + 1 == KEVENT_MAX_EVENTS) && ring->uidx == 
0)) {
+               if (k->user->overflow_kevent == NULL)
+                       k->user->overflow_kevent = k;
+               return -EAGAIN;
+       }
+


I really dont understand how you manage to queue multiple kevents in the 'overflow list'. You just queue one kevent at most. What am I missing ?



+
+       for (i=0; i<KEVENT_MAX_PAGES; ++i) {
+               u->pring[i] = (struct kevent_mring 
*)__get_free_page(GFP_KERNEL);
+               if (!u->pring[i])
+                       break;
+       }
+
+       if (i != KEVENT_MAX_PAGES)
+               goto err_out_free;

Why dont you use goto directly ?

        if (!u->pring[i])
                goto err_out_free;




+
+       u->pring[0]->uidx = u->pring[0]->kidx = 0;
+
+       return 0;
+
+err_out_free:
+       for (i=0; i<KEVENT_MAX_PAGES; ++i) {
+               if (!u->pring[i])
+                       break;
+
+               free_page((unsigned long)u->pring[i]);
+       }
+       return k;
+}
+




+static int kevent_user_ctl_add(struct kevent_user *u, unsigned int num, void 
__user *arg)
+{
+       int err, cerr = 0, knum = 0, rnum = 0, i;
+       void __user *orig = arg;
+       struct ukevent uk;
+
+       mutex_lock(&u->ctl_mutex);
+
+       err = -EINVAL;
+       if (num > KEVENT_MIN_BUFFS_ALLOC) {
+               struct ukevent *ukev;
+
+               ukev = kevent_get_user(num, arg);
+               if (ukev) {
+                       for (i = 0; i < num; ++i) {
+                               err = kevent_user_add_ukevent(&ukev[i], u);
+                               if (err) {
+                                       kevent_stat_im(u);
+                                       if (i != rnum)
+                                               memcpy(&ukev[rnum], &ukev[i], 
sizeof(struct ukevent));
+                                       rnum++;
+                               } else
+                                       knum++;


Why are you using/counting knum ?



+                       }
+                       if (copy_to_user(orig, ukev, rnum*sizeof(struct 
ukevent)))
+                               cerr = -EFAULT;
+                       kfree(ukev);
+                       goto out_setup;
+               }
+       }
+
+       for (i = 0; i < num; ++i) {
+               if (copy_from_user(&uk, arg, sizeof(struct ukevent))) {
+                       cerr = -EFAULT;
+                       break;
+               }
+               arg += sizeof(struct ukevent);
+
+               err = kevent_user_add_ukevent(&uk, u);
+               if (err) {
+                       kevent_stat_im(u);
+                       if (copy_to_user(orig, &uk, sizeof(struct ukevent))) {
+                               cerr = -EFAULT;
+                               break;
+                       }
+                       orig += sizeof(struct ukevent);
+                       rnum++;
+               } else
+                       knum++;
+       }
+
+out_setup:
+       if (cerr < 0) {
+               err = cerr;
+               goto out_remove;
+       }
+
+       err = rnum;
+out_remove:
+       mutex_unlock(&u->ctl_mutex);
+
+       return err;
+}
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to