aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/file.c')
-rw-r--r--fs/file.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/fs/file.c b/fs/file.c
index 771578b33fb6..8f294cfac697 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -25,7 +25,10 @@
25 25
26int sysctl_nr_open __read_mostly = 1024*1024; 26int sysctl_nr_open __read_mostly = 1024*1024;
27int sysctl_nr_open_min = BITS_PER_LONG; 27int sysctl_nr_open_min = BITS_PER_LONG;
28int sysctl_nr_open_max = 1024 * 1024; /* raised later */ 28/* our max() is unusable in constant expressions ;-/ */
29#define __const_max(x, y) ((x) < (y) ? (x) : (y))
30int sysctl_nr_open_max = __const_max(INT_MAX, ~(size_t)0/sizeof(void *)) &
31 -BITS_PER_LONG;
29 32
30static void *alloc_fdmem(size_t size) 33static void *alloc_fdmem(size_t size)
31{ 34{
@@ -34,7 +37,7 @@ static void *alloc_fdmem(size_t size)
34 * vmalloc() if the allocation size will be considered "large" by the VM. 37 * vmalloc() if the allocation size will be considered "large" by the VM.
35 */ 38 */
36 if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { 39 if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
37 void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); 40 void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY);
38 if (data != NULL) 41 if (data != NULL)
39 return data; 42 return data;
40 } 43 }
@@ -429,12 +432,6 @@ void exit_files(struct task_struct *tsk)
429 } 432 }
430} 433}
431 434
432void __init files_defer_init(void)
433{
434 sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) &
435 -BITS_PER_LONG;
436}
437
438struct files_struct init_files = { 435struct files_struct init_files = {
439 .count = ATOMIC_INIT(1), 436 .count = ATOMIC_INIT(1),
440 .fdt = &init_files.fdtab, 437 .fdt = &init_files.fdtab,
@@ -497,7 +494,7 @@ repeat:
497 error = fd; 494 error = fd;
498#if 1 495#if 1
499 /* Sanity check */ 496 /* Sanity check */
500 if (rcu_dereference_raw(fdt->fd[fd]) != NULL) { 497 if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
501 printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd); 498 printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd);
502 rcu_assign_pointer(fdt->fd[fd], NULL); 499 rcu_assign_pointer(fdt->fd[fd], NULL);
503 } 500 }
@@ -683,35 +680,54 @@ EXPORT_SYMBOL(fget_raw);
683 * The fput_needed flag returned by fget_light should be passed to the 680 * The fput_needed flag returned by fget_light should be passed to the
684 * corresponding fput_light. 681 * corresponding fput_light.
685 */ 682 */
686struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed) 683static unsigned long __fget_light(unsigned int fd, fmode_t mask)
687{ 684{
688 struct files_struct *files = current->files; 685 struct files_struct *files = current->files;
689 struct file *file; 686 struct file *file;
690 687
691 *fput_needed = 0;
692 if (atomic_read(&files->count) == 1) { 688 if (atomic_read(&files->count) == 1) {
693 file = __fcheck_files(files, fd); 689 file = __fcheck_files(files, fd);
694 if (file && (file->f_mode & mask)) 690 if (!file || unlikely(file->f_mode & mask))
695 file = NULL; 691 return 0;
692 return (unsigned long)file;
696 } else { 693 } else {
697 file = __fget(fd, mask); 694 file = __fget(fd, mask);
698 if (file) 695 if (!file)
699 *fput_needed = 1; 696 return 0;
697 return FDPUT_FPUT | (unsigned long)file;
700 } 698 }
701
702 return file;
703} 699}
704struct file *fget_light(unsigned int fd, int *fput_needed) 700unsigned long __fdget(unsigned int fd)
701{
702 return __fget_light(fd, FMODE_PATH);
703}
704EXPORT_SYMBOL(__fdget);
705
706unsigned long __fdget_raw(unsigned int fd)
705{ 707{
706 return __fget_light(fd, FMODE_PATH, fput_needed); 708 return __fget_light(fd, 0);
707} 709}
708EXPORT_SYMBOL(fget_light);
709 710
710struct file *fget_raw_light(unsigned int fd, int *fput_needed) 711unsigned long __fdget_pos(unsigned int fd)
711{ 712{
712 return __fget_light(fd, 0, fput_needed); 713 unsigned long v = __fdget(fd);
714 struct file *file = (struct file *)(v & ~3);
715
716 if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
717 if (file_count(file) > 1) {
718 v |= FDPUT_POS_UNLOCK;
719 mutex_lock(&file->f_pos_lock);
720 }
721 }
722 return v;
713} 723}
714 724
725/*
726 * We only lock f_pos if we have threads or if the file might be
727 * shared with another process. In both cases we'll have an elevated
728 * file count (done either by fdget() or by fork()).
729 */
730
715void set_close_on_exec(unsigned int fd, int flag) 731void set_close_on_exec(unsigned int fd, int flag)
716{ 732{
717 struct files_struct *files = current->files; 733 struct files_struct *files = current->files;