1
2
3
4
5
6
7
8#include <linux/string.h>
9#include <linux/slab.h>
10#include <linux/file.h>
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/smp_lock.h>
14#include <linux/fs.h>
15#include <linux/security.h>
16#include <linux/eventpoll.h>
17#include <linux/mount.h>
18#include <linux/cdev.h>
19
20
21struct files_stat_struct files_stat = {
22 .max_files = NR_FILE
23};
24
25EXPORT_SYMBOL(files_stat);
26
27
28spinlock_t __cacheline_aligned_in_smp files_lock = SPIN_LOCK_UNLOCKED;
29
30static spinlock_t filp_count_lock = SPIN_LOCK_UNLOCKED;
31
32
33
34
35
36void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
37{
38 if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
39 SLAB_CTOR_CONSTRUCTOR) {
40 unsigned long flags;
41 spin_lock_irqsave(&filp_count_lock, flags);
42 files_stat.nr_files++;
43 spin_unlock_irqrestore(&filp_count_lock, flags);
44 }
45}
46
47void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
48{
49 unsigned long flags;
50 spin_lock_irqsave(&filp_count_lock, flags);
51 files_stat.nr_files--;
52 spin_unlock_irqrestore(&filp_count_lock, flags);
53}
54
55static inline void file_free(struct file *f)
56{
57 kmem_cache_free(filp_cachep, f);
58}
59
60
61
62
63
64struct file *get_empty_filp(void)
65{
66static int old_max;
67 struct file * f;
68
69
70
71
72 if (files_stat.nr_files < files_stat.max_files ||
73 capable(CAP_SYS_ADMIN)) {
74 f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
75 if (f) {
76 memset(f, 0, sizeof(*f));
77 if (security_file_alloc(f)) {
78 file_free(f);
79 goto fail;
80 }
81 eventpoll_init_file(f);
82 atomic_set(&f->f_count, 1);
83 f->f_uid = current->fsuid;
84 f->f_gid = current->fsgid;
85 f->f_owner.lock = RW_LOCK_UNLOCKED;
86
87 INIT_LIST_HEAD(&f->f_list);
88 return f;
89 }
90 }
91
92
93 if (files_stat.max_files >= old_max) {
94 printk(KERN_INFO "VFS: file-max limit %d reached\n",
95 files_stat.max_files);
96 old_max = files_stat.max_files;
97 } else {
98
99 printk(KERN_WARNING "VFS: filp allocation failed\n");
100 }
101fail:
102 return NULL;
103}
104
105EXPORT_SYMBOL(get_empty_filp);
106
107void fastcall fput(struct file *file)
108{
109 if (atomic_dec_and_test(&file->f_count))
110 __fput(file);
111}
112
113EXPORT_SYMBOL(fput);
114
115
116
117
118void fastcall __fput(struct file *file)
119{
120 struct dentry *dentry = file->f_dentry;
121 struct vfsmount *mnt = file->f_vfsmnt;
122 struct inode *inode = dentry->d_inode;
123
124 might_sleep();
125
126
127
128
129 eventpoll_release(file);
130 locks_remove_flock(file);
131
132 if (file->f_op && file->f_op->release)
133 file->f_op->release(inode, file);
134 security_file_free(file);
135 if (unlikely(inode->i_cdev != NULL))
136 cdev_put(inode->i_cdev);
137 fops_put(file->f_op);
138 if (file->f_mode & FMODE_WRITE)
139 put_write_access(inode);
140 file_kill(file);
141 file->f_dentry = NULL;
142 file->f_vfsmnt = NULL;
143 file_free(file);
144 dput(dentry);
145 mntput(mnt);
146}
147
148struct file fastcall *fget(unsigned int fd)
149{
150 struct file *file;
151 struct files_struct *files = current->files;
152
153 spin_lock(&files->file_lock);
154 file = fcheck_files(files, fd);
155 if (file)
156 get_file(file);
157 spin_unlock(&files->file_lock);
158 return file;
159}
160
161EXPORT_SYMBOL(fget);
162
163
164
165
166
167
168
169
170struct file fastcall *fget_light(unsigned int fd, int *fput_needed)
171{
172 struct file *file;
173 struct files_struct *files = current->files;
174
175 *fput_needed = 0;
176 if (likely((atomic_read(&files->count) == 1))) {
177 file = fcheck_files(files, fd);
178 } else {
179 spin_lock(&files->file_lock);
180 file = fcheck_files(files, fd);
181 if (file) {
182 get_file(file);
183 *fput_needed = 1;
184 }
185 spin_unlock(&files->file_lock);
186 }
187 return file;
188}
189
190
191void put_filp(struct file *file)
192{
193 if (atomic_dec_and_test(&file->f_count)) {
194 security_file_free(file);
195 file_kill(file);
196 file_free(file);
197 }
198}
199
200void file_move(struct file *file, struct list_head *list)
201{
202 if (!list)
203 return;
204 file_list_lock();
205 list_move(&file->f_list, list);
206 file_list_unlock();
207}
208
209void file_kill(struct file *file)
210{
211 if (!list_empty(&file->f_list)) {
212 file_list_lock();
213 list_del_init(&file->f_list);
214 file_list_unlock();
215 }
216}
217
218int fs_may_remount_ro(struct super_block *sb)
219{
220 struct list_head *p;
221
222
223 file_list_lock();
224 list_for_each(p, &sb->s_files) {
225 struct file *file = list_entry(p, struct file, f_list);
226 struct inode *inode = file->f_dentry->d_inode;
227
228
229 if (inode->i_nlink == 0)
230 goto too_bad;
231
232
233 if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
234 goto too_bad;
235 }
236 file_list_unlock();
237 return 1;
238too_bad:
239 file_list_unlock();
240 return 0;
241}
242
243void __init files_init(unsigned long mempages)
244{
245 int n;
246
247
248
249
250 n = (mempages * (PAGE_SIZE / 1024)) / 10;
251 files_stat.max_files = n;
252 if (files_stat.max_files < NR_FILE)
253 files_stat.max_files = NR_FILE;
254}
255