switch timerfd compat syscalls to COMPAT_SYSCALL_DEFINE
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 27 Dec 2012 21:52:33 +0000 (16:52 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 3 Feb 2013 20:09:25 +0000 (15:09 -0500)
... and move them over to fs/timerfd.c.  Cleaner and easier
that way...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/compat.c
fs/timerfd.c

index f9e2fe3794fa91d831a68750d25ac7c990fa87ba..fe40fde291111b0f4d521756403dbc530be4da8a 100644 (file)
@@ -1737,47 +1737,6 @@ asmlinkage long compat_sys_signalfd(int ufd,
 }
 #endif /* CONFIG_SIGNALFD */
 
-#ifdef CONFIG_TIMERFD
-
-asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
-                                  const struct compat_itimerspec __user *utmr,
-                                  struct compat_itimerspec __user *otmr)
-{
-       int error;
-       struct itimerspec t;
-       struct itimerspec __user *ut;
-
-       if (get_compat_itimerspec(&t, utmr))
-               return -EFAULT;
-       ut = compat_alloc_user_space(2 * sizeof(struct itimerspec));
-       if (copy_to_user(&ut[0], &t, sizeof(t)))
-               return -EFAULT;
-       error = sys_timerfd_settime(ufd, flags, &ut[0], &ut[1]);
-       if (!error && otmr)
-               error = (copy_from_user(&t, &ut[1], sizeof(struct itimerspec)) ||
-                        put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0;
-
-       return error;
-}
-
-asmlinkage long compat_sys_timerfd_gettime(int ufd,
-                                  struct compat_itimerspec __user *otmr)
-{
-       int error;
-       struct itimerspec t;
-       struct itimerspec __user *ut;
-
-       ut = compat_alloc_user_space(sizeof(struct itimerspec));
-       error = sys_timerfd_gettime(ufd, ut);
-       if (!error)
-               error = (copy_from_user(&t, ut, sizeof(struct itimerspec)) ||
-                        put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0;
-
-       return error;
-}
-
-#endif /* CONFIG_TIMERFD */
-
 #ifdef CONFIG_FHANDLE
 /*
  * Exactly like fs/open.c:sys_open_by_handle_at(), except that it
index d03822bbf1909080ff201acc372de185d10d50d5..0e606b12a59df966b5509e87016d6782034ee473 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/anon_inodes.h>
 #include <linux/timerfd.h>
 #include <linux/syscalls.h>
+#include <linux/compat.h>
 #include <linux/rcupdate.h>
 
 struct timerfd_ctx {
@@ -278,21 +279,17 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
        return ufd;
 }
 
-SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
-               const struct itimerspec __user *, utmr,
-               struct itimerspec __user *, otmr)
+static int do_timerfd_settime(int ufd, int flags, 
+               const struct itimerspec *new,
+               struct itimerspec *old)
 {
        struct fd f;
        struct timerfd_ctx *ctx;
-       struct itimerspec ktmr, kotmr;
        int ret;
 
-       if (copy_from_user(&ktmr, utmr, sizeof(ktmr)))
-               return -EFAULT;
-
        if ((flags & ~TFD_SETTIME_FLAGS) ||
-           !timespec_valid(&ktmr.it_value) ||
-           !timespec_valid(&ktmr.it_interval))
+           !timespec_valid(&new->it_value) ||
+           !timespec_valid(&new->it_interval))
                return -EINVAL;
 
        ret = timerfd_fget(ufd, &f);
@@ -323,27 +320,23 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
        if (ctx->expired && ctx->tintv.tv64)
                hrtimer_forward_now(&ctx->tmr, ctx->tintv);
 
-       kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
-       kotmr.it_interval = ktime_to_timespec(ctx->tintv);
+       old->it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
+       old->it_interval = ktime_to_timespec(ctx->tintv);
 
        /*
         * Re-program the timer to the new value ...
         */
-       ret = timerfd_setup(ctx, flags, &ktmr);
+       ret = timerfd_setup(ctx, flags, new);
 
        spin_unlock_irq(&ctx->wqh.lock);
        fdput(f);
-       if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr)))
-               return -EFAULT;
-
        return ret;
 }
 
-SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
+static int do_timerfd_gettime(int ufd, struct itimerspec *t)
 {
        struct fd f;
        struct timerfd_ctx *ctx;
-       struct itimerspec kotmr;
        int ret = timerfd_fget(ufd, &f);
        if (ret)
                return ret;
@@ -356,11 +349,65 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
                        hrtimer_forward_now(&ctx->tmr, ctx->tintv) - 1;
                hrtimer_restart(&ctx->tmr);
        }
-       kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
-       kotmr.it_interval = ktime_to_timespec(ctx->tintv);
+       t->it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
+       t->it_interval = ktime_to_timespec(ctx->tintv);
        spin_unlock_irq(&ctx->wqh.lock);
        fdput(f);
+       return 0;
+}
+
+SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
+               const struct itimerspec __user *, utmr,
+               struct itimerspec __user *, otmr)
+{
+       struct itimerspec new, old;
+       int ret;
+
+       if (copy_from_user(&new, utmr, sizeof(new)))
+               return -EFAULT;
+       ret = do_timerfd_settime(ufd, flags, &new, &old);
+       if (ret)
+               return ret;
+       if (otmr && copy_to_user(otmr, &old, sizeof(old)))
+               return -EFAULT;
+
+       return ret;
+}
 
+SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
+{
+       struct itimerspec kotmr;
+       int ret = do_timerfd_gettime(ufd, &kotmr);
+       if (ret)
+               return ret;
        return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0;
 }
 
+#ifdef COMPAT
+COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
+               const struct itimerspec __user *, utmr,
+               struct itimerspec __user *, otmr)
+{
+       struct itimerspec new, old;
+       int ret;
+
+       if (get_compat_itimerspec(&new, utmr))
+               return -EFAULT;
+       ret = do_timerfd_settime(ufd, flags, &new, &old);
+       if (ret)
+               return ret;
+       if (otmr && put_compat_itimerspec(otmr, &old))
+               return -EFAULT;
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd,
+               struct itimerspec __user *, otmr)
+{
+       struct itimerspec kotmr;
+       int ret = do_timerfd_gettime(ufd, &kotmr);
+       if (ret)
+               return ret;
+       return put_compat_itimerspec(otmr, &t) ? -EFAULT: 0;
+}
+#endif