Blame view
fs/file_table.c
10.1 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 |
/* * linux/fs/file_table.c * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */ #include <linux/string.h> #include <linux/slab.h> #include <linux/file.h> |
9f3acc314 [PATCH] split lin... |
11 |
#include <linux/fdtable.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/init.h> #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 |
#include <linux/fs.h> #include <linux/security.h> #include <linux/eventpoll.h> |
ab2af1f50 [PATCH] files: fi... |
17 |
#include <linux/rcupdate.h> |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include <linux/mount.h> |
16f7e0fe2 [PATCH] capable/c... |
19 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include <linux/cdev.h> |
0eeca2830 [PATCH] inotify |
21 |
#include <linux/fsnotify.h> |
529bf6be5 [PATCH] fix file ... |
22 23 |
#include <linux/sysctl.h> #include <linux/percpu_counter.h> |
0552f879d Untangling ima me... |
24 |
#include <linux/ima.h> |
529bf6be5 [PATCH] fix file ... |
25 26 |
#include <asm/atomic.h> |
1da177e4c Linux-2.6.12-rc2 |
27 |
|
e81e3f4dc fs: move get_empt... |
28 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 32 |
/* sysctl tunables... */ struct files_stat_struct files_stat = { .max_files = NR_FILE }; |
1da177e4c Linux-2.6.12-rc2 |
33 |
/* public. Not pretty! */ |
529bf6be5 [PATCH] fix file ... |
34 |
__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); |
1da177e4c Linux-2.6.12-rc2 |
35 |
|
b6b3fdead filp_cachep can b... |
36 37 |
/* SLAB cache for file structures */ static struct kmem_cache *filp_cachep __read_mostly; |
529bf6be5 [PATCH] fix file ... |
38 |
static struct percpu_counter nr_files __cacheline_aligned_in_smp; |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
529bf6be5 [PATCH] fix file ... |
40 |
static inline void file_free_rcu(struct rcu_head *head) |
1da177e4c Linux-2.6.12-rc2 |
41 |
{ |
d76b0d9b2 CRED: Use creds i... |
42 43 44 |
struct file *f = container_of(head, struct file, f_u.fu_rcuhead); put_cred(f->f_cred); |
529bf6be5 [PATCH] fix file ... |
45 |
kmem_cache_free(filp_cachep, f); |
1da177e4c Linux-2.6.12-rc2 |
46 |
} |
529bf6be5 [PATCH] fix file ... |
47 |
static inline void file_free(struct file *f) |
1da177e4c Linux-2.6.12-rc2 |
48 |
{ |
529bf6be5 [PATCH] fix file ... |
49 |
percpu_counter_dec(&nr_files); |
ad775f5a8 [PATCH] r/o bind ... |
50 |
file_check_state(f); |
529bf6be5 [PATCH] fix file ... |
51 |
call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); |
1da177e4c Linux-2.6.12-rc2 |
52 |
} |
529bf6be5 [PATCH] fix file ... |
53 54 55 56 |
/* * Return the total number of open files in the system */ static int get_nr_files(void) |
1da177e4c Linux-2.6.12-rc2 |
57 |
{ |
529bf6be5 [PATCH] fix file ... |
58 |
return percpu_counter_read_positive(&nr_files); |
1da177e4c Linux-2.6.12-rc2 |
59 |
} |
529bf6be5 [PATCH] fix file ... |
60 61 62 63 |
/* * Return the maximum number of open files in the system */ int get_max_files(void) |
ab2af1f50 [PATCH] files: fi... |
64 |
{ |
529bf6be5 [PATCH] fix file ... |
65 |
return files_stat.max_files; |
ab2af1f50 [PATCH] files: fi... |
66 |
} |
529bf6be5 [PATCH] fix file ... |
67 68 69 70 71 72 |
EXPORT_SYMBOL_GPL(get_max_files); /* * Handle nr_files sysctl */ #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) |
8d65af789 sysctl: remove "s... |
73 |
int proc_nr_files(ctl_table *table, int write, |
529bf6be5 [PATCH] fix file ... |
74 75 76 |
void __user *buffer, size_t *lenp, loff_t *ppos) { files_stat.nr_files = get_nr_files(); |
8d65af789 sysctl: remove "s... |
77 |
return proc_dointvec(table, write, buffer, lenp, ppos); |
529bf6be5 [PATCH] fix file ... |
78 79 |
} #else |
8d65af789 sysctl: remove "s... |
80 |
int proc_nr_files(ctl_table *table, int write, |
529bf6be5 [PATCH] fix file ... |
81 82 83 84 85 |
void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } #endif |
ab2af1f50 [PATCH] files: fi... |
86 |
|
1da177e4c Linux-2.6.12-rc2 |
87 88 89 |
/* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. |
430e285e0 [PATCH] fix up ne... |
90 91 92 93 94 95 |
* * Be very careful using this. You are responsible for * getting write access to any mount that you might assign * to this filp, if it is opened for write. If this is not * done, you will imbalance int the mount's writer count * and a warning at __fput() time. |
1da177e4c Linux-2.6.12-rc2 |
96 97 98 |
*/ struct file *get_empty_filp(void) { |
86a264abe CRED: Wrap curren... |
99 |
const struct cred *cred = current_cred(); |
af4d2ecbf [PATCH] Fix of bo... |
100 |
static int old_max; |
1da177e4c Linux-2.6.12-rc2 |
101 102 103 104 105 |
struct file * f; /* * Privileged users can go above max_files */ |
529bf6be5 [PATCH] fix file ... |
106 107 108 109 110 |
if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* * percpu_counters are inaccurate. Do an expensive check before * we go and fail. */ |
52d9f3b40 lib: percpu_count... |
111 |
if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) |
529bf6be5 [PATCH] fix file ... |
112 113 |
goto over; } |
af4d2ecbf [PATCH] Fix of bo... |
114 |
|
4975e45ff fs: use kmem_cach... |
115 |
f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); |
af4d2ecbf [PATCH] Fix of bo... |
116 117 |
if (f == NULL) goto fail; |
529bf6be5 [PATCH] fix file ... |
118 |
percpu_counter_inc(&nr_files); |
af4d2ecbf [PATCH] Fix of bo... |
119 120 |
if (security_file_alloc(f)) goto fail_sec; |
1da177e4c Linux-2.6.12-rc2 |
121 |
|
5a6b7951b [PATCH] get_empty... |
122 |
INIT_LIST_HEAD(&f->f_u.fu_list); |
516e0cc56 [PATCH] f_count m... |
123 |
atomic_long_set(&f->f_count, 1); |
af4d2ecbf [PATCH] Fix of bo... |
124 |
rwlock_init(&f->f_owner.lock); |
d76b0d9b2 CRED: Use creds i... |
125 |
f->f_cred = get_cred(cred); |
684999149 Rename struct fil... |
126 |
spin_lock_init(&f->f_lock); |
5a6b7951b [PATCH] get_empty... |
127 |
eventpoll_init_file(f); |
af4d2ecbf [PATCH] Fix of bo... |
128 |
/* f->f_version: 0 */ |
af4d2ecbf [PATCH] Fix of bo... |
129 130 131 |
return f; over: |
1da177e4c Linux-2.6.12-rc2 |
132 |
/* Ran out of filps - report that */ |
529bf6be5 [PATCH] fix file ... |
133 |
if (get_nr_files() > old_max) { |
1da177e4c Linux-2.6.12-rc2 |
134 135 |
printk(KERN_INFO "VFS: file-max limit %d reached ", |
529bf6be5 [PATCH] fix file ... |
136 137 |
get_max_files()); old_max = get_nr_files(); |
1da177e4c Linux-2.6.12-rc2 |
138 |
} |
af4d2ecbf [PATCH] Fix of bo... |
139 140 141 142 |
goto fail; fail_sec: file_free(f); |
1da177e4c Linux-2.6.12-rc2 |
143 144 145 |
fail: return NULL; } |
ce8d2cdf3 r/o bind mounts: ... |
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
/** * alloc_file - allocate and initialize a 'struct file' * @mnt: the vfsmount on which the file will reside * @dentry: the dentry representing the new file * @mode: the mode with which the new file will be opened * @fop: the 'struct file_operations' for the new file * * Use this instead of get_empty_filp() to get a new * 'struct file'. Do so because of the same initialization * pitfalls reasons listed for init_file(). This is a * preferred interface to using init_file(). * * If all the callers of init_file() are eliminated, its * code should be moved into this function. */ |
2c48b9c45 switch alloc_file... |
161 162 |
struct file *alloc_file(struct path *path, fmode_t mode, const struct file_operations *fop) |
ce8d2cdf3 r/o bind mounts: ... |
163 164 |
{ struct file *file; |
ce8d2cdf3 r/o bind mounts: ... |
165 166 167 168 |
file = get_empty_filp(); if (!file) return NULL; |
2c48b9c45 switch alloc_file... |
169 170 |
file->f_path = *path; file->f_mapping = path->dentry->d_inode->i_mapping; |
ce8d2cdf3 r/o bind mounts: ... |
171 172 |
file->f_mode = mode; file->f_op = fop; |
4a3fd211c [PATCH] r/o bind ... |
173 174 175 176 177 178 179 |
/* * These mounts don't really matter in practice * for r/o bind mounts. They aren't userspace- * visible. We do this for consistency, and so * that we can do debugging checks at __fput() */ |
2c48b9c45 switch alloc_file... |
180 |
if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) { |
ad775f5a8 [PATCH] r/o bind ... |
181 |
file_take_write(file); |
385e3ed4f alloc_file(): sim... |
182 |
WARN_ON(mnt_clone_write(path->mnt)); |
4a3fd211c [PATCH] r/o bind ... |
183 |
} |
0552f879d Untangling ima me... |
184 |
ima_counts_get(file); |
3d1e46315 get rid of init_f... |
185 |
return file; |
ce8d2cdf3 r/o bind mounts: ... |
186 |
} |
73efc4681 re-export alloc_f... |
187 |
EXPORT_SYMBOL(alloc_file); |
ce8d2cdf3 r/o bind mounts: ... |
188 |
|
fc9b52cd8 fs: remove fastca... |
189 |
void fput(struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
190 |
{ |
516e0cc56 [PATCH] f_count m... |
191 |
if (atomic_long_dec_and_test(&file->f_count)) |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 195 |
__fput(file); } EXPORT_SYMBOL(fput); |
aceaf78da [PATCH] r/o bind ... |
196 197 198 199 200 201 202 203 204 205 |
/** * drop_file_write_access - give up ability to write to a file * @file: the file to which we will stop writing * * This is a central place which will give up the ability * to write to @file, along with access to write through * its vfsmount. */ void drop_file_write_access(struct file *file) { |
4a3fd211c [PATCH] r/o bind ... |
206 |
struct vfsmount *mnt = file->f_path.mnt; |
aceaf78da [PATCH] r/o bind ... |
207 208 209 210 |
struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; put_write_access(inode); |
ad775f5a8 [PATCH] r/o bind ... |
211 212 213 214 215 216 217 |
if (special_file(inode->i_mode)) return; if (file_check_writeable(file) != 0) return; mnt_drop_write(mnt); file_release_write(file); |
aceaf78da [PATCH] r/o bind ... |
218 219 |
} EXPORT_SYMBOL_GPL(drop_file_write_access); |
1da177e4c Linux-2.6.12-rc2 |
220 221 222 |
/* __fput is called from task context when aio completion releases the last * last use of a struct file *. Do not use otherwise. */ |
fc9b52cd8 fs: remove fastca... |
223 |
void __fput(struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
224 |
{ |
0f7fc9e4d [PATCH] VFS: chan... |
225 226 |
struct dentry *dentry = file->f_path.dentry; struct vfsmount *mnt = file->f_path.mnt; |
1da177e4c Linux-2.6.12-rc2 |
227 228 229 |
struct inode *inode = dentry->d_inode; might_sleep(); |
0eeca2830 [PATCH] inotify |
230 231 |
fsnotify_close(file); |
1da177e4c Linux-2.6.12-rc2 |
232 233 234 235 236 237 |
/* * The function eventpoll_release() should be the first called * in the file cleanup chain. */ eventpoll_release(file); locks_remove_flock(file); |
233e70f42 saner FASYNC hand... |
238 239 240 241 |
if (unlikely(file->f_flags & FASYNC)) { if (file->f_op && file->f_op->fasync) file->f_op->fasync(-1, file, 0); } |
1da177e4c Linux-2.6.12-rc2 |
242 243 244 |
if (file->f_op && file->f_op->release) file->f_op->release(inode, file); security_file_free(file); |
89068c576 Take ima_file_fre... |
245 |
ima_file_free(file); |
577c4eb09 [PATCH] inode-die... |
246 |
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) |
1da177e4c Linux-2.6.12-rc2 |
247 248 |
cdev_put(inode->i_cdev); fops_put(file->f_op); |
609d7fa95 [PATCH] file: mod... |
249 |
put_pid(file->f_owner.pid); |
1da177e4c Linux-2.6.12-rc2 |
250 |
file_kill(file); |
aceaf78da [PATCH] r/o bind ... |
251 252 |
if (file->f_mode & FMODE_WRITE) drop_file_write_access(file); |
0f7fc9e4d [PATCH] VFS: chan... |
253 254 |
file->f_path.dentry = NULL; file->f_path.mnt = NULL; |
1da177e4c Linux-2.6.12-rc2 |
255 256 257 258 |
file_free(file); dput(dentry); mntput(mnt); } |
fc9b52cd8 fs: remove fastca... |
259 |
struct file *fget(unsigned int fd) |
1da177e4c Linux-2.6.12-rc2 |
260 261 262 |
{ struct file *file; struct files_struct *files = current->files; |
ab2af1f50 [PATCH] files: fi... |
263 |
rcu_read_lock(); |
1da177e4c Linux-2.6.12-rc2 |
264 |
file = fcheck_files(files, fd); |
ab2af1f50 [PATCH] files: fi... |
265 |
if (file) { |
516e0cc56 [PATCH] f_count m... |
266 |
if (!atomic_long_inc_not_zero(&file->f_count)) { |
ab2af1f50 [PATCH] files: fi... |
267 268 269 270 271 272 |
/* File object ref couldn't be taken */ rcu_read_unlock(); return NULL; } } rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
273 274 275 276 277 278 279 280 281 282 283 284 |
return file; } EXPORT_SYMBOL(fget); /* * Lightweight file lookup - no refcnt increment if fd table isn't shared. * You can use this only if it is guranteed that the current task already * holds a refcnt to that file. That check has to be done at fget() only * and a flag is returned to be passed to the corresponding fput_light(). * There must not be a cloning between an fget_light/fput_light pair. */ |
fc9b52cd8 fs: remove fastca... |
285 |
struct file *fget_light(unsigned int fd, int *fput_needed) |
1da177e4c Linux-2.6.12-rc2 |
286 287 288 289 290 291 292 293 |
{ struct file *file; struct files_struct *files = current->files; *fput_needed = 0; if (likely((atomic_read(&files->count) == 1))) { file = fcheck_files(files, fd); } else { |
ab2af1f50 [PATCH] files: fi... |
294 |
rcu_read_lock(); |
1da177e4c Linux-2.6.12-rc2 |
295 296 |
file = fcheck_files(files, fd); if (file) { |
516e0cc56 [PATCH] f_count m... |
297 |
if (atomic_long_inc_not_zero(&file->f_count)) |
ab2af1f50 [PATCH] files: fi... |
298 299 300 301 |
*fput_needed = 1; else /* Didn't get the reference, someone's freed */ file = NULL; |
1da177e4c Linux-2.6.12-rc2 |
302 |
} |
ab2af1f50 [PATCH] files: fi... |
303 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
304 |
} |
ab2af1f50 [PATCH] files: fi... |
305 |
|
1da177e4c Linux-2.6.12-rc2 |
306 307 308 309 310 311 |
return file; } void put_filp(struct file *file) { |
516e0cc56 [PATCH] f_count m... |
312 |
if (atomic_long_dec_and_test(&file->f_count)) { |
1da177e4c Linux-2.6.12-rc2 |
313 314 315 316 317 318 319 320 321 322 323 |
security_file_free(file); file_kill(file); file_free(file); } } void file_move(struct file *file, struct list_head *list) { if (!list) return; file_list_lock(); |
2f5120166 [PATCH] reduce si... |
324 |
list_move(&file->f_u.fu_list, list); |
1da177e4c Linux-2.6.12-rc2 |
325 326 327 328 329 |
file_list_unlock(); } void file_kill(struct file *file) { |
2f5120166 [PATCH] reduce si... |
330 |
if (!list_empty(&file->f_u.fu_list)) { |
1da177e4c Linux-2.6.12-rc2 |
331 |
file_list_lock(); |
2f5120166 [PATCH] reduce si... |
332 |
list_del_init(&file->f_u.fu_list); |
1da177e4c Linux-2.6.12-rc2 |
333 334 335 336 337 338 |
file_list_unlock(); } } int fs_may_remount_ro(struct super_block *sb) { |
cfdaf9e5f fs/file_table.c: ... |
339 |
struct file *file; |
1da177e4c Linux-2.6.12-rc2 |
340 341 342 |
/* Check that no files are currently opened for writing. */ file_list_lock(); |
cfdaf9e5f fs/file_table.c: ... |
343 |
list_for_each_entry(file, &sb->s_files, f_u.fu_list) { |
0f7fc9e4d [PATCH] VFS: chan... |
344 |
struct inode *inode = file->f_path.dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
/* File with pending delete? */ if (inode->i_nlink == 0) goto too_bad; /* Writeable file? */ if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) goto too_bad; } file_list_unlock(); return 1; /* Tis' cool bro. */ too_bad: file_list_unlock(); return 0; } |
864d7c4c0 fs: move mark_fil... |
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
/** * mark_files_ro - mark all files read-only * @sb: superblock in question * * All files are marked read-only. We don't care about pending * delete files so this should be used in 'force' mode only. */ void mark_files_ro(struct super_block *sb) { struct file *f; retry: file_list_lock(); list_for_each_entry(f, &sb->s_files, f_u.fu_list) { struct vfsmount *mnt; if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) continue; if (!file_count(f)) continue; if (!(f->f_mode & FMODE_WRITE)) continue; |
42e496086 vfs: take f_lock ... |
381 |
spin_lock(&f->f_lock); |
864d7c4c0 fs: move mark_fil... |
382 |
f->f_mode &= ~FMODE_WRITE; |
42e496086 vfs: take f_lock ... |
383 |
spin_unlock(&f->f_lock); |
864d7c4c0 fs: move mark_fil... |
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
if (file_check_writeable(f) != 0) continue; file_release_write(f); mnt = mntget(f->f_path.mnt); file_list_unlock(); /* * This can sleep, so we can't hold * the file_list_lock() spinlock. */ mnt_drop_write(mnt); mntput(mnt); goto retry; } file_list_unlock(); } |
1da177e4c Linux-2.6.12-rc2 |
399 400 401 |
void __init files_init(unsigned long mempages) { int n; |
b6b3fdead filp_cachep can b... |
402 403 404 405 406 407 |
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); /* * One file with associated inode and dcache is very roughly 1K. |
1da177e4c Linux-2.6.12-rc2 |
408 409 410 411 412 413 414 |
* Per default don't use more than 10% of our memory for files. */ n = (mempages * (PAGE_SIZE / 1024)) / 10; files_stat.max_files = n; if (files_stat.max_files < NR_FILE) files_stat.max_files = NR_FILE; |
ab2af1f50 [PATCH] files: fi... |
415 |
files_defer_init(); |
0216bfcff [PATCH] percpu co... |
416 |
percpu_counter_init(&nr_files, 0); |
1da177e4c Linux-2.6.12-rc2 |
417 |
} |