diff options
Diffstat (limited to 'fs/file_table.c')
-rw-r--r-- | fs/file_table.c | 51 |
1 files changed, 12 insertions, 39 deletions
diff --git a/fs/file_table.c b/fs/file_table.c index 8eb44042e009..17a55b81be2d 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/security.h> | 15 | #include <linux/security.h> |
16 | #include <linux/ima.h> | ||
17 | #include <linux/eventpoll.h> | 16 | #include <linux/eventpoll.h> |
18 | #include <linux/rcupdate.h> | 17 | #include <linux/rcupdate.h> |
19 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
@@ -22,9 +21,12 @@ | |||
22 | #include <linux/fsnotify.h> | 21 | #include <linux/fsnotify.h> |
23 | #include <linux/sysctl.h> | 22 | #include <linux/sysctl.h> |
24 | #include <linux/percpu_counter.h> | 23 | #include <linux/percpu_counter.h> |
24 | #include <linux/ima.h> | ||
25 | 25 | ||
26 | #include <asm/atomic.h> | 26 | #include <asm/atomic.h> |
27 | 27 | ||
28 | #include "internal.h" | ||
29 | |||
28 | /* sysctl tunables... */ | 30 | /* sysctl tunables... */ |
29 | struct files_stat_struct files_stat = { | 31 | struct files_stat_struct files_stat = { |
30 | .max_files = NR_FILE | 32 | .max_files = NR_FILE |
@@ -148,8 +150,6 @@ fail: | |||
148 | return NULL; | 150 | return NULL; |
149 | } | 151 | } |
150 | 152 | ||
151 | EXPORT_SYMBOL(get_empty_filp); | ||
152 | |||
153 | /** | 153 | /** |
154 | * alloc_file - allocate and initialize a 'struct file' | 154 | * alloc_file - allocate and initialize a 'struct file' |
155 | * @mnt: the vfsmount on which the file will reside | 155 | * @mnt: the vfsmount on which the file will reside |
@@ -165,8 +165,8 @@ EXPORT_SYMBOL(get_empty_filp); | |||
165 | * If all the callers of init_file() are eliminated, its | 165 | * If all the callers of init_file() are eliminated, its |
166 | * code should be moved into this function. | 166 | * code should be moved into this function. |
167 | */ | 167 | */ |
168 | struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry, | 168 | struct file *alloc_file(struct path *path, fmode_t mode, |
169 | fmode_t mode, const struct file_operations *fop) | 169 | const struct file_operations *fop) |
170 | { | 170 | { |
171 | struct file *file; | 171 | struct file *file; |
172 | 172 | ||
@@ -174,35 +174,8 @@ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry, | |||
174 | if (!file) | 174 | if (!file) |
175 | return NULL; | 175 | return NULL; |
176 | 176 | ||
177 | init_file(file, mnt, dentry, mode, fop); | 177 | file->f_path = *path; |
178 | return file; | 178 | file->f_mapping = path->dentry->d_inode->i_mapping; |
179 | } | ||
180 | EXPORT_SYMBOL(alloc_file); | ||
181 | |||
182 | /** | ||
183 | * init_file - initialize a 'struct file' | ||
184 | * @file: the already allocated 'struct file' to initialized | ||
185 | * @mnt: the vfsmount on which the file resides | ||
186 | * @dentry: the dentry representing this file | ||
187 | * @mode: the mode the file is opened with | ||
188 | * @fop: the 'struct file_operations' for this file | ||
189 | * | ||
190 | * Use this instead of setting the members directly. Doing so | ||
191 | * avoids making mistakes like forgetting the mntget() or | ||
192 | * forgetting to take a write on the mnt. | ||
193 | * | ||
194 | * Note: This is a crappy interface. It is here to make | ||
195 | * merging with the existing users of get_empty_filp() | ||
196 | * who have complex failure logic easier. All users | ||
197 | * of this should be moving to alloc_file(). | ||
198 | */ | ||
199 | int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry, | ||
200 | fmode_t mode, const struct file_operations *fop) | ||
201 | { | ||
202 | int error = 0; | ||
203 | file->f_path.dentry = dentry; | ||
204 | file->f_path.mnt = mntget(mnt); | ||
205 | file->f_mapping = dentry->d_inode->i_mapping; | ||
206 | file->f_mode = mode; | 179 | file->f_mode = mode; |
207 | file->f_op = fop; | 180 | file->f_op = fop; |
208 | 181 | ||
@@ -212,14 +185,15 @@ int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry, | |||
212 | * visible. We do this for consistency, and so | 185 | * visible. We do this for consistency, and so |
213 | * that we can do debugging checks at __fput() | 186 | * that we can do debugging checks at __fput() |
214 | */ | 187 | */ |
215 | if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) { | 188 | if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) { |
189 | int error = 0; | ||
216 | file_take_write(file); | 190 | file_take_write(file); |
217 | error = mnt_clone_write(mnt); | 191 | error = mnt_clone_write(path->mnt); |
218 | WARN_ON(error); | 192 | WARN_ON(error); |
219 | } | 193 | } |
220 | return error; | 194 | ima_counts_get(file); |
195 | return file; | ||
221 | } | 196 | } |
222 | EXPORT_SYMBOL(init_file); | ||
223 | 197 | ||
224 | void fput(struct file *file) | 198 | void fput(struct file *file) |
225 | { | 199 | { |
@@ -280,7 +254,6 @@ void __fput(struct file *file) | |||
280 | if (file->f_op && file->f_op->release) | 254 | if (file->f_op && file->f_op->release) |
281 | file->f_op->release(inode, file); | 255 | file->f_op->release(inode, file); |
282 | security_file_free(file); | 256 | security_file_free(file); |
283 | ima_file_free(file); | ||
284 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) | 257 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) |
285 | cdev_put(inode->i_cdev); | 258 | cdev_put(inode->i_cdev); |
286 | fops_put(file->f_op); | 259 | fops_put(file->f_op); |