ROUND_UP macro cleanup in fs/(select|compat|readdir).c
[deliverable/linux.git] / fs / compat.c
index 0ec70e3cee0a6113e24b9282250dbcb950e144f1..a32e2ae737fb0d0acc8d8537b98c27aa24ba3467 100644 (file)
@@ -15,6 +15,7 @@
  *  published by the Free Software Foundation.
  */
 
+#include <linux/kernel.h>
 #include <linux/linkage.h>
 #include <linux/compat.h>
 #include <linux/errno.h>
@@ -48,6 +49,7 @@
 #include <linux/highmem.h>
 #include <linux/poll.h>
 #include <linux/mm.h>
+#include <linux/eventpoll.h>
 
 #include <net/sock.h>          /* siocdevprivate_ioctl */
 
@@ -370,13 +372,14 @@ static void compat_ioctl_error(struct file *filp, unsigned int fd,
                        fn = "?";
        }
 
-       sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
+       sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK);
        if (!isprint(buf[1]))
                sprintf(buf, "%02x", buf[1]);
        compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
-                       "cmd(%08x){%s} arg(%08x) on %s\n",
+                       "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n",
                        current->comm, current->pid,
                        (int)fd, (unsigned int)cmd, buf,
+                       (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK,
                        (unsigned int)arg, fn);
 
        if (path)
@@ -900,8 +903,6 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
 }
 
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define COMPAT_ROUND_UP(x) (((x)+sizeof(compat_long_t)-1) & \
-                               ~(sizeof(compat_long_t)-1))
 
 struct compat_old_linux_dirent {
        compat_ulong_t  d_ino;
@@ -989,7 +990,7 @@ static int compat_filldir(void *__buf, const char *name, int namlen,
        struct compat_linux_dirent __user * dirent;
        struct compat_getdents_callback *buf = __buf;
        compat_ulong_t d_ino;
-       int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+       int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(compat_long_t));
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
@@ -1064,7 +1065,6 @@ out:
 }
 
 #ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64
-#define COMPAT_ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
 
 struct compat_getdents_callback64 {
        struct linux_dirent64 __user *current_dir;
@@ -1079,7 +1079,7 @@ static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t
        struct linux_dirent64 __user *dirent;
        struct compat_getdents_callback64 *buf = __buf;
        int jj = NAME_OFFSET(dirent);
-       int reclen = COMPAT_ROUND_UP64(jj + namlen + 1);
+       int reclen = ALIGN(jj + namlen + 1, sizeof(u64));
        u64 off;
 
        buf->error = -EINVAL;   /* only used if we fail.. */
@@ -1592,8 +1592,6 @@ out_ret:
 
 #define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))
 
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
-
 /*
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  * 64-bit unsigned longs.
@@ -1602,7 +1600,7 @@ static
 int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
                        unsigned long *fdset)
 {
-       nr = ROUND_UP(nr, __COMPAT_NFDBITS);
+       nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
        if (ufdset) {
                unsigned long odd;
 
@@ -1636,7 +1634,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
                      unsigned long *fdset)
 {
        unsigned long odd;
-       nr = ROUND_UP(nr, __COMPAT_NFDBITS);
+       nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
 
        if (!ufdset)
                return 0;
@@ -1758,7 +1756,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
                if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
                        timeout = -1;   /* infinite */
                else {
-                       timeout = ROUND_UP(tv.tv_usec, 1000000/HZ);
+                       timeout = DIV_ROUND_UP(tv.tv_usec, 1000000/HZ);
                        timeout += tv.tv_sec * HZ;
                }
        }
@@ -1826,7 +1824,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
        do {
                if (tsp) {
                        if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
-                               timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+                               timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
                                timeout += ts.tv_sec * (unsigned long)HZ;
                                ts.tv_sec = 0;
                                ts.tv_nsec = 0;
@@ -1922,7 +1920,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
                /* We assume that ts.tv_sec is always lower than
                   the number of seconds that can be expressed in
                   an s64. Otherwise the compiler bitches at us */
-               timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+               timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
                timeout += ts.tv_sec * HZ;
        }
 
@@ -2235,3 +2233,102 @@ long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2)
        return sys_ni_syscall();
 }
 #endif
+
+#ifdef CONFIG_EPOLL
+
+#ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT
+asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd,
+                       struct compat_epoll_event __user *event)
+{
+       long err = 0;
+       struct compat_epoll_event user;
+       struct epoll_event __user *kernel = NULL;
+
+       if (event) {
+               if (copy_from_user(&user, event, sizeof(user)))
+                       return -EFAULT;
+               kernel = compat_alloc_user_space(sizeof(struct epoll_event));
+               err |= __put_user(user.events, &kernel->events);
+               err |= __put_user(user.data, &kernel->data);
+       }
+
+       return err ? err : sys_epoll_ctl(epfd, op, fd, kernel);
+}
+
+
+asmlinkage long compat_sys_epoll_wait(int epfd,
+                       struct compat_epoll_event __user *events,
+                       int maxevents, int timeout)
+{
+       long i, ret, err = 0;
+       struct epoll_event __user *kbuf;
+       struct epoll_event ev;
+
+       if ((maxevents <= 0) ||
+                       (maxevents > (INT_MAX / sizeof(struct epoll_event))))
+               return -EINVAL;
+       kbuf = compat_alloc_user_space(sizeof(struct epoll_event) * maxevents);
+       ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout);
+       for (i = 0; i < ret; i++) {
+               err |= __get_user(ev.events, &kbuf[i].events);
+               err |= __get_user(ev.data, &kbuf[i].data);
+               err |= __put_user(ev.events, &events->events);
+               err |= __put_user_unaligned(ev.data, &events->data);
+               events++;
+       }
+
+       return err ? -EFAULT: ret;
+}
+#endif /* CONFIG_HAS_COMPAT_EPOLL_EVENT */
+
+#ifdef TIF_RESTORE_SIGMASK
+asmlinkage long compat_sys_epoll_pwait(int epfd,
+                       struct compat_epoll_event __user *events,
+                       int maxevents, int timeout,
+                       const compat_sigset_t __user *sigmask,
+                       compat_size_t sigsetsize)
+{
+       long err;
+       compat_sigset_t csigmask;
+       sigset_t ksigmask, sigsaved;
+
+       /*
+        * If the caller wants a certain signal mask to be set during the wait,
+        * we apply it here.
+        */
+       if (sigmask) {
+               if (sigsetsize != sizeof(compat_sigset_t))
+                       return -EINVAL;
+               if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
+                       return -EFAULT;
+               sigset_from_compat(&ksigmask, &csigmask);
+               sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+               sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+       }
+
+#ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT
+       err = compat_sys_epoll_wait(epfd, events, maxevents, timeout);
+#else
+       err = sys_epoll_wait(epfd, events, maxevents, timeout);
+#endif
+
+       /*
+        * If we changed the signal mask, we need to restore the original one.
+        * In case we've got a signal while waiting, we do not restore the
+        * signal mask yet, and we allow do_signal() to deliver the signal on
+        * the way back to userspace, before the signal mask is restored.
+        */
+       if (sigmask) {
+               if (err == -EINTR) {
+                       memcpy(&current->saved_sigmask, &sigsaved,
+                              sizeof(sigsaved));
+                       set_thread_flag(TIF_RESTORE_SIGMASK);
+               } else
+                       sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+       }
+
+       return err;
+}
+#endif /* TIF_RESTORE_SIGMASK */
+
+#endif /* CONFIG_EPOLL */
This page took 0.027787 seconds and 5 git commands to generate.