diff options
Diffstat (limited to 'fs/file_table.c')
-rw-r--r-- | fs/file_table.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/fs/file_table.c b/fs/file_table.c index 03d83cb686b1..fa7849fae134 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -63,42 +63,45 @@ static inline void file_free(struct file *f) | |||
63 | */ | 63 | */ |
64 | struct file *get_empty_filp(void) | 64 | struct file *get_empty_filp(void) |
65 | { | 65 | { |
66 | static int old_max; | 66 | static int old_max; |
67 | struct file * f; | 67 | struct file * f; |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * Privileged users can go above max_files | 70 | * Privileged users can go above max_files |
71 | */ | 71 | */ |
72 | if (files_stat.nr_files < files_stat.max_files || | 72 | if (files_stat.nr_files >= files_stat.max_files && |
73 | capable(CAP_SYS_ADMIN)) { | 73 | !capable(CAP_SYS_ADMIN)) |
74 | f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); | 74 | goto over; |
75 | if (f) { | 75 | |
76 | memset(f, 0, sizeof(*f)); | 76 | f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); |
77 | if (security_file_alloc(f)) { | 77 | if (f == NULL) |
78 | file_free(f); | 78 | goto fail; |
79 | goto fail; | 79 | |
80 | } | 80 | memset(f, 0, sizeof(*f)); |
81 | eventpoll_init_file(f); | 81 | if (security_file_alloc(f)) |
82 | atomic_set(&f->f_count, 1); | 82 | goto fail_sec; |
83 | f->f_uid = current->fsuid; | 83 | |
84 | f->f_gid = current->fsgid; | 84 | eventpoll_init_file(f); |
85 | rwlock_init(&f->f_owner.lock); | 85 | atomic_set(&f->f_count, 1); |
86 | /* f->f_version: 0 */ | 86 | f->f_uid = current->fsuid; |
87 | INIT_LIST_HEAD(&f->f_list); | 87 | f->f_gid = current->fsgid; |
88 | f->f_maxcount = INT_MAX; | 88 | rwlock_init(&f->f_owner.lock); |
89 | return f; | 89 | /* f->f_version: 0 */ |
90 | } | 90 | INIT_LIST_HEAD(&f->f_list); |
91 | } | 91 | f->f_maxcount = INT_MAX; |
92 | 92 | return f; | |
93 | |||
94 | over: | ||
93 | /* Ran out of filps - report that */ | 95 | /* Ran out of filps - report that */ |
94 | if (files_stat.max_files >= old_max) { | 96 | if (files_stat.nr_files > old_max) { |
95 | printk(KERN_INFO "VFS: file-max limit %d reached\n", | 97 | printk(KERN_INFO "VFS: file-max limit %d reached\n", |
96 | files_stat.max_files); | 98 | files_stat.max_files); |
97 | old_max = files_stat.max_files; | 99 | old_max = files_stat.nr_files; |
98 | } else { | ||
99 | /* Big problems... */ | ||
100 | printk(KERN_WARNING "VFS: filp allocation failed\n"); | ||
101 | } | 100 | } |
101 | goto fail; | ||
102 | |||
103 | fail_sec: | ||
104 | file_free(f); | ||
102 | fail: | 105 | fail: |
103 | return NULL; | 106 | return NULL; |
104 | } | 107 | } |