diff options
-rw-r--r-- | fs/file_table.c | 27 | ||||
-rw-r--r-- | fs/namei.c | 4 | ||||
-rw-r--r-- | fs/open.c | 27 |
3 files changed, 28 insertions, 30 deletions
diff --git a/fs/file_table.c b/fs/file_table.c index 0f607ce89acc..cd76d4fdf4a4 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -94,8 +94,8 @@ int proc_nr_files(ctl_table *table, int write, | |||
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | /* Find an unused file structure and return a pointer to it. | 96 | /* Find an unused file structure and return a pointer to it. |
97 | * Returns NULL, if there are no more free file structures or | 97 | * Returns an error pointer if some error happend e.g. we over file |
98 | * we run out of memory. | 98 | * structures limit, run out of memory or operation is not permitted. |
99 | * | 99 | * |
100 | * Be very careful using this. You are responsible for | 100 | * Be very careful using this. You are responsible for |
101 | * getting write access to any mount that you might assign | 101 | * getting write access to any mount that you might assign |
@@ -107,7 +107,8 @@ struct file *get_empty_filp(void) | |||
107 | { | 107 | { |
108 | const struct cred *cred = current_cred(); | 108 | const struct cred *cred = current_cred(); |
109 | static long old_max; | 109 | static long old_max; |
110 | struct file * f; | 110 | struct file *f; |
111 | int error; | ||
111 | 112 | ||
112 | /* | 113 | /* |
113 | * Privileged users can go above max_files | 114 | * Privileged users can go above max_files |
@@ -122,13 +123,16 @@ struct file *get_empty_filp(void) | |||
122 | } | 123 | } |
123 | 124 | ||
124 | f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); | 125 | f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); |
125 | if (f == NULL) | 126 | if (unlikely(!f)) |
126 | goto fail; | 127 | return ERR_PTR(-ENOMEM); |
127 | 128 | ||
128 | percpu_counter_inc(&nr_files); | 129 | percpu_counter_inc(&nr_files); |
129 | f->f_cred = get_cred(cred); | 130 | f->f_cred = get_cred(cred); |
130 | if (security_file_alloc(f)) | 131 | error = security_file_alloc(f); |
131 | goto fail_sec; | 132 | if (unlikely(error)) { |
133 | file_free(f); | ||
134 | return ERR_PTR(error); | ||
135 | } | ||
132 | 136 | ||
133 | INIT_LIST_HEAD(&f->f_u.fu_list); | 137 | INIT_LIST_HEAD(&f->f_u.fu_list); |
134 | atomic_long_set(&f->f_count, 1); | 138 | atomic_long_set(&f->f_count, 1); |
@@ -144,12 +148,7 @@ over: | |||
144 | pr_info("VFS: file-max limit %lu reached\n", get_max_files()); | 148 | pr_info("VFS: file-max limit %lu reached\n", get_max_files()); |
145 | old_max = get_nr_files(); | 149 | old_max = get_nr_files(); |
146 | } | 150 | } |
147 | goto fail; | 151 | return ERR_PTR(-ENFILE); |
148 | |||
149 | fail_sec: | ||
150 | file_free(f); | ||
151 | fail: | ||
152 | return NULL; | ||
153 | } | 152 | } |
154 | 153 | ||
155 | /** | 154 | /** |
@@ -173,7 +172,7 @@ struct file *alloc_file(struct path *path, fmode_t mode, | |||
173 | struct file *file; | 172 | struct file *file; |
174 | 173 | ||
175 | file = get_empty_filp(); | 174 | file = get_empty_filp(); |
176 | if (!file) | 175 | if (IS_ERR(file)) |
177 | return NULL; | 176 | return NULL; |
178 | 177 | ||
179 | file->f_path = *path; | 178 | file->f_path = *path; |
diff --git a/fs/namei.c b/fs/namei.c index df00b754631d..e0a33f598cdf 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2941,8 +2941,8 @@ static struct file *path_openat(int dfd, struct filename *pathname, | |||
2941 | int error; | 2941 | int error; |
2942 | 2942 | ||
2943 | file = get_empty_filp(); | 2943 | file = get_empty_filp(); |
2944 | if (!file) | 2944 | if (IS_ERR(file)) |
2945 | return ERR_PTR(-ENFILE); | 2945 | return file; |
2946 | 2946 | ||
2947 | file->f_flags = op->open_flag; | 2947 | file->f_flags = op->open_flag; |
2948 | 2948 | ||
@@ -810,23 +810,22 @@ struct file *dentry_open(const struct path *path, int flags, | |||
810 | /* We must always pass in a valid mount pointer. */ | 810 | /* We must always pass in a valid mount pointer. */ |
811 | BUG_ON(!path->mnt); | 811 | BUG_ON(!path->mnt); |
812 | 812 | ||
813 | error = -ENFILE; | ||
814 | f = get_empty_filp(); | 813 | f = get_empty_filp(); |
815 | if (f == NULL) | 814 | if (!IS_ERR(f)) { |
816 | return ERR_PTR(error); | 815 | f->f_flags = flags; |
817 | 816 | f->f_path = *path; | |
818 | f->f_flags = flags; | 817 | error = do_dentry_open(f, NULL, cred); |
819 | f->f_path = *path; | 818 | if (!error) { |
820 | error = do_dentry_open(f, NULL, cred); | 819 | /* from now on we need fput() to dispose of f */ |
821 | if (!error) { | 820 | error = open_check_o_direct(f); |
822 | error = open_check_o_direct(f); | 821 | if (error) { |
823 | if (error) { | 822 | fput(f); |
824 | fput(f); | 823 | f = ERR_PTR(error); |
824 | } | ||
825 | } else { | ||
826 | put_filp(f); | ||
825 | f = ERR_PTR(error); | 827 | f = ERR_PTR(error); |
826 | } | 828 | } |
827 | } else { | ||
828 | put_filp(f); | ||
829 | f = ERR_PTR(error); | ||
830 | } | 829 | } |
831 | return f; | 830 | return f; |
832 | } | 831 | } |