Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc
[pandora-kernel.git] / fs / select.c
index 071660f..a8109ba 100644 (file)
@@ -310,8 +310,9 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
                           fd_set __user *exp, s64 *timeout)
 {
        fd_set_bits fds;
-       char *bits;
-       int ret, size, max_fdset;
+       void *bits;
+       int ret, max_fdset;
+       unsigned int size;
        struct fdtable *fdt;
        /* Allocate small arguments on the stack to save memory and be faster */
        long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
@@ -333,20 +334,21 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
         * since we used fdset we need to allocate memory in units of
         * long-words. 
         */
-       ret = -ENOMEM;
        size = FDS_BYTES(n);
-       if (6*size < SELECT_STACK_ALLOC)
-               bits = stack_fds;
-       else
+       bits = stack_fds;
+       if (size > sizeof(stack_fds) / 6) {
+               /* Not enough space in on-stack array; must use kmalloc */
+               ret = -ENOMEM;
                bits = kmalloc(6 * size, GFP_KERNEL);
-       if (!bits)
-               goto out_nofds;
-       fds.in      = (unsigned long *)  bits;
-       fds.out     = (unsigned long *) (bits +   size);
-       fds.ex      = (unsigned long *) (bits + 2*size);
-       fds.res_in  = (unsigned long *) (bits + 3*size);
-       fds.res_out = (unsigned long *) (bits + 4*size);
-       fds.res_ex  = (unsigned long *) (bits + 5*size);
+               if (!bits)
+                       goto out_nofds;
+       }
+       fds.in      = bits;
+       fds.out     = bits +   size;
+       fds.ex      = bits + 2*size;
+       fds.res_in  = bits + 3*size;
+       fds.res_out = bits + 4*size;
+       fds.res_ex  = bits + 5*size;
 
        if ((ret = get_fd_set(n, inp, fds.in)) ||
            (ret = get_fd_set(n, outp, fds.out)) ||