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)) || |