diff options
Diffstat (limited to 'fs/select.c')
| -rw-r--r-- | fs/select.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/fs/select.c b/fs/select.c index 071660fa7b01..a8109baa5e46 100644 --- a/fs/select.c +++ b/fs/select.c | |||
| @@ -310,8 +310,9 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
| 310 | fd_set __user *exp, s64 *timeout) | 310 | fd_set __user *exp, s64 *timeout) |
| 311 | { | 311 | { |
| 312 | fd_set_bits fds; | 312 | fd_set_bits fds; |
| 313 | char *bits; | 313 | void *bits; |
| 314 | int ret, size, max_fdset; | 314 | int ret, max_fdset; |
| 315 | unsigned int size; | ||
| 315 | struct fdtable *fdt; | 316 | struct fdtable *fdt; |
| 316 | /* Allocate small arguments on the stack to save memory and be faster */ | 317 | /* Allocate small arguments on the stack to save memory and be faster */ |
| 317 | long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; | 318 | 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, | |||
| 333 | * since we used fdset we need to allocate memory in units of | 334 | * since we used fdset we need to allocate memory in units of |
| 334 | * long-words. | 335 | * long-words. |
| 335 | */ | 336 | */ |
| 336 | ret = -ENOMEM; | ||
| 337 | size = FDS_BYTES(n); | 337 | size = FDS_BYTES(n); |
| 338 | if (6*size < SELECT_STACK_ALLOC) | 338 | bits = stack_fds; |
| 339 | bits = stack_fds; | 339 | if (size > sizeof(stack_fds) / 6) { |
| 340 | else | 340 | /* Not enough space in on-stack array; must use kmalloc */ |
| 341 | ret = -ENOMEM; | ||
| 341 | bits = kmalloc(6 * size, GFP_KERNEL); | 342 | bits = kmalloc(6 * size, GFP_KERNEL); |
| 342 | if (!bits) | 343 | if (!bits) |
| 343 | goto out_nofds; | 344 | goto out_nofds; |
| 344 | fds.in = (unsigned long *) bits; | 345 | } |
| 345 | fds.out = (unsigned long *) (bits + size); | 346 | fds.in = bits; |
| 346 | fds.ex = (unsigned long *) (bits + 2*size); | 347 | fds.out = bits + size; |
| 347 | fds.res_in = (unsigned long *) (bits + 3*size); | 348 | fds.ex = bits + 2*size; |
| 348 | fds.res_out = (unsigned long *) (bits + 4*size); | 349 | fds.res_in = bits + 3*size; |
| 349 | fds.res_ex = (unsigned long *) (bits + 5*size); | 350 | fds.res_out = bits + 4*size; |
| 351 | fds.res_ex = bits + 5*size; | ||
| 350 | 352 | ||
| 351 | if ((ret = get_fd_set(n, inp, fds.in)) || | 353 | if ((ret = get_fd_set(n, inp, fds.in)) || |
| 352 | (ret = get_fd_set(n, outp, fds.out)) || | 354 | (ret = get_fd_set(n, outp, fds.out)) || |
