Blame view

fs/super.c 24.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   *  linux/fs/super.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   *
   *  super.c contains code to handle: - mount structures
   *                                   - super-block tables
   *                                   - filesystem drivers list
   *                                   - mount system call
   *                                   - umount system call
   *                                   - ustat system call
   *
   * GK 2/5/95  -  Changed to support mounting the root fs via NFS
   *
   *  Added kerneld support: Jacques Gelinas and Bjorn Ekwall
   *  Added change_root: Werner Almesberger & Hans Lermen, Feb '96
   *  Added options to /proc/mounts:
96de0e252   Jan Engelhardt   Convert files to ...
18
   *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
   *  Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
   *  Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
  #include <linux/module.h>
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
  #include <linux/acct.h>
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  #include <linux/mount.h>
  #include <linux/security.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
  #include <linux/writeback.h>		/* for the emergency remount stuff */
  #include <linux/idr.h>
353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
30
  #include <linux/mutex.h>
5477d0fac   Jens Axboe   fs: fs/super.c ne...
31
  #include <linux/backing-dev.h>
ceb5bdc2d   Nick Piggin   fs: dcache per-bu...
32
  #include <linux/rculist_bl.h>
6d59e7f58   Al Viro   [PATCH] move a bu...
33
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
39
  LIST_HEAD(super_blocks);
  DEFINE_SPINLOCK(sb_lock);
  
  /**
   *	alloc_super	-	create new superblock
fe2bbc483   Henrik Kretzschmar   [PATCH] add missi...
40
   *	@type:	filesystem type superblock should belong to
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
   *
   *	Allocates and initializes a new &struct super_block.  alloc_super()
   *	returns a pointer new superblock or %NULL if allocation had failed.
   */
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
45
  static struct super_block *alloc_super(struct file_system_type *type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  {
11b0b5abb   Oliver Neukum   [PATCH] use kzall...
47
  	struct super_block *s = kzalloc(sizeof(struct super_block),  GFP_USER);
b87221de6   Alexey Dobriyan   const: mark remai...
48
  	static const struct super_operations default_op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
  
  	if (s) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
54
55
  		if (security_sb_alloc(s)) {
  			kfree(s);
  			s = NULL;
  			goto out;
  		}
6416ccb78   Nick Piggin   fs: scale files_lock
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  #ifdef CONFIG_SMP
  		s->s_files = alloc_percpu(struct list_head);
  		if (!s->s_files) {
  			security_sb_free(s);
  			kfree(s);
  			s = NULL;
  			goto out;
  		} else {
  			int i;
  
  			for_each_possible_cpu(i)
  				INIT_LIST_HEAD(per_cpu_ptr(s->s_files, i));
  		}
  #else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  		INIT_LIST_HEAD(&s->s_files);
6416ccb78   Nick Piggin   fs: scale files_lock
71
  #endif
95f28604a   Jens Axboe   fs: assign sb->s_...
72
  		s->s_bdi = &default_backing_dev_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  		INIT_LIST_HEAD(&s->s_instances);
ceb5bdc2d   Nick Piggin   fs: dcache per-bu...
74
  		INIT_HLIST_BL_HEAD(&s->s_anon);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  		INIT_LIST_HEAD(&s->s_inodes);
da3bbdd46   Kentaro Makita   fix soft lock up ...
76
  		INIT_LIST_HEAD(&s->s_dentry_lru);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  		init_rwsem(&s->s_umount);
7892f2f48   Ingo Molnar   [PATCH] mutex sub...
78
  		mutex_init(&s->s_lock);
897c6ff95   Arjan van de Ven   [PATCH] lockdep: ...
79
  		lockdep_set_class(&s->s_umount, &type->s_umount_key);
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
80
81
82
83
84
85
  		/*
  		 * The locking rules for s_lock are up to the
  		 * filesystem. For example ext3fs has different
  		 * lock ordering than usbfs:
  		 */
  		lockdep_set_class(&s->s_lock, &type->s_lock_key);
ada723dcd   Peter Zijlstra   fs/super.c: add l...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  		/*
  		 * sget() can have s_umount recursion.
  		 *
  		 * When it cannot find a suitable sb, it allocates a new
  		 * one (this one), and tries again to find a suitable old
  		 * one.
  		 *
  		 * In case that succeeds, it will acquire the s_umount
  		 * lock of the old one. Since these are clearly distrinct
  		 * locks, and this object isn't exposed yet, there's no
  		 * risk of deadlocks.
  		 *
  		 * Annotate this by putting this lock in a different
  		 * subclass.
  		 */
  		down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING);
b20bd1a5e   Al Viro   get rid of S_BIAS
102
  		s->s_count = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  		atomic_set(&s->s_active, 1);
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
104
  		mutex_init(&s->s_vfs_rename_mutex);
51ee049e7   Roland Dreier   vfs: add lockdep ...
105
  		lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
106
107
  		mutex_init(&s->s_dquot.dqio_mutex);
  		mutex_init(&s->s_dquot.dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
  		init_rwsem(&s->s_dquot.dqptr_sem);
  		init_waitqueue_head(&s->s_wait_unfrozen);
  		s->s_maxbytes = MAX_NON_LFS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  		s->s_op = &default_op;
  		s->s_time_gran = 1000000000;
  	}
  out:
  	return s;
  }
  
  /**
   *	destroy_super	-	frees a superblock
   *	@s: superblock to free
   *
   *	Frees a superblock.
   */
  static inline void destroy_super(struct super_block *s)
  {
6416ccb78   Nick Piggin   fs: scale files_lock
126
127
128
  #ifdef CONFIG_SMP
  	free_percpu(s->s_files);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  	security_sb_free(s);
79c0b2df7   Miklos Szeredi   add filesystem su...
130
  	kfree(s->s_subtype);
b3b304a23   Miklos Szeredi   mount options: ad...
131
  	kfree(s->s_options);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
135
136
137
  	kfree(s);
  }
  
  /* Superblock refcounting  */
  
  /*
35cf7ba0b   Al Viro   Bury __put_super_...
138
   * Drop a superblock's refcount.  The caller must hold sb_lock.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
   */
35cf7ba0b   Al Viro   Bury __put_super_...
140
  void __put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  	if (!--sb->s_count) {
551de6f34   Al Viro   Leave superblocks...
143
  		list_del_init(&sb->s_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  		destroy_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
148
149
150
151
152
153
154
  }
  
  /**
   *	put_super	-	drop a temporary reference to superblock
   *	@sb: superblock in question
   *
   *	Drops a temporary reference, frees superblock if there's no
   *	references left.
   */
03ba3782e   Jens Axboe   writeback: switch...
155
  void put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
161
162
163
  {
  	spin_lock(&sb_lock);
  	__put_super(sb);
  	spin_unlock(&sb_lock);
  }
  
  
  /**
1712ac8fd   Al Viro   Saner locking aro...
164
   *	deactivate_locked_super	-	drop an active reference to superblock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
   *	@s: superblock to deactivate
   *
1712ac8fd   Al Viro   Saner locking aro...
167
168
   *	Drops an active reference to superblock, converting it into a temprory
   *	one if there is no other active references left.  In that case we
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
170
   *	tell fs driver to shut it down and drop the temporary reference we
   *	had just acquired.
1712ac8fd   Al Viro   Saner locking aro...
171
172
   *
   *	Caller holds exclusive lock on superblock; that lock is released.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
   */
1712ac8fd   Al Viro   Saner locking aro...
174
  void deactivate_locked_super(struct super_block *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
  {
  	struct file_system_type *fs = s->s_type;
b20bd1a5e   Al Viro   get rid of S_BIAS
177
  	if (atomic_dec_and_test(&s->s_active)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
  		fs->kill_sb(s);
d863b50ab   Boaz Harrosh   vfs: call rcu_bar...
179
180
181
182
183
  		/*
  		 * We need to call rcu_barrier so all the delayed rcu free
  		 * inodes are flushed before we release the fs module.
  		 */
  		rcu_barrier();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
  		put_filesystem(fs);
  		put_super(s);
1712ac8fd   Al Viro   Saner locking aro...
186
187
  	} else {
  		up_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
  	}
  }
1712ac8fd   Al Viro   Saner locking aro...
190
  EXPORT_SYMBOL(deactivate_locked_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
  
  /**
1712ac8fd   Al Viro   Saner locking aro...
193
   *	deactivate_super	-	drop an active reference to superblock
74dbbdd7f   Al Viro   New helper: deact...
194
195
   *	@s: superblock to deactivate
   *
1712ac8fd   Al Viro   Saner locking aro...
196
197
198
   *	Variant of deactivate_locked_super(), except that superblock is *not*
   *	locked by caller.  If we are going to drop the final active reference,
   *	lock will be acquired prior to that.
74dbbdd7f   Al Viro   New helper: deact...
199
   */
1712ac8fd   Al Viro   Saner locking aro...
200
  void deactivate_super(struct super_block *s)
74dbbdd7f   Al Viro   New helper: deact...
201
  {
1712ac8fd   Al Viro   Saner locking aro...
202
203
204
          if (!atomic_add_unless(&s->s_active, -1, 1)) {
  		down_write(&s->s_umount);
  		deactivate_locked_super(s);
74dbbdd7f   Al Viro   New helper: deact...
205
206
  	}
  }
1712ac8fd   Al Viro   Saner locking aro...
207
  EXPORT_SYMBOL(deactivate_super);
74dbbdd7f   Al Viro   New helper: deact...
208
209
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
214
215
216
217
218
219
   *	grab_super - acquire an active reference
   *	@s: reference we are trying to make active
   *
   *	Tries to acquire an active reference.  grab_super() is used when we
   * 	had just found a superblock in super_blocks or fs_type->fs_supers
   *	and want to turn it into a full-blown active reference.  grab_super()
   *	is called with sb_lock held and drops it.  Returns 1 in case of
   *	success, 0 if we had failed (superblock contents was already dead or
   *	dying when grab_super() had been called).
   */
9c4dbee79   Josh Triplett   [PATCH] fs: add l...
220
  static int grab_super(struct super_block *s) __releases(sb_lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
  {
b20bd1a5e   Al Viro   get rid of S_BIAS
222
223
  	if (atomic_inc_not_zero(&s->s_active)) {
  		spin_unlock(&sb_lock);
b20bd1a5e   Al Viro   get rid of S_BIAS
224
225
226
  		return 1;
  	}
  	/* it's going away */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
228
  	s->s_count++;
  	spin_unlock(&sb_lock);
1712ac8fd   Al Viro   Saner locking aro...
229
  	/* wait for it to die */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
  	down_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
232
  	up_write(&s->s_umount);
  	put_super(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
  	return 0;
  }
cf9a2ae8d   David Howells   [PATCH] BLOCK: Mo...
235
  /*
914e26379   Al Viro   [PATCH] severing ...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
   * Superblock locking.  We really ought to get rid of these two.
   */
  void lock_super(struct super_block * sb)
  {
  	get_fs_excl();
  	mutex_lock(&sb->s_lock);
  }
  
  void unlock_super(struct super_block * sb)
  {
  	put_fs_excl();
  	mutex_unlock(&sb->s_lock);
  }
  
  EXPORT_SYMBOL(lock_super);
  EXPORT_SYMBOL(unlock_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
257
258
259
260
  /**
   *	generic_shutdown_super	-	common helper for ->kill_sb()
   *	@sb: superblock to kill
   *
   *	generic_shutdown_super() does all fs-independent work on superblock
   *	shutdown.  Typical ->kill_sb() should pick all fs-specific objects
   *	that need destruction out of superblock, call generic_shutdown_super()
   *	and release aforementioned objects.  Note: dentries and inodes _are_
   *	taken care of and do not need specific handling.
c636ebdb1   David Howells   [PATCH] VFS: Dest...
261
262
263
264
   *
   *	Upon calling this function, the filesystem may no longer alter or
   *	rearrange the set of dentries belonging to this super_block, nor may it
   *	change the attachments of dentries to inodes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
   */
  void generic_shutdown_super(struct super_block *sb)
  {
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
268
  	const struct super_operations *sop = sb->s_op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269

efaee1920   Arjan van de Ven   async: make the f...
270

c636ebdb1   David Howells   [PATCH] VFS: Dest...
271
272
  	if (sb->s_root) {
  		shrink_dcache_for_umount(sb);
60b0680fa   Jan Kara   vfs: Rename fsync...
273
  		sync_filesystem(sb);
a9e220f83   Al Viro   No need to do loc...
274
  		get_fs_excl();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  		sb->s_flags &= ~MS_ACTIVE;
efaee1920   Arjan van de Ven   async: make the f...
276

63997e98a   Al Viro   split invalidate_...
277
278
279
  		fsnotify_unmount_inodes(&sb->s_inodes);
  
  		evict_inodes(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
282
  		if (sop->put_super)
  			sop->put_super(sb);
63997e98a   Al Viro   split invalidate_...
283
  		if (!list_empty(&sb->s_inodes)) {
7b4fe29e0   Dave Jones   [PATCH] More info...
284
285
286
287
  			printk("VFS: Busy inodes after unmount of %s. "
  			   "Self-destruct in 5 seconds.  Have a nice day...
  ",
  			   sb->s_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  		}
a9e220f83   Al Viro   No need to do loc...
289
  		put_fs_excl();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
  	}
  	spin_lock(&sb_lock);
  	/* should be initialized for __put_super_and_need_restart() */
551de6f34   Al Viro   Leave superblocks...
293
  	list_del_init(&sb->s_instances);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  	spin_unlock(&sb_lock);
  	up_write(&sb->s_umount);
  }
  
  EXPORT_SYMBOL(generic_shutdown_super);
  
  /**
   *	sget	-	find or create a superblock
   *	@type:	filesystem type superblock should belong to
   *	@test:	comparison callback
   *	@set:	setup callback
   *	@data:	argument to each of them
   */
  struct super_block *sget(struct file_system_type *type,
  			int (*test)(struct super_block *,void *),
  			int (*set)(struct super_block *,void *),
  			void *data)
  {
  	struct super_block *s = NULL;
d47301271   Matthias Kaehlcke   fs/super.c: use l...
313
  	struct super_block *old;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
316
317
  	int err;
  
  retry:
  	spin_lock(&sb_lock);
d47301271   Matthias Kaehlcke   fs/super.c: use l...
318
319
320
321
322
323
  	if (test) {
  		list_for_each_entry(old, &type->fs_supers, s_instances) {
  			if (!test(old, data))
  				continue;
  			if (!grab_super(old))
  				goto retry;
a3cfbb53b   Li Zefan   vfs: add missing ...
324
325
  			if (s) {
  				up_write(&s->s_umount);
d47301271   Matthias Kaehlcke   fs/super.c: use l...
326
  				destroy_super(s);
7a4dec538   Al Viro   Fix sget() race w...
327
  				s = NULL;
a3cfbb53b   Li Zefan   vfs: add missing ...
328
  			}
d3f214730   Al Viro   Move grabbing s_u...
329
  			down_write(&old->s_umount);
7a4dec538   Al Viro   Fix sget() race w...
330
331
332
333
  			if (unlikely(!(old->s_flags & MS_BORN))) {
  				deactivate_locked_super(old);
  				goto retry;
  			}
d47301271   Matthias Kaehlcke   fs/super.c: use l...
334
335
  			return old;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
338
  	}
  	if (!s) {
  		spin_unlock(&sb_lock);
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
339
  		s = alloc_super(type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
342
343
344
345
346
347
  		if (!s)
  			return ERR_PTR(-ENOMEM);
  		goto retry;
  	}
  		
  	err = set(s, data);
  	if (err) {
  		spin_unlock(&sb_lock);
a3cfbb53b   Li Zefan   vfs: add missing ...
348
  		up_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  		destroy_super(s);
  		return ERR_PTR(err);
  	}
  	s->s_type = type;
  	strlcpy(s->s_id, type->name, sizeof(s->s_id));
  	list_add_tail(&s->s_list, &super_blocks);
  	list_add(&s->s_instances, &type->fs_supers);
  	spin_unlock(&sb_lock);
  	get_filesystem(type);
  	return s;
  }
  
  EXPORT_SYMBOL(sget);
  
  void drop_super(struct super_block *sb)
  {
  	up_read(&sb->s_umount);
  	put_super(sb);
  }
  
  EXPORT_SYMBOL(drop_super);
e50047533   Christoph Hellwig   cleanup sync_supers
370
371
372
373
374
375
376
377
  /**
   * sync_supers - helper for periodic superblock writeback
   *
   * Call the write_super method if present on all dirty superblocks in
   * the system.  This is for the periodic writeback used by most older
   * filesystems.  For data integrity superblock writeback use
   * sync_filesystems() instead.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
382
383
   * Note: check the dirty flag before waiting, so we don't
   * hold up the sync while mounting a device. (The newly
   * mounted device won't need syncing.)
   */
  void sync_supers(void)
  {
dca332528   Al Viro   no need for list_...
384
  	struct super_block *sb, *p = NULL;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
385

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
387
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
388
389
  		if (list_empty(&sb->s_instances))
  			continue;
e50047533   Christoph Hellwig   cleanup sync_supers
390
  		if (sb->s_op->write_super && sb->s_dirt) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
  			sb->s_count++;
  			spin_unlock(&sb_lock);
e50047533   Christoph Hellwig   cleanup sync_supers
393

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
  			down_read(&sb->s_umount);
e50047533   Christoph Hellwig   cleanup sync_supers
395
396
  			if (sb->s_root && sb->s_dirt)
  				sb->s_op->write_super(sb);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
397
  			up_read(&sb->s_umount);
e50047533   Christoph Hellwig   cleanup sync_supers
398

618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
399
  			spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
400
401
402
  			if (p)
  				__put_super(p);
  			p = sb;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
403
404
  		}
  	}
dca332528   Al Viro   no need for list_...
405
406
  	if (p)
  		__put_super(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
  	spin_unlock(&sb_lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  /**
01a05b337   Al Viro   new helper: itera...
410
411
412
413
414
415
416
417
418
   *	iterate_supers - call function for all active superblocks
   *	@f: function to call
   *	@arg: argument to pass to it
   *
   *	Scans the superblock list and calls given function, passing it
   *	locked superblock and given argument.
   */
  void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
  {
dca332528   Al Viro   no need for list_...
419
  	struct super_block *sb, *p = NULL;
01a05b337   Al Viro   new helper: itera...
420
421
  
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
422
  	list_for_each_entry(sb, &super_blocks, s_list) {
01a05b337   Al Viro   new helper: itera...
423
424
425
426
427
428
429
430
431
432
433
  		if (list_empty(&sb->s_instances))
  			continue;
  		sb->s_count++;
  		spin_unlock(&sb_lock);
  
  		down_read(&sb->s_umount);
  		if (sb->s_root)
  			f(sb, arg);
  		up_read(&sb->s_umount);
  
  		spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
434
435
436
  		if (p)
  			__put_super(p);
  		p = sb;
01a05b337   Al Viro   new helper: itera...
437
  	}
dca332528   Al Viro   no need for list_...
438
439
  	if (p)
  		__put_super(p);
01a05b337   Al Viro   new helper: itera...
440
441
442
443
  	spin_unlock(&sb_lock);
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
446
447
448
449
   *	get_super - get the superblock of a device
   *	@bdev: device to get the superblock for
   *	
   *	Scans the superblock list and finds the superblock of the file system
   *	mounted on the device given. %NULL is returned if no match is found.
   */
df40c01a9   Al Viro   In get_super() an...
450
  struct super_block *get_super(struct block_device *bdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
  {
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
452
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
  	if (!bdev)
  		return NULL;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
455

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  	spin_lock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
457
458
  rescan:
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
459
460
  		if (list_empty(&sb->s_instances))
  			continue;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
461
462
  		if (sb->s_bdev == bdev) {
  			sb->s_count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  			spin_unlock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
464
  			down_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
465
  			/* still alive? */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
466
467
468
  			if (sb->s_root)
  				return sb;
  			up_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
469
  			/* nope, got unmounted */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
470
  			spin_lock(&sb_lock);
df40c01a9   Al Viro   In get_super() an...
471
472
  			__put_super(sb);
  			goto rescan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
474
475
476
477
478
479
  		}
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
  
  EXPORT_SYMBOL(get_super);
4504230a7   Christoph Hellwig   freeze_bdev: grab...
480
481
482
483
484
485
486
  
  /**
   * get_active_super - get an active reference to the superblock of a device
   * @bdev: device to get the superblock for
   *
   * Scans the superblock list and finds the superblock of the file system
   * mounted on the device given.  Returns the superblock with an active
d3f214730   Al Viro   Move grabbing s_u...
487
   * reference or %NULL if none was found.
4504230a7   Christoph Hellwig   freeze_bdev: grab...
488
489
490
491
492
493
494
   */
  struct super_block *get_active_super(struct block_device *bdev)
  {
  	struct super_block *sb;
  
  	if (!bdev)
  		return NULL;
1494583de   Al Viro   fix get_active_su...
495
  restart:
4504230a7   Christoph Hellwig   freeze_bdev: grab...
496
497
  	spin_lock(&sb_lock);
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
498
499
  		if (list_empty(&sb->s_instances))
  			continue;
1494583de   Al Viro   fix get_active_su...
500
501
502
503
504
505
  		if (sb->s_bdev == bdev) {
  			if (grab_super(sb)) /* drops sb_lock */
  				return sb;
  			else
  				goto restart;
  		}
4504230a7   Christoph Hellwig   freeze_bdev: grab...
506
507
508
509
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
   
df40c01a9   Al Viro   In get_super() an...
511
  struct super_block *user_get_super(dev_t dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  {
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
513
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515
  	spin_lock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
516
517
  rescan:
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
518
519
  		if (list_empty(&sb->s_instances))
  			continue;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
520
521
  		if (sb->s_dev ==  dev) {
  			sb->s_count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
  			spin_unlock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
523
  			down_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
524
  			/* still alive? */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
525
526
527
  			if (sb->s_root)
  				return sb;
  			up_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
528
  			/* nope, got unmounted */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
529
  			spin_lock(&sb_lock);
df40c01a9   Al Viro   In get_super() an...
530
531
  			__put_super(sb);
  			goto rescan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
  		}
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
539
540
541
542
543
544
545
546
547
548
   *	do_remount_sb - asks filesystem to change mount options.
   *	@sb:	superblock in question
   *	@flags:	numeric part of options
   *	@data:	the rest of options
   *      @force: whether or not to force the change
   *
   *	Alters the mount options of a mounted file system.
   */
  int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
  {
  	int retval;
c79d967de   Christoph Hellwig   quota: move remou...
549
  	int remount_ro;
4504230a7   Christoph Hellwig   freeze_bdev: grab...
550
551
552
  
  	if (sb->s_frozen != SB_UNFROZEN)
  		return -EBUSY;
9361401eb   David Howells   [PATCH] BLOCK: Ma...
553
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
555
  	if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
  		return -EACCES;
9361401eb   David Howells   [PATCH] BLOCK: Ma...
556
  #endif
4504230a7   Christoph Hellwig   freeze_bdev: grab...
557

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
  	if (flags & MS_RDONLY)
  		acct_auto_close(sb);
  	shrink_dcache_sb(sb);
60b0680fa   Jan Kara   vfs: Rename fsync...
561
  	sync_filesystem(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562

d208bbdda   Nick Piggin   fs: improve remou...
563
  	remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
d208bbdda   Nick Piggin   fs: improve remou...
564

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
  	/* If we are remounting RDONLY and current sb is read/write,
  	   make sure there are no rw files opened */
d208bbdda   Nick Piggin   fs: improve remou...
567
  	if (remount_ro) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
  		if (force)
  			mark_files_ro(sb);
b0895513f   J. R. Okajima   remove unlock_ker...
570
  		else if (!fs_may_remount_ro(sb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
574
  			return -EBUSY;
  	}
  
  	if (sb->s_op->remount_fs) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  		retval = sb->s_op->remount_fs(sb, &flags, data);
b0895513f   J. R. Okajima   remove unlock_ker...
576
  		if (retval)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
  			return retval;
  	}
  	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
c79d967de   Christoph Hellwig   quota: move remou...
580

d208bbdda   Nick Piggin   fs: improve remou...
581
582
583
584
585
586
587
588
589
590
  	/*
  	 * Some filesystems modify their metadata via some other path than the
  	 * bdev buffer cache (eg. use a private mapping, or directories in
  	 * pagecache, etc). Also file data modifications go via their own
  	 * mappings. So If we try to mount readonly then copy the filesystem
  	 * from bdev, we could get stale data, so invalidate it to give a best
  	 * effort at coherency.
  	 */
  	if (remount_ro && sb->s_bdev)
  		invalidate_bdev(sb->s_bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
  	return 0;
  }
a2a9537ac   Jens Axboe   Get rid of pdflus...
593
  static void do_emergency_remount(struct work_struct *work)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
  {
dca332528   Al Viro   no need for list_...
595
  	struct super_block *sb, *p = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
  
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
598
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
599
600
  		if (list_empty(&sb->s_instances))
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
  		sb->s_count++;
  		spin_unlock(&sb_lock);
443b94baa   Al Viro   Make sure that al...
603
  		down_write(&sb->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
605
  		if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) {
  			/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
607
  			 * What lock protects sb->s_flags??
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
  			do_remount_sb(sb, MS_RDONLY, NULL, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  		}
443b94baa   Al Viro   Make sure that al...
610
  		up_write(&sb->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  		spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
612
613
614
  		if (p)
  			__put_super(p);
  		p = sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
  	}
dca332528   Al Viro   no need for list_...
616
617
  	if (p)
  		__put_super(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
  	spin_unlock(&sb_lock);
a2a9537ac   Jens Axboe   Get rid of pdflus...
619
  	kfree(work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620
621
622
623
624
625
  	printk("Emergency Remount complete
  ");
  }
  
  void emergency_remount(void)
  {
a2a9537ac   Jens Axboe   Get rid of pdflus...
626
627
628
629
630
631
632
  	struct work_struct *work;
  
  	work = kmalloc(sizeof(*work), GFP_ATOMIC);
  	if (work) {
  		INIT_WORK(work, do_emergency_remount);
  		schedule_work(work);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
636
637
638
  }
  
  /*
   * Unnamed block devices are dummy devices used by virtual
   * filesystems which don't use real block-devices.  -- jrs
   */
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
639
  static DEFINE_IDA(unnamed_dev_ida);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
  static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
c63e09ecc   Al Viro   Make allocation o...
641
  static int unnamed_dev_start = 0; /* don't bother trying below it */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
643
644
645
646
647
648
  
  int set_anon_super(struct super_block *s, void *data)
  {
  	int dev;
  	int error;
  
   retry:
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
649
  	if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
  		return -ENOMEM;
  	spin_lock(&unnamed_dev_lock);
c63e09ecc   Al Viro   Make allocation o...
652
  	error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev);
f21f62208   Al Viro   ... and the same ...
653
654
  	if (!error)
  		unnamed_dev_start = dev + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
656
657
658
659
660
661
662
663
  	spin_unlock(&unnamed_dev_lock);
  	if (error == -EAGAIN)
  		/* We raced and lost with another CPU. */
  		goto retry;
  	else if (error)
  		return -EAGAIN;
  
  	if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) {
  		spin_lock(&unnamed_dev_lock);
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
664
  		ida_remove(&unnamed_dev_ida, dev);
f21f62208   Al Viro   ... and the same ...
665
666
  		if (unnamed_dev_start > dev)
  			unnamed_dev_start = dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
669
670
  		spin_unlock(&unnamed_dev_lock);
  		return -EMFILE;
  	}
  	s->s_dev = MKDEV(0, dev & MINORMASK);
5129a469a   Jörn Engel   Catch filesystems...
671
  	s->s_bdi = &noop_backing_dev_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
674
675
676
677
678
679
680
681
682
  	return 0;
  }
  
  EXPORT_SYMBOL(set_anon_super);
  
  void kill_anon_super(struct super_block *sb)
  {
  	int slot = MINOR(sb->s_dev);
  
  	generic_shutdown_super(sb);
  	spin_lock(&unnamed_dev_lock);
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
683
  	ida_remove(&unnamed_dev_ida, slot);
c63e09ecc   Al Viro   Make allocation o...
684
685
  	if (slot < unnamed_dev_start)
  		unnamed_dev_start = slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
688
689
  	spin_unlock(&unnamed_dev_lock);
  }
  
  EXPORT_SYMBOL(kill_anon_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
691
692
693
694
695
696
697
  void kill_litter_super(struct super_block *sb)
  {
  	if (sb->s_root)
  		d_genocide(sb->s_root);
  	kill_anon_super(sb);
  }
  
  EXPORT_SYMBOL(kill_litter_super);
909e6d947   Serge E. Hallyn   namespaces: move ...
698
699
700
701
702
703
704
705
706
707
  static int ns_test_super(struct super_block *sb, void *data)
  {
  	return sb->s_fs_info == data;
  }
  
  static int ns_set_super(struct super_block *sb, void *data)
  {
  	sb->s_fs_info = data;
  	return set_anon_super(sb, NULL);
  }
ceefda693   Al Viro   switch get_sb_ns(...
708
709
  struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
  	void *data, int (*fill_super)(struct super_block *, void *, int))
909e6d947   Serge E. Hallyn   namespaces: move ...
710
711
712
713
714
  {
  	struct super_block *sb;
  
  	sb = sget(fs_type, ns_test_super, ns_set_super, data);
  	if (IS_ERR(sb))
ceefda693   Al Viro   switch get_sb_ns(...
715
  		return ERR_CAST(sb);
909e6d947   Serge E. Hallyn   namespaces: move ...
716
717
718
719
720
721
  
  	if (!sb->s_root) {
  		int err;
  		sb->s_flags = flags;
  		err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
  		if (err) {
74dbbdd7f   Al Viro   New helper: deact...
722
  			deactivate_locked_super(sb);
ceefda693   Al Viro   switch get_sb_ns(...
723
  			return ERR_PTR(err);
909e6d947   Serge E. Hallyn   namespaces: move ...
724
725
726
727
  		}
  
  		sb->s_flags |= MS_ACTIVE;
  	}
ceefda693   Al Viro   switch get_sb_ns(...
728
  	return dget(sb->s_root);
909e6d947   Serge E. Hallyn   namespaces: move ...
729
  }
ceefda693   Al Viro   switch get_sb_ns(...
730
  EXPORT_SYMBOL(mount_ns);
909e6d947   Serge E. Hallyn   namespaces: move ...
731

9361401eb   David Howells   [PATCH] BLOCK: Ma...
732
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
734
735
736
  static int set_bdev_super(struct super_block *s, void *data)
  {
  	s->s_bdev = data;
  	s->s_dev = s->s_bdev->bd_dev;
32a88aa1b   Jens Axboe   fs: Assign bdi in...
737
738
739
740
741
742
  
  	/*
  	 * We set the bdi here to the queue backing, file systems can
  	 * overwrite this in ->fill_super()
  	 */
  	s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743
744
745
746
747
748
749
  	return 0;
  }
  
  static int test_bdev_super(struct super_block *s, void *data)
  {
  	return (void *)s->s_bdev == data;
  }
152a08366   Al Viro   new helper: mount...
750
  struct dentry *mount_bdev(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
751
  	int flags, const char *dev_name, void *data,
152a08366   Al Viro   new helper: mount...
752
  	int (*fill_super)(struct super_block *, void *, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
753
754
755
  {
  	struct block_device *bdev;
  	struct super_block *s;
d4d776299   Tejun Heo   block: clean up b...
756
  	fmode_t mode = FMODE_READ | FMODE_EXCL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
  	int error = 0;
30c40d2c0   Al Viro   [PATCH] propagate...
758
759
  	if (!(flags & MS_RDONLY))
  		mode |= FMODE_WRITE;
d4d776299   Tejun Heo   block: clean up b...
760
  	bdev = blkdev_get_by_path(dev_name, mode, fs_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
  	if (IS_ERR(bdev))
152a08366   Al Viro   new helper: mount...
762
  		return ERR_CAST(bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
763
764
765
766
767
768
  
  	/*
  	 * once the super is inserted into the list by sget, s_umount
  	 * will protect the lockfs code from trying to start a snapshot
  	 * while we are mounting
  	 */
4fadd7bb2   Christoph Hellwig   freeze_bdev: kill...
769
770
771
772
773
774
  	mutex_lock(&bdev->bd_fsfreeze_mutex);
  	if (bdev->bd_fsfreeze_count > 0) {
  		mutex_unlock(&bdev->bd_fsfreeze_mutex);
  		error = -EBUSY;
  		goto error_bdev;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
  	s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
4fadd7bb2   Christoph Hellwig   freeze_bdev: kill...
776
  	mutex_unlock(&bdev->bd_fsfreeze_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
  	if (IS_ERR(s))
454e2398b   David Howells   [PATCH] VFS: Perm...
778
  		goto error_s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
781
  
  	if (s->s_root) {
  		if ((flags ^ s->s_flags) & MS_RDONLY) {
74dbbdd7f   Al Viro   New helper: deact...
782
  			deactivate_locked_super(s);
454e2398b   David Howells   [PATCH] VFS: Perm...
783
784
  			error = -EBUSY;
  			goto error_bdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
  		}
454e2398b   David Howells   [PATCH] VFS: Perm...
786

4f331f01b   Tejun Heo   vfs: don't hold s...
787
788
  		/*
  		 * s_umount nests inside bd_mutex during
e525fd89d   Tejun Heo   block: make blkde...
789
790
791
792
  		 * __invalidate_device().  blkdev_put() acquires
  		 * bd_mutex and can't be called under s_umount.  Drop
  		 * s_umount temporarily.  This is safe as we're
  		 * holding an active reference.
4f331f01b   Tejun Heo   vfs: don't hold s...
793
794
  		 */
  		up_write(&s->s_umount);
d4d776299   Tejun Heo   block: clean up b...
795
  		blkdev_put(bdev, mode);
4f331f01b   Tejun Heo   vfs: don't hold s...
796
  		down_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
798
799
800
  	} else {
  		char b[BDEVNAME_SIZE];
  
  		s->s_flags = flags;
30c40d2c0   Al Viro   [PATCH] propagate...
801
  		s->s_mode = mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
802
  		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
e78c9a004   Pekka Enberg   [PATCH] fs: remov...
803
  		sb_set_blocksize(s, block_size(bdev));
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
804
  		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
  		if (error) {
74dbbdd7f   Al Viro   New helper: deact...
806
  			deactivate_locked_super(s);
454e2398b   David Howells   [PATCH] VFS: Perm...
807
  			goto error;
fa675765a   Greg Kroah-Hartman   Revert mount/umou...
808
  		}
454e2398b   David Howells   [PATCH] VFS: Perm...
809
810
  
  		s->s_flags |= MS_ACTIVE;
87d8fe1ee   Theodore Ts'o   add releasepage h...
811
  		bdev->bd_super = s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
  	}
152a08366   Al Viro   new helper: mount...
813
  	return dget(s->s_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814

454e2398b   David Howells   [PATCH] VFS: Perm...
815
816
817
  error_s:
  	error = PTR_ERR(s);
  error_bdev:
d4d776299   Tejun Heo   block: clean up b...
818
  	blkdev_put(bdev, mode);
454e2398b   David Howells   [PATCH] VFS: Perm...
819
  error:
152a08366   Al Viro   new helper: mount...
820
821
822
  	return ERR_PTR(error);
  }
  EXPORT_SYMBOL(mount_bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823
824
825
  void kill_block_super(struct super_block *sb)
  {
  	struct block_device *bdev = sb->s_bdev;
30c40d2c0   Al Viro   [PATCH] propagate...
826
  	fmode_t mode = sb->s_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827

ddbaaf302   H Hartley Sweeten   NULL noise in fs/...
828
  	bdev->bd_super = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
  	generic_shutdown_super(sb);
  	sync_blockdev(bdev);
d4d776299   Tejun Heo   block: clean up b...
831
  	WARN_ON_ONCE(!(mode & FMODE_EXCL));
e525fd89d   Tejun Heo   block: make blkde...
832
  	blkdev_put(bdev, mode | FMODE_EXCL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
834
835
  }
  
  EXPORT_SYMBOL(kill_block_super);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
836
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837

3c26ff6e4   Al Viro   convert get_sb_no...
838
  struct dentry *mount_nodev(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
  	int flags, void *data,
3c26ff6e4   Al Viro   convert get_sb_no...
840
  	int (*fill_super)(struct super_block *, void *, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
844
845
  {
  	int error;
  	struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
  
  	if (IS_ERR(s))
3c26ff6e4   Al Viro   convert get_sb_no...
846
  		return ERR_CAST(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
  
  	s->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
849
  	error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
  	if (error) {
74dbbdd7f   Al Viro   New helper: deact...
851
  		deactivate_locked_super(s);
3c26ff6e4   Al Viro   convert get_sb_no...
852
  		return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
  	}
  	s->s_flags |= MS_ACTIVE;
3c26ff6e4   Al Viro   convert get_sb_no...
855
  	return dget(s->s_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  }
3c26ff6e4   Al Viro   convert get_sb_no...
857
  EXPORT_SYMBOL(mount_nodev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
859
860
861
  static int compare_single(struct super_block *s, void *p)
  {
  	return 1;
  }
fc14f2fef   Al Viro   convert get_sb_si...
862
  struct dentry *mount_single(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
  	int flags, void *data,
fc14f2fef   Al Viro   convert get_sb_si...
864
  	int (*fill_super)(struct super_block *, void *, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
866
867
868
869
870
  {
  	struct super_block *s;
  	int error;
  
  	s = sget(fs_type, compare_single, set_anon_super, NULL);
  	if (IS_ERR(s))
fc14f2fef   Al Viro   convert get_sb_si...
871
  		return ERR_CAST(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
  	if (!s->s_root) {
  		s->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
874
  		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
  		if (error) {
74dbbdd7f   Al Viro   New helper: deact...
876
  			deactivate_locked_super(s);
fc14f2fef   Al Viro   convert get_sb_si...
877
  			return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
879
  		}
  		s->s_flags |= MS_ACTIVE;
9329d1bea   Kay Sievers   vfs: get_sb_singl...
880
881
  	} else {
  		do_remount_sb(s, flags, data, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  	}
fc14f2fef   Al Viro   convert get_sb_si...
883
884
885
  	return dget(s->s_root);
  }
  EXPORT_SYMBOL(mount_single);
9d412a43c   Al Viro   vfs: split off vf...
886
887
  struct dentry *
  mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
  {
c96e41e92   Al Viro   beginning of tran...
889
  	struct dentry *root;
9d412a43c   Al Viro   vfs: split off vf...
890
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
  	char *secdata = NULL;
9d412a43c   Al Viro   vfs: split off vf...
892
  	int error = -ENOMEM;
8089352a1   Al Viro   Mirror MS_KERNMOU...
893

e00075298   Eric Paris   LSM/SELinux: Inte...
894
  	if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
  		secdata = alloc_secdata();
454e2398b   David Howells   [PATCH] VFS: Perm...
896
  		if (!secdata)
9d412a43c   Al Viro   vfs: split off vf...
897
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898

e00075298   Eric Paris   LSM/SELinux: Inte...
899
  		error = security_sb_copy_data(data, secdata);
454e2398b   David Howells   [PATCH] VFS: Perm...
900
  		if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  			goto out_free_secdata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
  	}
1a102ff92   Al Viro   vfs: bury ->get_sb()
903
904
905
906
  	root = type->mount(type, flags, name, data);
  	if (IS_ERR(root)) {
  		error = PTR_ERR(root);
  		goto out_free_secdata;
c96e41e92   Al Viro   beginning of tran...
907
  	}
9d412a43c   Al Viro   vfs: split off vf...
908
909
910
  	sb = root->d_sb;
  	BUG_ON(!sb);
  	WARN_ON(!sb->s_bdi);
6c5103890   Linus Torvalds   Merge branch 'for...
911
  	WARN_ON(sb->s_bdi == &default_backing_dev_info);
9d412a43c   Al Viro   vfs: split off vf...
912
  	sb->s_flags |= MS_BORN;
454e2398b   David Howells   [PATCH] VFS: Perm...
913

9d412a43c   Al Viro   vfs: split off vf...
914
  	error = security_sb_kern_mount(sb, flags, secdata);
5129a469a   Jörn Engel   Catch filesystems...
915
916
  	if (error)
  		goto out_sb;
454e2398b   David Howells   [PATCH] VFS: Perm...
917

42cb56ae2   Jeff Layton   vfs: change sb->s...
918
919
920
921
922
923
924
  	/*
  	 * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE
  	 * but s_maxbytes was an unsigned long long for many releases. Throw
  	 * this warning for a little while to try and catch filesystems that
  	 * violate this rule. This warning should be either removed or
  	 * converted to a BUG() in 2.6.34.
  	 */
9d412a43c   Al Viro   vfs: split off vf...
925
926
927
  	WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
  		"negative value (%lld)
  ", type->name, sb->s_maxbytes);
42cb56ae2   Jeff Layton   vfs: change sb->s...
928

9d412a43c   Al Viro   vfs: split off vf...
929
  	up_write(&sb->s_umount);
8680e22f2   Gerald Schaefer   [PATCH] VFS: memo...
930
  	free_secdata(secdata);
9d412a43c   Al Viro   vfs: split off vf...
931
  	return root;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
  out_sb:
9d412a43c   Al Viro   vfs: split off vf...
933
934
  	dput(root);
  	deactivate_locked_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
935
936
  out_free_secdata:
  	free_secdata(secdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
  out:
454e2398b   David Howells   [PATCH] VFS: Perm...
938
  	return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939
  }
18e9e5104   Josef Bacik   Introduce freeze_...
940
  /**
7000d3c42   Randy Dunlap   fs/super: fix ker...
941
942
   * freeze_super - lock the filesystem and force it into a consistent state
   * @sb: the super to lock
18e9e5104   Josef Bacik   Introduce freeze_...
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
   *
   * Syncs the super to make sure the filesystem is consistent and calls the fs's
   * freeze_fs.  Subsequent calls to this without first thawing the fs will return
   * -EBUSY.
   */
  int freeze_super(struct super_block *sb)
  {
  	int ret;
  
  	atomic_inc(&sb->s_active);
  	down_write(&sb->s_umount);
  	if (sb->s_frozen) {
  		deactivate_locked_super(sb);
  		return -EBUSY;
  	}
  
  	if (sb->s_flags & MS_RDONLY) {
  		sb->s_frozen = SB_FREEZE_TRANS;
  		smp_wmb();
  		up_write(&sb->s_umount);
  		return 0;
  	}
  
  	sb->s_frozen = SB_FREEZE_WRITE;
  	smp_wmb();
  
  	sync_filesystem(sb);
  
  	sb->s_frozen = SB_FREEZE_TRANS;
  	smp_wmb();
  
  	sync_blockdev(sb->s_bdev);
  	if (sb->s_op->freeze_fs) {
  		ret = sb->s_op->freeze_fs(sb);
  		if (ret) {
  			printk(KERN_ERR
  				"VFS:Filesystem freeze failed
  ");
  			sb->s_frozen = SB_UNFROZEN;
  			deactivate_locked_super(sb);
  			return ret;
  		}
  	}
  	up_write(&sb->s_umount);
  	return 0;
  }
  EXPORT_SYMBOL(freeze_super);
  
  /**
   * thaw_super -- unlock filesystem
   * @sb: the super to thaw
   *
   * Unlocks the filesystem and marks it writeable again after freeze_super().
   */
  int thaw_super(struct super_block *sb)
  {
  	int error;
  
  	down_write(&sb->s_umount);
  	if (sb->s_frozen == SB_UNFROZEN) {
  		up_write(&sb->s_umount);
  		return -EINVAL;
  	}
  
  	if (sb->s_flags & MS_RDONLY)
  		goto out;
  
  	if (sb->s_op->unfreeze_fs) {
  		error = sb->s_op->unfreeze_fs(sb);
  		if (error) {
  			printk(KERN_ERR
  				"VFS:Filesystem thaw failed
  ");
  			sb->s_frozen = SB_FREEZE_TRANS;
  			up_write(&sb->s_umount);
  			return error;
  		}
  	}
  
  out:
  	sb->s_frozen = SB_UNFROZEN;
  	smp_wmb();
  	wake_up(&sb->s_wait_unfrozen);
  	deactivate_locked_super(sb);
  
  	return 0;
  }
  EXPORT_SYMBOL(thaw_super);