Blame view

fs/file_table.c 12.6 KB
1da177e4c   Linus Torvalds   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   Al Viro   [PATCH] split lin...
11
  #include <linux/fdtable.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
  #include <linux/init.h>
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
  #include <linux/fs.h>
  #include <linux/security.h>
  #include <linux/eventpoll.h>
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
17
  #include <linux/rcupdate.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #include <linux/mount.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
19
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include <linux/cdev.h>
0eeca2830   Robert Love   [PATCH] inotify
21
  #include <linux/fsnotify.h>
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
22
  #include <linux/sysctl.h>
6416ccb78   Nick Piggin   fs: scale files_lock
23
  #include <linux/lglock.h>
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
24
  #include <linux/percpu_counter.h>
6416ccb78   Nick Piggin   fs: scale files_lock
25
  #include <linux/percpu.h>
0552f879d   Al Viro   Untangling ima me...
26
  #include <linux/ima.h>
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
27

60063497a   Arun Sharma   atomic: use <linu...
28
  #include <linux/atomic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29

e81e3f4dc   Eric Paris   fs: move get_empt...
30
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
  /* sysctl tunables... */
  struct files_stat_struct files_stat = {
  	.max_files = NR_FILE
  };
6416ccb78   Nick Piggin   fs: scale files_lock
35
36
  DECLARE_LGLOCK(files_lglock);
  DEFINE_LGLOCK(files_lglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

b6b3fdead   Eric Dumazet   filp_cachep can b...
38
39
  /* SLAB cache for file structures */
  static struct kmem_cache *filp_cachep __read_mostly;
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
40
  static struct percpu_counter nr_files __cacheline_aligned_in_smp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

529bf6be5   Dipankar Sarma   [PATCH] fix file ...
42
  static inline void file_free_rcu(struct rcu_head *head)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  {
d76b0d9b2   David Howells   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   Dipankar Sarma   [PATCH] fix file ...
47
  	kmem_cache_free(filp_cachep, f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  }
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
49
  static inline void file_free(struct file *f)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  {
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
51
  	percpu_counter_dec(&nr_files);
ad775f5a8   Dave Hansen   [PATCH] r/o bind ...
52
  	file_check_state(f);
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
53
  	call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  }
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
55
56
57
  /*
   * Return the total number of open files in the system
   */
518de9b39   Eric Dumazet   fs: allow for mor...
58
  static long get_nr_files(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  {
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
60
  	return percpu_counter_read_positive(&nr_files);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  }
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
62
63
64
  /*
   * Return the maximum number of open files in the system
   */
518de9b39   Eric Dumazet   fs: allow for mor...
65
  unsigned long get_max_files(void)
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
66
  {
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
67
  	return files_stat.max_files;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
68
  }
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
69
70
71
72
73
74
  EXPORT_SYMBOL_GPL(get_max_files);
  
  /*
   * Handle nr_files sysctl
   */
  #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS)
8d65af789   Alexey Dobriyan   sysctl: remove "s...
75
  int proc_nr_files(ctl_table *table, int write,
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
76
77
78
                       void __user *buffer, size_t *lenp, loff_t *ppos)
  {
  	files_stat.nr_files = get_nr_files();
518de9b39   Eric Dumazet   fs: allow for mor...
79
  	return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
80
81
  }
  #else
8d65af789   Alexey Dobriyan   sysctl: remove "s...
82
  int proc_nr_files(ctl_table *table, int write,
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
83
84
85
86
87
                       void __user *buffer, size_t *lenp, loff_t *ppos)
  {
  	return -ENOSYS;
  }
  #endif
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
88

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
91
  /* 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   Dave Hansen   [PATCH] fix up ne...
92
93
94
95
96
97
   *
   * 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   Linus Torvalds   Linux-2.6.12-rc2
98
99
100
   */
  struct file *get_empty_filp(void)
  {
86a264abe   David Howells   CRED: Wrap curren...
101
  	const struct cred *cred = current_cred();
518de9b39   Eric Dumazet   fs: allow for mor...
102
  	static long old_max;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
107
  	struct file * f;
  
  	/*
  	 * Privileged users can go above max_files
  	 */
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
108
109
110
111
112
  	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   Peter Zijlstra   lib: percpu_count...
113
  		if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files)
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
114
115
  			goto over;
  	}
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
116

4975e45ff   Denis Cheng   fs: use kmem_cach...
117
  	f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL);
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
118
119
  	if (f == NULL)
  		goto fail;
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
120
  	percpu_counter_inc(&nr_files);
78d297887   Tetsuo Handa   CRED: Fix kernel ...
121
  	f->f_cred = get_cred(cred);
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
122
123
  	if (security_file_alloc(f))
  		goto fail_sec;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124

5a6b7951b   Benjamin LaHaise   [PATCH] get_empty...
125
  	INIT_LIST_HEAD(&f->f_u.fu_list);
516e0cc56   Al Viro   [PATCH] f_count m...
126
  	atomic_long_set(&f->f_count, 1);
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
127
  	rwlock_init(&f->f_owner.lock);
684999149   Jonathan Corbet   Rename struct fil...
128
  	spin_lock_init(&f->f_lock);
5a6b7951b   Benjamin LaHaise   [PATCH] get_empty...
129
  	eventpoll_init_file(f);
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
130
  	/* f->f_version: 0 */
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
131
132
133
  	return f;
  
  over:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
  	/* Ran out of filps - report that */
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
135
  	if (get_nr_files() > old_max) {
518de9b39   Eric Dumazet   fs: allow for mor...
136
137
  		pr_info("VFS: file-max limit %lu reached
  ", get_max_files());
529bf6be5   Dipankar Sarma   [PATCH] fix file ...
138
  		old_max = get_nr_files();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  	}
af4d2ecbf   Kirill Korotaev   [PATCH] Fix of bo...
140
141
142
143
  	goto fail;
  
  fail_sec:
  	file_free(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
  fail:
  	return NULL;
  }
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  /**
   * 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   Al Viro   switch alloc_file...
162
163
  struct file *alloc_file(struct path *path, fmode_t mode,
  		const struct file_operations *fop)
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
164
165
  {
  	struct file *file;
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
166
167
168
169
  
  	file = get_empty_filp();
  	if (!file)
  		return NULL;
2c48b9c45   Al Viro   switch alloc_file...
170
171
  	file->f_path = *path;
  	file->f_mapping = path->dentry->d_inode->i_mapping;
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
172
173
  	file->f_mode = mode;
  	file->f_op = fop;
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
174
175
176
177
178
179
180
  
  	/*
  	 * 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   Al Viro   switch alloc_file...
181
  	if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) {
ad775f5a8   Dave Hansen   [PATCH] r/o bind ...
182
  		file_take_write(file);
385e3ed4f   Roland Dreier   alloc_file(): sim...
183
  		WARN_ON(mnt_clone_write(path->mnt));
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
184
  	}
890275b5e   Mimi Zohar   IMA: maintain i_r...
185
186
  	if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
  		i_readcount_inc(path->dentry->d_inode);
3d1e46315   Al Viro   get rid of init_f...
187
  	return file;
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
188
  }
73efc4681   Roland Dreier   re-export alloc_f...
189
  EXPORT_SYMBOL(alloc_file);
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
190

aceaf78da   Dave Hansen   [PATCH] r/o bind ...
191
192
193
194
195
196
197
198
199
200
  /**
   * 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   Dave Hansen   [PATCH] r/o bind ...
201
  	struct vfsmount *mnt = file->f_path.mnt;
aceaf78da   Dave Hansen   [PATCH] r/o bind ...
202
203
204
205
  	struct dentry *dentry = file->f_path.dentry;
  	struct inode *inode = dentry->d_inode;
  
  	put_write_access(inode);
ad775f5a8   Dave Hansen   [PATCH] r/o bind ...
206
207
208
209
210
211
212
  
  	if (special_file(inode->i_mode))
  		return;
  	if (file_check_writeable(file) != 0)
  		return;
  	mnt_drop_write(mnt);
  	file_release_write(file);
aceaf78da   Dave Hansen   [PATCH] r/o bind ...
213
214
  }
  EXPORT_SYMBOL_GPL(drop_file_write_access);
d7065da03   Al Viro   get rid of the ma...
215
  /* the real guts of fput() - releasing the last reference to file
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
   */
d7065da03   Al Viro   get rid of the ma...
217
  static void __fput(struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
219
220
  	struct dentry *dentry = file->f_path.dentry;
  	struct vfsmount *mnt = file->f_path.mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
  	struct inode *inode = dentry->d_inode;
  
  	might_sleep();
0eeca2830   Robert Love   [PATCH] inotify
224
225
  
  	fsnotify_close(file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
228
229
230
231
  	/*
  	 * The function eventpoll_release() should be the first called
  	 * in the file cleanup chain.
  	 */
  	eventpoll_release(file);
  	locks_remove_flock(file);
233e70f42   Al Viro   saner FASYNC hand...
232
233
234
235
  	if (unlikely(file->f_flags & FASYNC)) {
  		if (file->f_op && file->f_op->fasync)
  			file->f_op->fasync(-1, file, 0);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
  	if (file->f_op && file->f_op->release)
  		file->f_op->release(inode, file);
  	security_file_free(file);
89068c576   Al Viro   Take ima_file_fre...
239
  	ima_file_free(file);
60ed8cf78   Miklos Szeredi   fix cdev leak on ...
240
241
  	if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL &&
  		     !(file->f_mode & FMODE_PATH))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
  		cdev_put(inode->i_cdev);
60ed8cf78   Miklos Szeredi   fix cdev leak on ...
243
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
  	fops_put(file->f_op);
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
245
  	put_pid(file->f_owner.pid);
ee2ffa0df   Nick Piggin   fs: cleanup files...
246
  	file_sb_list_del(file);
890275b5e   Mimi Zohar   IMA: maintain i_r...
247
248
  	if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
  		i_readcount_dec(inode);
aceaf78da   Dave Hansen   [PATCH] r/o bind ...
249
250
  	if (file->f_mode & FMODE_WRITE)
  		drop_file_write_access(file);
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
251
252
  	file->f_path.dentry = NULL;
  	file->f_path.mnt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
255
256
  	file_free(file);
  	dput(dentry);
  	mntput(mnt);
  }
d7065da03   Al Viro   get rid of the ma...
257
258
259
260
261
262
263
  void fput(struct file *file)
  {
  	if (atomic_long_dec_and_test(&file->f_count))
  		__fput(file);
  }
  
  EXPORT_SYMBOL(fput);
fc9b52cd8   Harvey Harrison   fs: remove fastca...
264
  struct file *fget(unsigned int fd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
  {
  	struct file *file;
  	struct files_struct *files = current->files;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
268
  	rcu_read_lock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  	file = fcheck_files(files, fd);
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
270
  	if (file) {
1abf0c718   Al Viro   New kind of open ...
271
272
273
274
  		/* File object ref couldn't be taken */
  		if (file->f_mode & FMODE_PATH ||
  		    !atomic_long_inc_not_zero(&file->f_count))
  			file = NULL;
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
275
276
  	}
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
279
280
  	return file;
  }
  
  EXPORT_SYMBOL(fget);
1abf0c718   Al Viro   New kind of open ...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
  struct file *fget_raw(unsigned int fd)
  {
  	struct file *file;
  	struct files_struct *files = current->files;
  
  	rcu_read_lock();
  	file = fcheck_files(files, fd);
  	if (file) {
  		/* File object ref couldn't be taken */
  		if (!atomic_long_inc_not_zero(&file->f_count))
  			file = NULL;
  	}
  	rcu_read_unlock();
  
  	return file;
  }
326be7b48   Al Viro   Allow passing O_P...
297
  EXPORT_SYMBOL(fget_raw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  /*
58939473b   Tony Battersby   vfs: improve comm...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
   * Lightweight file lookup - no refcnt increment if fd table isn't shared.
   *
   * You can use this instead of fget if you satisfy all of the following
   * conditions:
   * 1) You must call fput_light before exiting the syscall and returning control
   *    to userspace (i.e. you cannot remember the returned struct file * after
   *    returning to userspace).
   * 2) You must not call filp_close on the returned struct file * in between
   *    calls to fget_light and fput_light.
   * 3) You must not clone the current task in between the calls to fget_light
   *    and fput_light.
   *
   * The fput_needed flag returned by fget_light should be passed to the
   * corresponding fput_light.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
   */
fc9b52cd8   Harvey Harrison   fs: remove fastca...
314
  struct file *fget_light(unsigned int fd, int *fput_needed)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
318
319
  {
  	struct file *file;
  	struct files_struct *files = current->files;
  
  	*fput_needed = 0;
3bc0ba430   Steven Rostedt   fs: Remove unlike...
320
  	if (atomic_read(&files->count) == 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
  		file = fcheck_files(files, fd);
1abf0c718   Al Viro   New kind of open ...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  		if (file && (file->f_mode & FMODE_PATH))
  			file = NULL;
  	} else {
  		rcu_read_lock();
  		file = fcheck_files(files, fd);
  		if (file) {
  			if (!(file->f_mode & FMODE_PATH) &&
  			    atomic_long_inc_not_zero(&file->f_count))
  				*fput_needed = 1;
  			else
  				/* Didn't get the reference, someone's freed */
  				file = NULL;
  		}
  		rcu_read_unlock();
  	}
  
  	return file;
  }
  
  struct file *fget_raw_light(unsigned int fd, int *fput_needed)
  {
  	struct file *file;
  	struct files_struct *files = current->files;
  
  	*fput_needed = 0;
  	if (atomic_read(&files->count) == 1) {
  		file = fcheck_files(files, fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
  	} else {
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
350
  		rcu_read_lock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
  		file = fcheck_files(files, fd);
  		if (file) {
516e0cc56   Al Viro   [PATCH] f_count m...
353
  			if (atomic_long_inc_not_zero(&file->f_count))
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
354
355
356
357
  				*fput_needed = 1;
  			else
  				/* Didn't get the reference, someone's freed */
  				file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
  		}
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
359
  		rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  	}
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
361

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
  	return file;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
365
  void put_filp(struct file *file)
  {
516e0cc56   Al Viro   [PATCH] f_count m...
366
  	if (atomic_long_dec_and_test(&file->f_count)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
  		security_file_free(file);
ee2ffa0df   Nick Piggin   fs: cleanup files...
368
  		file_sb_list_del(file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
371
  		file_free(file);
  	}
  }
6416ccb78   Nick Piggin   fs: scale files_lock
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  static inline int file_list_cpu(struct file *file)
  {
  #ifdef CONFIG_SMP
  	return file->f_sb_list_cpu;
  #else
  	return smp_processor_id();
  #endif
  }
  
  /* helper for file_sb_list_add to reduce ifdefs */
  static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
  {
  	struct list_head *list;
  #ifdef CONFIG_SMP
  	int cpu;
  	cpu = smp_processor_id();
  	file->f_sb_list_cpu = cpu;
  	list = per_cpu_ptr(sb->s_files, cpu);
  #else
  	list = &sb->s_files;
  #endif
  	list_add(&file->f_u.fu_list, list);
  }
  
  /**
   * file_sb_list_add - add a file to the sb's file list
   * @file: file to add
   * @sb: sb to add it to
   *
   * Use this function to associate a file with the superblock of the inode it
   * refers to.
   */
ee2ffa0df   Nick Piggin   fs: cleanup files...
404
  void file_sb_list_add(struct file *file, struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  {
6416ccb78   Nick Piggin   fs: scale files_lock
406
407
408
  	lg_local_lock(files_lglock);
  	__file_sb_list_add(file, sb);
  	lg_local_unlock(files_lglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  }
6416ccb78   Nick Piggin   fs: scale files_lock
410
411
412
413
414
415
416
  /**
   * file_sb_list_del - remove a file from the sb's file list
   * @file: file to remove
   * @sb: sb to remove it from
   *
   * Use this function to remove a file from its superblock.
   */
ee2ffa0df   Nick Piggin   fs: cleanup files...
417
  void file_sb_list_del(struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
  {
2f5120166   Eric Dumazet   [PATCH] reduce si...
419
  	if (!list_empty(&file->f_u.fu_list)) {
6416ccb78   Nick Piggin   fs: scale files_lock
420
  		lg_local_lock_cpu(files_lglock, file_list_cpu(file));
2f5120166   Eric Dumazet   [PATCH] reduce si...
421
  		list_del_init(&file->f_u.fu_list);
6416ccb78   Nick Piggin   fs: scale files_lock
422
  		lg_local_unlock_cpu(files_lglock, file_list_cpu(file));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
  	}
  }
6416ccb78   Nick Piggin   fs: scale files_lock
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  #ifdef CONFIG_SMP
  
  /*
   * These macros iterate all files on all CPUs for a given superblock.
   * files_lglock must be held globally.
   */
  #define do_file_list_for_each_entry(__sb, __file)		\
  {								\
  	int i;							\
  	for_each_possible_cpu(i) {				\
  		struct list_head *list;				\
  		list = per_cpu_ptr((__sb)->s_files, i);		\
  		list_for_each_entry((__file), list, f_u.fu_list)
  
  #define while_file_list_for_each_entry				\
  	}							\
  }
  
  #else
  
  #define do_file_list_for_each_entry(__sb, __file)		\
  {								\
  	struct list_head *list;					\
  	list = &(sb)->s_files;					\
  	list_for_each_entry((__file), list, f_u.fu_list)
  
  #define while_file_list_for_each_entry				\
  }
  
  #endif
864d7c4c0   npiggin@suse.de   fs: move mark_fil...
455
456
457
458
459
460
461
462
463
464
465
466
  /**
   *	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:
6416ccb78   Nick Piggin   fs: scale files_lock
467
468
  	lg_global_lock(files_lglock);
  	do_file_list_for_each_entry(sb, f) {
864d7c4c0   npiggin@suse.de   fs: move mark_fil...
469
470
471
472
473
474
475
  		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   Wu Fengguang   vfs: take f_lock ...
476
  		spin_lock(&f->f_lock);
864d7c4c0   npiggin@suse.de   fs: move mark_fil...
477
  		f->f_mode &= ~FMODE_WRITE;
42e496086   Wu Fengguang   vfs: take f_lock ...
478
  		spin_unlock(&f->f_lock);
864d7c4c0   npiggin@suse.de   fs: move mark_fil...
479
480
481
482
  		if (file_check_writeable(f) != 0)
  			continue;
  		file_release_write(f);
  		mnt = mntget(f->f_path.mnt);
ee2ffa0df   Nick Piggin   fs: cleanup files...
483
  		/* This can sleep, so we can't hold the spinlock. */
6416ccb78   Nick Piggin   fs: scale files_lock
484
  		lg_global_unlock(files_lglock);
864d7c4c0   npiggin@suse.de   fs: move mark_fil...
485
486
487
  		mnt_drop_write(mnt);
  		mntput(mnt);
  		goto retry;
6416ccb78   Nick Piggin   fs: scale files_lock
488
489
  	} while_file_list_for_each_entry;
  	lg_global_unlock(files_lglock);
864d7c4c0   npiggin@suse.de   fs: move mark_fil...
490
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
  void __init files_init(unsigned long mempages)
  { 
518de9b39   Eric Dumazet   fs: allow for mor...
493
  	unsigned long n;
b6b3fdead   Eric Dumazet   filp_cachep can b...
494
495
496
497
498
499
  
  	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   Linus Torvalds   Linux-2.6.12-rc2
500
501
502
503
  	 * Per default don't use more than 10% of our memory for files. 
  	 */ 
  
  	n = (mempages * (PAGE_SIZE / 1024)) / 10;
518de9b39   Eric Dumazet   fs: allow for mor...
504
  	files_stat.max_files = max_t(unsigned long, n, NR_FILE);
ab2af1f50   Dipankar Sarma   [PATCH] files: fi...
505
  	files_defer_init();
6416ccb78   Nick Piggin   fs: scale files_lock
506
  	lg_lock_init(files_lglock);
0216bfcff   Mingming Cao   [PATCH] percpu co...
507
  	percpu_counter_init(&nr_files, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
  }