Blame view
fs/file_table.c
10.3 KB
457c89965 treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 11 |
/* * 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... |
12 |
#include <linux/fdtable.h> |
1da177e4c Linux-2.6.12-rc2 |
13 14 |
#include <linux/init.h> #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 |
#include <linux/fs.h> #include <linux/security.h> |
5b825c3af sched/headers: Pr... |
17 |
#include <linux/cred.h> |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include <linux/eventpoll.h> |
ab2af1f50 [PATCH] files: fi... |
19 |
#include <linux/rcupdate.h> |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include <linux/mount.h> |
16f7e0fe2 [PATCH] capable/c... |
21 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include <linux/cdev.h> |
0eeca2830 [PATCH] inotify |
23 |
#include <linux/fsnotify.h> |
529bf6be5 [PATCH] fix file ... |
24 25 |
#include <linux/sysctl.h> #include <linux/percpu_counter.h> |
6416ccb78 fs: scale files_lock |
26 |
#include <linux/percpu.h> |
4a9d4b024 switch fput to ta... |
27 |
#include <linux/task_work.h> |
0552f879d Untangling ima me... |
28 |
#include <linux/ima.h> |
4248b0da4 fs, file table: r... |
29 |
#include <linux/swap.h> |
529bf6be5 [PATCH] fix file ... |
30 |
|
60063497a atomic: use <linu... |
31 |
#include <linux/atomic.h> |
1da177e4c Linux-2.6.12-rc2 |
32 |
|
e81e3f4dc fs: move get_empt... |
33 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 |
/* sysctl tunables... */ struct files_stat_struct files_stat = { .max_files = NR_FILE }; |
b6b3fdead filp_cachep can b... |
38 39 |
/* SLAB cache for file structures */ static struct kmem_cache *filp_cachep __read_mostly; |
529bf6be5 [PATCH] fix file ... |
40 |
static struct percpu_counter nr_files __cacheline_aligned_in_smp; |
1da177e4c Linux-2.6.12-rc2 |
41 |
|
5c33b183a uninline file_fre... |
42 |
static void file_free_rcu(struct rcu_head *head) |
1da177e4c Linux-2.6.12-rc2 |
43 |
{ |
d76b0d9b2 CRED: Use creds i... |
44 45 46 |
struct file *f = container_of(head, struct file, f_u.fu_rcuhead); put_cred(f->f_cred); |
529bf6be5 [PATCH] fix file ... |
47 |
kmem_cache_free(filp_cachep, f); |
1da177e4c Linux-2.6.12-rc2 |
48 |
} |
529bf6be5 [PATCH] fix file ... |
49 |
static inline void file_free(struct file *f) |
1da177e4c Linux-2.6.12-rc2 |
50 |
{ |
e8cff84fa fold security_fil... |
51 |
security_file_free(f); |
d3b1084df vfs: make open_wi... |
52 53 |
if (!(f->f_mode & FMODE_NOACCOUNT)) percpu_counter_dec(&nr_files); |
529bf6be5 [PATCH] fix file ... |
54 |
call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); |
1da177e4c Linux-2.6.12-rc2 |
55 |
} |
529bf6be5 [PATCH] fix file ... |
56 57 58 |
/* * Return the total number of open files in the system */ |
518de9b39 fs: allow for mor... |
59 |
static long get_nr_files(void) |
1da177e4c Linux-2.6.12-rc2 |
60 |
{ |
529bf6be5 [PATCH] fix file ... |
61 |
return percpu_counter_read_positive(&nr_files); |
1da177e4c Linux-2.6.12-rc2 |
62 |
} |
529bf6be5 [PATCH] fix file ... |
63 64 65 |
/* * Return the maximum number of open files in the system */ |
518de9b39 fs: allow for mor... |
66 |
unsigned long get_max_files(void) |
ab2af1f50 [PATCH] files: fi... |
67 |
{ |
529bf6be5 [PATCH] fix file ... |
68 |
return files_stat.max_files; |
ab2af1f50 [PATCH] files: fi... |
69 |
} |
529bf6be5 [PATCH] fix file ... |
70 71 72 73 74 75 |
EXPORT_SYMBOL_GPL(get_max_files); /* * Handle nr_files sysctl */ #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) |
1f7e0616c fs: convert use o... |
76 |
int proc_nr_files(struct ctl_table *table, int write, |
32927393d sysctl: pass kern... |
77 |
void *buffer, size_t *lenp, loff_t *ppos) |
529bf6be5 [PATCH] fix file ... |
78 79 |
{ files_stat.nr_files = get_nr_files(); |
518de9b39 fs: allow for mor... |
80 |
return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); |
529bf6be5 [PATCH] fix file ... |
81 82 |
} #else |
1f7e0616c fs: convert use o... |
83 |
int proc_nr_files(struct ctl_table *table, int write, |
32927393d sysctl: pass kern... |
84 |
void *buffer, size_t *lenp, loff_t *ppos) |
529bf6be5 [PATCH] fix file ... |
85 86 87 88 |
{ return -ENOSYS; } #endif |
ab2af1f50 [PATCH] files: fi... |
89 |
|
d3b1084df vfs: make open_wi... |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
static struct file *__alloc_file(int flags, const struct cred *cred) { struct file *f; int error; f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (unlikely(!f)) return ERR_PTR(-ENOMEM); f->f_cred = get_cred(cred); error = security_file_alloc(f); if (unlikely(error)) { file_free_rcu(&f->f_u.fu_rcuhead); return ERR_PTR(error); } atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); spin_lock_init(&f->f_lock); mutex_init(&f->f_pos_lock); eventpoll_init_file(f); f->f_flags = flags; f->f_mode = OPEN_FMODE(flags); /* f->f_version: 0 */ return f; } |
1da177e4c Linux-2.6.12-rc2 |
117 |
/* Find an unused file structure and return a pointer to it. |
1afc99bea propagate error f... |
118 119 |
* Returns an error pointer if some error happend e.g. we over file * structures limit, run out of memory or operation is not permitted. |
430e285e0 [PATCH] fix up ne... |
120 121 122 123 124 125 |
* * 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 |
126 |
*/ |
ea73ea727 pass ->f_flags va... |
127 |
struct file *alloc_empty_file(int flags, const struct cred *cred) |
1da177e4c Linux-2.6.12-rc2 |
128 |
{ |
518de9b39 fs: allow for mor... |
129 |
static long old_max; |
1afc99bea propagate error f... |
130 |
struct file *f; |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 134 |
/* * Privileged users can go above max_files */ |
529bf6be5 [PATCH] fix file ... |
135 136 137 138 139 |
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... |
140 |
if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) |
529bf6be5 [PATCH] fix file ... |
141 142 |
goto over; } |
af4d2ecbf [PATCH] Fix of bo... |
143 |
|
d3b1084df vfs: make open_wi... |
144 145 146 |
f = __alloc_file(flags, cred); if (!IS_ERR(f)) percpu_counter_inc(&nr_files); |
1da177e4c Linux-2.6.12-rc2 |
147 |
|
af4d2ecbf [PATCH] Fix of bo... |
148 149 150 |
return f; over: |
1da177e4c Linux-2.6.12-rc2 |
151 |
/* Ran out of filps - report that */ |
529bf6be5 [PATCH] fix file ... |
152 |
if (get_nr_files() > old_max) { |
518de9b39 fs: allow for mor... |
153 154 |
pr_info("VFS: file-max limit %lu reached ", get_max_files()); |
529bf6be5 [PATCH] fix file ... |
155 |
old_max = get_nr_files(); |
1da177e4c Linux-2.6.12-rc2 |
156 |
} |
1afc99bea propagate error f... |
157 |
return ERR_PTR(-ENFILE); |
1da177e4c Linux-2.6.12-rc2 |
158 |
} |
d3b1084df vfs: make open_wi... |
159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/* * Variant of alloc_empty_file() that doesn't check and modify nr_files. * * Should not be used unless there's a very good reason to do so. */ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred) { struct file *f = __alloc_file(flags, cred); if (!IS_ERR(f)) f->f_mode |= FMODE_NOACCOUNT; return f; } |
ce8d2cdf3 r/o bind mounts: ... |
173 174 |
/** * alloc_file - allocate and initialize a 'struct file' |
a457606a6 fs/file_table.c: ... |
175 176 |
* * @path: the (dentry, vfsmount) pair for the new file |
c9c554f21 alloc_file(): swi... |
177 |
* @flags: O_... flags with which the new file will be opened |
ce8d2cdf3 r/o bind mounts: ... |
178 |
* @fop: the 'struct file_operations' for the new file |
ce8d2cdf3 r/o bind mounts: ... |
179 |
*/ |
ee1904ba4 make alloc_file()... |
180 |
static struct file *alloc_file(const struct path *path, int flags, |
2c48b9c45 switch alloc_file... |
181 |
const struct file_operations *fop) |
ce8d2cdf3 r/o bind mounts: ... |
182 183 |
{ struct file *file; |
ce8d2cdf3 r/o bind mounts: ... |
184 |
|
ea73ea727 pass ->f_flags va... |
185 |
file = alloc_empty_file(flags, current_cred()); |
1afc99bea propagate error f... |
186 |
if (IS_ERR(file)) |
39b652527 fs: Preserve erro... |
187 |
return file; |
ce8d2cdf3 r/o bind mounts: ... |
188 |
|
2c48b9c45 switch alloc_file... |
189 |
file->f_path = *path; |
dd37978c5 cache the value o... |
190 |
file->f_inode = path->dentry->d_inode; |
2c48b9c45 switch alloc_file... |
191 |
file->f_mapping = path->dentry->d_inode->i_mapping; |
5660e13d2 fs: new infrastru... |
192 |
file->f_wb_err = filemap_sample_wb_err(file->f_mapping); |
735e4ae5b vfs: track per-sb... |
193 |
file->f_sb_err = file_sample_sb_err(file); |
c9c554f21 alloc_file(): swi... |
194 |
if ((file->f_mode & FMODE_READ) && |
843631820 ->aio_read and ->... |
195 |
likely(fop->read || fop->read_iter)) |
c9c554f21 alloc_file(): swi... |
196 197 |
file->f_mode |= FMODE_CAN_READ; if ((file->f_mode & FMODE_WRITE) && |
843631820 ->aio_read and ->... |
198 |
likely(fop->write || fop->write_iter)) |
c9c554f21 alloc_file(): swi... |
199 |
file->f_mode |= FMODE_CAN_WRITE; |
f5d11409e introduce FMODE_O... |
200 |
file->f_mode |= FMODE_OPENED; |
ce8d2cdf3 r/o bind mounts: ... |
201 |
file->f_op = fop; |
c9c554f21 alloc_file(): swi... |
202 |
if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) |
890275b5e IMA: maintain i_r... |
203 |
i_readcount_inc(path->dentry->d_inode); |
3d1e46315 get rid of init_f... |
204 |
return file; |
ce8d2cdf3 r/o bind mounts: ... |
205 |
} |
ce8d2cdf3 r/o bind mounts: ... |
206 |
|
d93aa9d82 new wrapper: allo... |
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
struct file *alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt, const char *name, int flags, const struct file_operations *fops) { static const struct dentry_operations anon_ops = { .d_dname = simple_dname }; struct qstr this = QSTR_INIT(name, strlen(name)); struct path path; struct file *file; path.dentry = d_alloc_pseudo(mnt->mnt_sb, &this); if (!path.dentry) return ERR_PTR(-ENOMEM); if (!mnt->mnt_sb->s_d_op) d_set_d_op(path.dentry, &anon_ops); path.mnt = mntget(mnt); d_instantiate(path.dentry, inode); |
b6509f6a8 Revert "fs: Do no... |
225 |
file = alloc_file(&path, flags, fops); |
d93aa9d82 new wrapper: allo... |
226 227 228 229 230 231 232 |
if (IS_ERR(file)) { ihold(inode); path_put(&path); } return file; } EXPORT_SYMBOL(alloc_file_pseudo); |
183266f26 new helper: alloc... |
233 234 235 236 237 238 239 240 241 242 |
struct file *alloc_file_clone(struct file *base, int flags, const struct file_operations *fops) { struct file *f = alloc_file(&base->f_path, flags, fops); if (!IS_ERR(f)) { path_get(&f->f_path); f->f_mapping = base->f_mapping; } return f; } |
d7065da03 get rid of the ma... |
243 |
/* the real guts of fput() - releasing the last reference to file |
1da177e4c Linux-2.6.12-rc2 |
244 |
*/ |
d7065da03 get rid of the ma... |
245 |
static void __fput(struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
246 |
{ |
0f7fc9e4d [PATCH] VFS: chan... |
247 248 |
struct dentry *dentry = file->f_path.dentry; struct vfsmount *mnt = file->f_path.mnt; |
c77cecee5 Replace a bunch o... |
249 |
struct inode *inode = file->f_inode; |
a07b20004 vfs: syscall: Add... |
250 |
fmode_t mode = file->f_mode; |
1da177e4c Linux-2.6.12-rc2 |
251 |
|
4d27f3266 fold put_filp() i... |
252 253 |
if (unlikely(!(file->f_mode & FMODE_OPENED))) goto out; |
1da177e4c Linux-2.6.12-rc2 |
254 |
might_sleep(); |
0eeca2830 [PATCH] inotify |
255 256 |
fsnotify_close(file); |
1da177e4c Linux-2.6.12-rc2 |
257 258 259 260 261 |
/* * The function eventpoll_release() should be the first called * in the file cleanup chain. */ eventpoll_release(file); |
78ed8a133 locks: rename loc... |
262 |
locks_remove_file(file); |
1da177e4c Linux-2.6.12-rc2 |
263 |
|
bb02b186d ima: call ima_fil... |
264 |
ima_file_free(file); |
233e70f42 saner FASYNC hand... |
265 |
if (unlikely(file->f_flags & FASYNC)) { |
72c2d5319 file->f_op is nev... |
266 |
if (file->f_op->fasync) |
233e70f42 saner FASYNC hand... |
267 268 |
file->f_op->fasync(-1, file, 0); } |
72c2d5319 file->f_op is nev... |
269 |
if (file->f_op->release) |
1da177e4c Linux-2.6.12-rc2 |
270 |
file->f_op->release(inode, file); |
60ed8cf78 fix cdev leak on ... |
271 |
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL && |
a07b20004 vfs: syscall: Add... |
272 |
!(mode & FMODE_PATH))) { |
1da177e4c Linux-2.6.12-rc2 |
273 |
cdev_put(inode->i_cdev); |
60ed8cf78 fix cdev leak on ... |
274 |
} |
1da177e4c Linux-2.6.12-rc2 |
275 |
fops_put(file->f_op); |
609d7fa95 [PATCH] file: mod... |
276 |
put_pid(file->f_owner.pid); |
a07b20004 vfs: syscall: Add... |
277 |
if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) |
890275b5e IMA: maintain i_r... |
278 |
i_readcount_dec(inode); |
a07b20004 vfs: syscall: Add... |
279 |
if (mode & FMODE_WRITER) { |
83f936c75 mark struct file ... |
280 281 282 |
put_write_access(inode); __mnt_drop_write(mnt); } |
1da177e4c Linux-2.6.12-rc2 |
283 |
dput(dentry); |
a07b20004 vfs: syscall: Add... |
284 285 |
if (unlikely(mode & FMODE_NEED_UNMOUNT)) dissolve_on_fput(mnt); |
1da177e4c Linux-2.6.12-rc2 |
286 |
mntput(mnt); |
4d27f3266 fold put_filp() i... |
287 288 |
out: file_free(file); |
1da177e4c Linux-2.6.12-rc2 |
289 |
} |
4f5e65a1c fput: turn "list_... |
290 |
static LLIST_HEAD(delayed_fput_list); |
4a9d4b024 switch fput to ta... |
291 292 |
static void delayed_fput(struct work_struct *unused) { |
4f5e65a1c fput: turn "list_... |
293 |
struct llist_node *node = llist_del_all(&delayed_fput_list); |
b9ea557ee fput: Don't reinv... |
294 |
struct file *f, *t; |
4f5e65a1c fput: turn "list_... |
295 |
|
b9ea557ee fput: Don't reinv... |
296 297 |
llist_for_each_entry_safe(f, t, node, f_u.fu_llist) __fput(f); |
4a9d4b024 switch fput to ta... |
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
} static void ____fput(struct callback_head *work) { __fput(container_of(work, struct file, f_u.fu_rcuhead)); } /* * If kernel thread really needs to have the final fput() it has done * to complete, call this. The only user right now is the boot - we * *do* need to make sure our writes to binaries on initramfs has * not left us with opened struct file waiting for __fput() - execve() * won't work without that. Please, don't add more callers without * very good reasons; in particular, never call that with locks * held and never call that from a thread that might need to do * some work on any kind of umount. */ void flush_delayed_fput(void) { delayed_fput(NULL); } |
7239a40ca vfs: Export flush... |
319 |
EXPORT_SYMBOL_GPL(flush_delayed_fput); |
4a9d4b024 switch fput to ta... |
320 |
|
c7314d74f nfsd regression s... |
321 |
static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); |
4a9d4b024 switch fput to ta... |
322 |
|
091141a42 fs: add fget_many... |
323 |
void fput_many(struct file *file, unsigned int refs) |
d7065da03 get rid of the ma... |
324 |
{ |
091141a42 fs: add fget_many... |
325 |
if (atomic_long_sub_and_test(refs, &file->f_count)) { |
4a9d4b024 switch fput to ta... |
326 |
struct task_struct *task = current; |
e7b2c4069 fput: task_work_a... |
327 |
|
e7b2c4069 fput: task_work_a... |
328 329 |
if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { init_task_work(&file->f_u.fu_rcuhead, ____fput); |
91989c707 task_work: cleanu... |
330 |
if (!task_work_add(task, &file->f_u.fu_rcuhead, TWA_RESUME)) |
e7b2c4069 fput: task_work_a... |
331 |
return; |
64372501e fs/file_table.c:f... |
332 333 |
/* * After this task has run exit_task_work(), |
be49b30a9 fs/file_table.c:f... |
334 |
* task_work_add() will fail. Fall through to delayed |
64372501e fs/file_table.c:f... |
335 336 |
* fput to avoid leaking *file. */ |
4a9d4b024 switch fput to ta... |
337 |
} |
4f5e65a1c fput: turn "list_... |
338 339 |
if (llist_add(&file->f_u.fu_llist, &delayed_fput_list)) |
c7314d74f nfsd regression s... |
340 |
schedule_delayed_work(&delayed_fput_work, 1); |
4a9d4b024 switch fput to ta... |
341 342 |
} } |
091141a42 fs: add fget_many... |
343 344 345 346 |
void fput(struct file *file) { fput_many(file, 1); } |
4a9d4b024 switch fput to ta... |
347 348 349 350 351 352 353 354 355 356 357 358 |
/* * synchronous analog of fput(); for kernel threads that might be needed * in some umount() (and thus can't use flush_delayed_fput() without * risking deadlocks), need to wait for completion of __fput() and know * for this specific struct file it won't involve anything that would * need them. Use only if you really need it - at the very least, * don't blindly convert fput() by kernel thread to that. */ void __fput_sync(struct file *file) { if (atomic_long_dec_and_test(&file->f_count)) { struct task_struct *task = current; |
4a9d4b024 switch fput to ta... |
359 |
BUG_ON(!(task->flags & PF_KTHREAD)); |
d7065da03 get rid of the ma... |
360 |
__fput(file); |
4a9d4b024 switch fput to ta... |
361 |
} |
d7065da03 get rid of the ma... |
362 363 364 |
} EXPORT_SYMBOL(fput); |
4248b0da4 fs, file table: r... |
365 |
void __init files_init(void) |
b9ea557ee fput: Don't reinv... |
366 |
{ |
b6b3fdead filp_cachep can b... |
367 |
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, |
f3f7c0935 fs, mm: account f... |
368 |
SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT, NULL); |
4248b0da4 fs, file table: r... |
369 370 |
percpu_counter_init(&nr_files, 0, GFP_KERNEL); } |
b6b3fdead filp_cachep can b... |
371 |
|
4248b0da4 fs, file table: r... |
372 373 374 375 376 377 378 |
/* * One file with associated inode and dcache is very roughly 1K. Per default * do not use more than 10% of our memory for files. */ void __init files_maxfiles_init(void) { unsigned long n; |
ca79b0c21 mm: convert total... |
379 |
unsigned long nr_pages = totalram_pages(); |
3d6357de8 mm: reference tot... |
380 |
unsigned long memreserve = (nr_pages - nr_free_pages()) * 3/2; |
4248b0da4 fs, file table: r... |
381 |
|
3d6357de8 mm: reference tot... |
382 383 |
memreserve = min(memreserve, nr_pages - 1); n = ((nr_pages - memreserve) * (PAGE_SIZE / 1024)) / 10; |
1da177e4c Linux-2.6.12-rc2 |
384 |
|
518de9b39 fs: allow for mor... |
385 |
files_stat.max_files = max_t(unsigned long, n, NR_FILE); |
b9ea557ee fput: Don't reinv... |
386 |
} |