Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[sfrench/cifs-2.6.git] / kernel / posix-timers.c
index 7a15afb73ed0352d9ee31f6d03334255c716e5a9..ce268966007d6f71904cd8229939f6fb9a2324c5 100644 (file)
@@ -241,7 +241,8 @@ static __init int init_posix_timers(void)
        register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
 
        posix_timers_cache = kmem_cache_create("posix_timers_cache",
-                                       sizeof (struct k_itimer), 0, 0, NULL);
+                                       sizeof (struct k_itimer), 0, SLAB_PANIC,
+                                       NULL);
        idr_init(&posix_timers_id);
        return 0;
 }
@@ -255,8 +256,9 @@ static void schedule_next_timer(struct k_itimer *timr)
        if (timr->it.real.interval.tv64 == 0)
                return;
 
-       timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(),
-                                           timr->it.real.interval);
+       timr->it_overrun += (unsigned int) hrtimer_forward(timer,
+                                               timer->base->get_time(),
+                                               timr->it.real.interval);
 
        timr->it_overrun_last = timr->it_overrun;
        timr->it_overrun = -1;
@@ -385,7 +387,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
                                        now = ktime_add(now, kj);
                        }
 #endif
-                       timr->it_overrun +=
+                       timr->it_overrun += (unsigned int)
                                hrtimer_forward(timer, now,
                                                timr->it.real.interval);
                        ret = HRTIMER_RESTART;
@@ -402,8 +404,8 @@ static struct task_struct * good_sigevent(sigevent_t * event)
        struct task_struct *rtn = current->group_leader;
 
        if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
-               (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
-                rtn->tgid != current->tgid ||
+               (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) ||
+                !same_thread_group(rtn, current) ||
                 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
                return NULL;
 
@@ -492,7 +494,7 @@ sys_timer_create(const clockid_t which_clock,
                goto retry;
        else if (error) {
                /*
-                * Wierd looking, but we return EAGAIN if the IDR is
+                * Weird looking, but we return EAGAIN if the IDR is
                 * full (proper POSIX return value for this)
                 */
                error = -EAGAIN;
@@ -607,7 +609,7 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
                spin_lock(&timr->it_lock);
 
                if ((timr->it_id != timer_id) || !(timr->it_process) ||
-                               timr->it_process->tgid != current->tgid) {
+                               !same_thread_group(timr->it_process, current)) {
                        spin_unlock(&timr->it_lock);
                        spin_unlock_irqrestore(&idr_lock, *flags);
                        timr = NULL;
@@ -661,7 +663,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
         */
        if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
            (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
-               timr->it_overrun += hrtimer_forward(timer, now, iv);
+               timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
 
        remaining = ktime_sub(timer->expires, now);
        /* Return 0 only, when the timer is expired and not pending */
@@ -712,7 +714,7 @@ sys_timer_getoverrun(timer_t timer_id)
 {
        struct k_itimer *timr;
        int overrun;
-       long flags;
+       unsigned long flags;
 
        timr = lock_timer(timer_id, &flags);
        if (!timr)
@@ -784,7 +786,7 @@ sys_timer_settime(timer_t timer_id, int flags,
        struct k_itimer *timr;
        struct itimerspec new_spec, old_spec;
        int error = 0;
-       long flag;
+       unsigned long flag;
        struct itimerspec *rtn = old_setting ? &old_spec : NULL;
 
        if (!new_setting)
@@ -836,7 +838,7 @@ asmlinkage long
 sys_timer_delete(timer_t timer_id)
 {
        struct k_itimer *timer;
-       long flags;
+       unsigned long flags;
 
 retry_delete:
        timer = lock_timer(timer_id, &flags);
@@ -980,9 +982,20 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
 static int common_nsleep(const clockid_t which_clock, int flags,
                         struct timespec *tsave, struct timespec __user *rmtp)
 {
-       return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
-                                HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-                                which_clock);
+       struct timespec rmt;
+       int ret;
+
+       ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
+                               flags & TIMER_ABSTIME ?
+                               HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+                               which_clock);
+
+       if (ret && rmtp) {
+               if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+                       return -EFAULT;
+       }
+
+       return ret;
 }
 
 asmlinkage long