diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-29 21:12:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-29 21:12:23 -0400 |
commit | a591afc01d9e48affbacb365558a31e53c85af45 (patch) | |
tree | 9bb91f4eb94ec69fc4706c4944788ec5f3586063 /fs/file.c | |
parent | 820d41cf0cd0e94a5661e093821e2e5c6b36a9d8 (diff) | |
parent | 31796ac4e8f0e88f5c10f1ad6dab8f19bebe44a4 (diff) |
Merge branch 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x32 support for x86-64 from Ingo Molnar:
"This tree introduces the X32 binary format and execution mode for x86:
32-bit data space binaries using 64-bit instructions and 64-bit kernel
syscalls.
This allows applications whose working set fits into a 32 bits address
space to make use of 64-bit instructions while using a 32-bit address
space with shorter pointers, more compressed data structures, etc."
Fix up trivial context conflicts in arch/x86/{Kconfig,vdso/vma.c}
* 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (71 commits)
x32: Fix alignment fail in struct compat_siginfo
x32: Fix stupid ia32/x32 inversion in the siginfo format
x32: Add ptrace for x32
x32: Switch to a 64-bit clock_t
x32: Provide separate is_ia32_task() and is_x32_task() predicates
x86, mtrr: Use explicit sizing and padding for the 64-bit ioctls
x86/x32: Fix the binutils auto-detect
x32: Warn and disable rather than error if binutils too old
x32: Only clear TIF_X32 flag once
x32: Make sure TS_COMPAT is cleared for x32 tasks
fs: Remove missed ->fds_bits from cessation use of fd_set structs internally
fs: Fix close_on_exec pointer in alloc_fdtable
x32: Drop non-__vdso weak symbols from the x32 VDSO
x32: Fix coding style violations in the x32 VDSO code
x32: Add x32 VDSO support
x32: Allow x32 to be configured
x32: If configured, add x32 system calls to system call tables
x32: Handle process creation
x32: Signal-related system calls
x86: Add #ifdef CONFIG_COMPAT to <asm/sys_ia32.h>
...
Diffstat (limited to 'fs/file.c')
-rw-r--r-- | fs/file.c | 52 |
1 files changed, 25 insertions, 27 deletions
@@ -40,7 +40,7 @@ int sysctl_nr_open_max = 1024 * 1024; /* raised later */ | |||
40 | */ | 40 | */ |
41 | static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); | 41 | static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); |
42 | 42 | ||
43 | static void *alloc_fdmem(unsigned int size) | 43 | static void *alloc_fdmem(size_t size) |
44 | { | 44 | { |
45 | /* | 45 | /* |
46 | * Very large allocations can stress page reclaim, so fall back to | 46 | * Very large allocations can stress page reclaim, so fall back to |
@@ -142,7 +142,7 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) | |||
142 | static struct fdtable * alloc_fdtable(unsigned int nr) | 142 | static struct fdtable * alloc_fdtable(unsigned int nr) |
143 | { | 143 | { |
144 | struct fdtable *fdt; | 144 | struct fdtable *fdt; |
145 | char *data; | 145 | void *data; |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * Figure out how many fds we actually want to support in this fdtable. | 148 | * Figure out how many fds we actually want to support in this fdtable. |
@@ -172,14 +172,15 @@ static struct fdtable * alloc_fdtable(unsigned int nr) | |||
172 | data = alloc_fdmem(nr * sizeof(struct file *)); | 172 | data = alloc_fdmem(nr * sizeof(struct file *)); |
173 | if (!data) | 173 | if (!data) |
174 | goto out_fdt; | 174 | goto out_fdt; |
175 | fdt->fd = (struct file **)data; | 175 | fdt->fd = data; |
176 | data = alloc_fdmem(max_t(unsigned int, | 176 | |
177 | data = alloc_fdmem(max_t(size_t, | ||
177 | 2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES)); | 178 | 2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES)); |
178 | if (!data) | 179 | if (!data) |
179 | goto out_arr; | 180 | goto out_arr; |
180 | fdt->open_fds = (fd_set *)data; | 181 | fdt->open_fds = data; |
181 | data += nr / BITS_PER_BYTE; | 182 | data += nr / BITS_PER_BYTE; |
182 | fdt->close_on_exec = (fd_set *)data; | 183 | fdt->close_on_exec = data; |
183 | fdt->next = NULL; | 184 | fdt->next = NULL; |
184 | 185 | ||
185 | return fdt; | 186 | return fdt; |
@@ -275,11 +276,11 @@ static int count_open_files(struct fdtable *fdt) | |||
275 | int i; | 276 | int i; |
276 | 277 | ||
277 | /* Find the last open fd */ | 278 | /* Find the last open fd */ |
278 | for (i = size/(8*sizeof(long)); i > 0; ) { | 279 | for (i = size / BITS_PER_LONG; i > 0; ) { |
279 | if (fdt->open_fds->fds_bits[--i]) | 280 | if (fdt->open_fds[--i]) |
280 | break; | 281 | break; |
281 | } | 282 | } |
282 | i = (i+1) * 8 * sizeof(long); | 283 | i = (i + 1) * BITS_PER_LONG; |
283 | return i; | 284 | return i; |
284 | } | 285 | } |
285 | 286 | ||
@@ -306,8 +307,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
306 | newf->next_fd = 0; | 307 | newf->next_fd = 0; |
307 | new_fdt = &newf->fdtab; | 308 | new_fdt = &newf->fdtab; |
308 | new_fdt->max_fds = NR_OPEN_DEFAULT; | 309 | new_fdt->max_fds = NR_OPEN_DEFAULT; |
309 | new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; | 310 | new_fdt->close_on_exec = newf->close_on_exec_init; |
310 | new_fdt->open_fds = (fd_set *)&newf->open_fds_init; | 311 | new_fdt->open_fds = newf->open_fds_init; |
311 | new_fdt->fd = &newf->fd_array[0]; | 312 | new_fdt->fd = &newf->fd_array[0]; |
312 | new_fdt->next = NULL; | 313 | new_fdt->next = NULL; |
313 | 314 | ||
@@ -350,10 +351,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
350 | old_fds = old_fdt->fd; | 351 | old_fds = old_fdt->fd; |
351 | new_fds = new_fdt->fd; | 352 | new_fds = new_fdt->fd; |
352 | 353 | ||
353 | memcpy(new_fdt->open_fds->fds_bits, | 354 | memcpy(new_fdt->open_fds, old_fdt->open_fds, open_files / 8); |
354 | old_fdt->open_fds->fds_bits, open_files/8); | 355 | memcpy(new_fdt->close_on_exec, old_fdt->close_on_exec, open_files / 8); |
355 | memcpy(new_fdt->close_on_exec->fds_bits, | ||
356 | old_fdt->close_on_exec->fds_bits, open_files/8); | ||
357 | 356 | ||
358 | for (i = open_files; i != 0; i--) { | 357 | for (i = open_files; i != 0; i--) { |
359 | struct file *f = *old_fds++; | 358 | struct file *f = *old_fds++; |
@@ -366,7 +365,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
366 | * is partway through open(). So make sure that this | 365 | * is partway through open(). So make sure that this |
367 | * fd is available to the new process. | 366 | * fd is available to the new process. |
368 | */ | 367 | */ |
369 | FD_CLR(open_files - i, new_fdt->open_fds); | 368 | __clear_open_fd(open_files - i, new_fdt); |
370 | } | 369 | } |
371 | rcu_assign_pointer(*new_fds++, f); | 370 | rcu_assign_pointer(*new_fds++, f); |
372 | } | 371 | } |
@@ -379,11 +378,11 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
379 | memset(new_fds, 0, size); | 378 | memset(new_fds, 0, size); |
380 | 379 | ||
381 | if (new_fdt->max_fds > open_files) { | 380 | if (new_fdt->max_fds > open_files) { |
382 | int left = (new_fdt->max_fds-open_files)/8; | 381 | int left = (new_fdt->max_fds - open_files) / 8; |
383 | int start = open_files / (8 * sizeof(unsigned long)); | 382 | int start = open_files / BITS_PER_LONG; |
384 | 383 | ||
385 | memset(&new_fdt->open_fds->fds_bits[start], 0, left); | 384 | memset(&new_fdt->open_fds[start], 0, left); |
386 | memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); | 385 | memset(&new_fdt->close_on_exec[start], 0, left); |
387 | } | 386 | } |
388 | 387 | ||
389 | rcu_assign_pointer(newf->fdt, new_fdt); | 388 | rcu_assign_pointer(newf->fdt, new_fdt); |
@@ -419,8 +418,8 @@ struct files_struct init_files = { | |||
419 | .fdtab = { | 418 | .fdtab = { |
420 | .max_fds = NR_OPEN_DEFAULT, | 419 | .max_fds = NR_OPEN_DEFAULT, |
421 | .fd = &init_files.fd_array[0], | 420 | .fd = &init_files.fd_array[0], |
422 | .close_on_exec = (fd_set *)&init_files.close_on_exec_init, | 421 | .close_on_exec = init_files.close_on_exec_init, |
423 | .open_fds = (fd_set *)&init_files.open_fds_init, | 422 | .open_fds = init_files.open_fds_init, |
424 | }, | 423 | }, |
425 | .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), | 424 | .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), |
426 | }; | 425 | }; |
@@ -443,8 +442,7 @@ repeat: | |||
443 | fd = files->next_fd; | 442 | fd = files->next_fd; |
444 | 443 | ||
445 | if (fd < fdt->max_fds) | 444 | if (fd < fdt->max_fds) |
446 | fd = find_next_zero_bit(fdt->open_fds->fds_bits, | 445 | fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, fd); |
447 | fdt->max_fds, fd); | ||
448 | 446 | ||
449 | error = expand_files(files, fd); | 447 | error = expand_files(files, fd); |
450 | if (error < 0) | 448 | if (error < 0) |
@@ -460,11 +458,11 @@ repeat: | |||
460 | if (start <= files->next_fd) | 458 | if (start <= files->next_fd) |
461 | files->next_fd = fd + 1; | 459 | files->next_fd = fd + 1; |
462 | 460 | ||
463 | FD_SET(fd, fdt->open_fds); | 461 | __set_open_fd(fd, fdt); |
464 | if (flags & O_CLOEXEC) | 462 | if (flags & O_CLOEXEC) |
465 | FD_SET(fd, fdt->close_on_exec); | 463 | __set_close_on_exec(fd, fdt); |
466 | else | 464 | else |
467 | FD_CLR(fd, fdt->close_on_exec); | 465 | __clear_close_on_exec(fd, fdt); |
468 | error = fd; | 466 | error = fd; |
469 | #if 1 | 467 | #if 1 |
470 | /* Sanity check */ | 468 | /* Sanity check */ |