Blame view

fs/super.c 25.5 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>
6d59e7f58   Al Viro   [PATCH] move a bu...
32
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
  LIST_HEAD(super_blocks);
  DEFINE_SPINLOCK(sb_lock);
  
  /**
   *	alloc_super	-	create new superblock
fe2bbc483   Henrik Kretzschmar   [PATCH] add missi...
39
   *	@type:	filesystem type superblock should belong to
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
   *
   *	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: ...
44
  static struct super_block *alloc_super(struct file_system_type *type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  {
11b0b5abb   Oliver Neukum   [PATCH] use kzall...
46
  	struct super_block *s = kzalloc(sizeof(struct super_block),  GFP_USER);
b87221de6   Alexey Dobriyan   const: mark remai...
47
  	static const struct super_operations default_op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
  
  	if (s) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
  		if (security_sb_alloc(s)) {
  			kfree(s);
  			s = NULL;
  			goto out;
  		}
6416ccb78   Nick Piggin   fs: scale files_lock
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  #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
69
  		INIT_LIST_HEAD(&s->s_files);
6416ccb78   Nick Piggin   fs: scale files_lock
70
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
  		INIT_LIST_HEAD(&s->s_instances);
  		INIT_HLIST_HEAD(&s->s_anon);
  		INIT_LIST_HEAD(&s->s_inodes);
da3bbdd46   Kentaro Makita   fix soft lock up ...
74
  		INIT_LIST_HEAD(&s->s_dentry_lru);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  		init_rwsem(&s->s_umount);
7892f2f48   Ingo Molnar   [PATCH] mutex sub...
76
  		mutex_init(&s->s_lock);
897c6ff95   Arjan van de Ven   [PATCH] lockdep: ...
77
  		lockdep_set_class(&s->s_umount, &type->s_umount_key);
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
78
79
80
81
82
83
  		/*
  		 * 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...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  		/*
  		 * 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
100
  		s->s_count = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  		atomic_set(&s->s_active, 1);
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
102
  		mutex_init(&s->s_vfs_rename_mutex);
51ee049e7   Roland Dreier   vfs: add lockdep ...
103
  		lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
104
105
  		mutex_init(&s->s_dquot.dqio_mutex);
  		mutex_init(&s->s_dquot.dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
  		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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  		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
124
125
126
  #ifdef CONFIG_SMP
  	free_percpu(s->s_files);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  	security_sb_free(s);
79c0b2df7   Miklos Szeredi   add filesystem su...
128
  	kfree(s->s_subtype);
b3b304a23   Miklos Szeredi   mount options: ad...
129
  	kfree(s->s_options);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
133
134
135
  	kfree(s);
  }
  
  /* Superblock refcounting  */
  
  /*
35cf7ba0b   Al Viro   Bury __put_super_...
136
   * Drop a superblock's refcount.  The caller must hold sb_lock.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
   */
35cf7ba0b   Al Viro   Bury __put_super_...
138
  void __put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  	if (!--sb->s_count) {
551de6f34   Al Viro   Leave superblocks...
141
  		list_del_init(&sb->s_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  		destroy_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
148
149
150
151
152
  }
  
  /**
   *	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...
153
  void put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
157
158
159
160
161
  {
  	spin_lock(&sb_lock);
  	__put_super(sb);
  	spin_unlock(&sb_lock);
  }
  
  
  /**
1712ac8fd   Al Viro   Saner locking aro...
162
   *	deactivate_locked_super	-	drop an active reference to superblock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
   *	@s: superblock to deactivate
   *
1712ac8fd   Al Viro   Saner locking aro...
165
166
   *	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
167
168
   *	tell fs driver to shut it down and drop the temporary reference we
   *	had just acquired.
1712ac8fd   Al Viro   Saner locking aro...
169
170
   *
   *	Caller holds exclusive lock on superblock; that lock is released.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
   */
1712ac8fd   Al Viro   Saner locking aro...
172
  void deactivate_locked_super(struct super_block *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  {
  	struct file_system_type *fs = s->s_type;
b20bd1a5e   Al Viro   get rid of S_BIAS
175
  	if (atomic_dec_and_test(&s->s_active)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
178
  		fs->kill_sb(s);
  		put_filesystem(fs);
  		put_super(s);
1712ac8fd   Al Viro   Saner locking aro...
179
180
  	} else {
  		up_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
  	}
  }
1712ac8fd   Al Viro   Saner locking aro...
183
  EXPORT_SYMBOL(deactivate_locked_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
  
  /**
1712ac8fd   Al Viro   Saner locking aro...
186
   *	deactivate_super	-	drop an active reference to superblock
74dbbdd7f   Al Viro   New helper: deact...
187
188
   *	@s: superblock to deactivate
   *
1712ac8fd   Al Viro   Saner locking aro...
189
190
191
   *	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...
192
   */
1712ac8fd   Al Viro   Saner locking aro...
193
  void deactivate_super(struct super_block *s)
74dbbdd7f   Al Viro   New helper: deact...
194
  {
1712ac8fd   Al Viro   Saner locking aro...
195
196
197
          if (!atomic_add_unless(&s->s_active, -1, 1)) {
  		down_write(&s->s_umount);
  		deactivate_locked_super(s);
74dbbdd7f   Al Viro   New helper: deact...
198
199
  	}
  }
1712ac8fd   Al Viro   Saner locking aro...
200
  EXPORT_SYMBOL(deactivate_super);
74dbbdd7f   Al Viro   New helper: deact...
201
202
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
209
210
211
212
   *	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...
213
  static int grab_super(struct super_block *s) __releases(sb_lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
  {
b20bd1a5e   Al Viro   get rid of S_BIAS
215
216
  	if (atomic_inc_not_zero(&s->s_active)) {
  		spin_unlock(&sb_lock);
b20bd1a5e   Al Viro   get rid of S_BIAS
217
218
219
  		return 1;
  	}
  	/* it's going away */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
  	s->s_count++;
  	spin_unlock(&sb_lock);
1712ac8fd   Al Viro   Saner locking aro...
222
  	/* wait for it to die */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
  	down_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
  	up_write(&s->s_umount);
  	put_super(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
  	return 0;
  }
cf9a2ae8d   David Howells   [PATCH] BLOCK: Mo...
228
  /*
914e26379   Al Viro   [PATCH] severing ...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
   * 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
245
246
247
248
249
250
251
252
253
  /**
   *	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...
254
255
256
257
   *
   *	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
258
259
260
   */
  void generic_shutdown_super(struct super_block *sb)
  {
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
261
  	const struct super_operations *sop = sb->s_op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
271
  		/* bad name - it should be evict_inodes() */
  		invalidate_inodes(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
276
277
  		if (sop->put_super)
  			sop->put_super(sb);
  
  		/* Forget any remaining inodes */
  		if (invalidate_inodes(sb)) {
7b4fe29e0   Dave Jones   [PATCH] More info...
278
279
280
281
  			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
282
  		}
a9e220f83   Al Viro   No need to do loc...
283
  		put_fs_excl();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
  	}
  	spin_lock(&sb_lock);
  	/* should be initialized for __put_super_and_need_restart() */
551de6f34   Al Viro   Leave superblocks...
287
  	list_del_init(&sb->s_instances);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  	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...
307
  	struct super_block *old;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
309
310
311
  	int err;
  
  retry:
  	spin_lock(&sb_lock);
d47301271   Matthias Kaehlcke   fs/super.c: use l...
312
313
314
315
316
317
  	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 ...
318
319
  			if (s) {
  				up_write(&s->s_umount);
d47301271   Matthias Kaehlcke   fs/super.c: use l...
320
  				destroy_super(s);
7a4dec538   Al Viro   Fix sget() race w...
321
  				s = NULL;
a3cfbb53b   Li Zefan   vfs: add missing ...
322
  			}
d3f214730   Al Viro   Move grabbing s_u...
323
  			down_write(&old->s_umount);
7a4dec538   Al Viro   Fix sget() race w...
324
325
326
327
  			if (unlikely(!(old->s_flags & MS_BORN))) {
  				deactivate_locked_super(old);
  				goto retry;
  			}
d47301271   Matthias Kaehlcke   fs/super.c: use l...
328
329
  			return old;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
331
332
  	}
  	if (!s) {
  		spin_unlock(&sb_lock);
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
333
  		s = alloc_super(type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
336
337
338
339
340
341
  		if (!s)
  			return ERR_PTR(-ENOMEM);
  		goto retry;
  	}
  		
  	err = set(s, data);
  	if (err) {
  		spin_unlock(&sb_lock);
a3cfbb53b   Li Zefan   vfs: add missing ...
342
  		up_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
  		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
364
365
366
367
368
369
370
371
  /**
   * 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
372
373
374
375
376
377
   * 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_...
378
  	struct super_block *sb, *p = NULL;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
379

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  			down_read(&sb->s_umount);
e50047533   Christoph Hellwig   cleanup sync_supers
389
390
  			if (sb->s_root && sb->s_dirt)
  				sb->s_op->write_super(sb);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
391
  			up_read(&sb->s_umount);
e50047533   Christoph Hellwig   cleanup sync_supers
392

618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
393
  			spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
394
395
396
  			if (p)
  				__put_super(p);
  			p = sb;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
397
398
  		}
  	}
dca332528   Al Viro   no need for list_...
399
400
  	if (p)
  		__put_super(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
  	spin_unlock(&sb_lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
  /**
01a05b337   Al Viro   new helper: itera...
404
405
406
407
408
409
410
411
412
   *	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_...
413
  	struct super_block *sb, *p = NULL;
01a05b337   Al Viro   new helper: itera...
414
415
  
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
416
  	list_for_each_entry(sb, &super_blocks, s_list) {
01a05b337   Al Viro   new helper: itera...
417
418
419
420
421
422
423
424
425
426
427
  		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_...
428
429
430
  		if (p)
  			__put_super(p);
  		p = sb;
01a05b337   Al Viro   new helper: itera...
431
  	}
dca332528   Al Viro   no need for list_...
432
433
  	if (p)
  		__put_super(p);
01a05b337   Al Viro   new helper: itera...
434
435
436
437
  	spin_unlock(&sb_lock);
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
443
   *	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...
444
  struct super_block *get_super(struct block_device *bdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  {
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
446
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
  	if (!bdev)
  		return NULL;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
449

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  	spin_lock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
451
452
  rescan:
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
453
454
  		if (list_empty(&sb->s_instances))
  			continue;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
455
456
  		if (sb->s_bdev == bdev) {
  			sb->s_count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
  			spin_unlock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
458
  			down_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
459
  			/* still alive? */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
460
461
462
  			if (sb->s_root)
  				return sb;
  			up_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
463
  			/* nope, got unmounted */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
464
  			spin_lock(&sb_lock);
df40c01a9   Al Viro   In get_super() an...
465
466
  			__put_super(sb);
  			goto rescan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
468
469
470
471
472
473
  		}
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
  
  EXPORT_SYMBOL(get_super);
4504230a7   Christoph Hellwig   freeze_bdev: grab...
474
475
476
477
478
479
480
  
  /**
   * 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...
481
   * reference or %NULL if none was found.
4504230a7   Christoph Hellwig   freeze_bdev: grab...
482
483
484
485
486
487
488
   */
  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...
489
  restart:
4504230a7   Christoph Hellwig   freeze_bdev: grab...
490
491
  	spin_lock(&sb_lock);
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
492
493
  		if (list_empty(&sb->s_instances))
  			continue;
1494583de   Al Viro   fix get_active_su...
494
495
496
497
498
499
  		if (sb->s_bdev == bdev) {
  			if (grab_super(sb)) /* drops sb_lock */
  				return sb;
  			else
  				goto restart;
  		}
4504230a7   Christoph Hellwig   freeze_bdev: grab...
500
501
502
503
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
   
df40c01a9   Al Viro   In get_super() an...
505
  struct super_block *user_get_super(dev_t dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
  {
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
507
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
  	spin_lock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
510
511
  rescan:
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
512
513
  		if (list_empty(&sb->s_instances))
  			continue;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
514
515
  		if (sb->s_dev ==  dev) {
  			sb->s_count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  			spin_unlock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
517
  			down_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
518
  			/* still alive? */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
519
520
521
  			if (sb->s_root)
  				return sb;
  			up_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
522
  			/* nope, got unmounted */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
523
  			spin_lock(&sb_lock);
df40c01a9   Al Viro   In get_super() an...
524
525
  			__put_super(sb);
  			goto rescan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
530
  		}
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
538
539
540
541
542
   *	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...
543
  	int remount_ro;
4504230a7   Christoph Hellwig   freeze_bdev: grab...
544
545
546
  
  	if (sb->s_frozen != SB_UNFROZEN)
  		return -EBUSY;
9361401eb   David Howells   [PATCH] BLOCK: Ma...
547
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
  	if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
  		return -EACCES;
9361401eb   David Howells   [PATCH] BLOCK: Ma...
550
  #endif
4504230a7   Christoph Hellwig   freeze_bdev: grab...
551

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
554
  	if (flags & MS_RDONLY)
  		acct_auto_close(sb);
  	shrink_dcache_sb(sb);
60b0680fa   Jan Kara   vfs: Rename fsync...
555
  	sync_filesystem(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
  	/* 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...
561
  	if (remount_ro) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
  		if (force)
  			mark_files_ro(sb);
b0895513f   J. R. Okajima   remove unlock_ker...
564
  		else if (!fs_may_remount_ro(sb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
567
568
  			return -EBUSY;
  	}
  
  	if (sb->s_op->remount_fs) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  		retval = sb->s_op->remount_fs(sb, &flags, data);
b0895513f   J. R. Okajima   remove unlock_ker...
570
  		if (retval)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
  			return retval;
  	}
  	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
c79d967de   Christoph Hellwig   quota: move remou...
574

d208bbdda   Nick Piggin   fs: improve remou...
575
576
577
578
579
580
581
582
583
584
  	/*
  	 * 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
585
586
  	return 0;
  }
a2a9537ac   Jens Axboe   Get rid of pdflus...
587
  static void do_emergency_remount(struct work_struct *work)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
588
  {
dca332528   Al Viro   no need for list_...
589
  	struct super_block *sb, *p = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
  
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
592
  	list_for_each_entry(sb, &super_blocks, s_list) {
551de6f34   Al Viro   Leave superblocks...
593
594
  		if (list_empty(&sb->s_instances))
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
596
  		sb->s_count++;
  		spin_unlock(&sb_lock);
443b94baa   Al Viro   Make sure that al...
597
  		down_write(&sb->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
  		if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) {
  			/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
600
601
  			 * What lock protects sb->s_flags??
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
  			do_remount_sb(sb, MS_RDONLY, NULL, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
  		}
443b94baa   Al Viro   Make sure that al...
604
  		up_write(&sb->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
  		spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
606
607
608
  		if (p)
  			__put_super(p);
  		p = sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	}
dca332528   Al Viro   no need for list_...
610
611
  	if (p)
  		__put_super(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
  	spin_unlock(&sb_lock);
a2a9537ac   Jens Axboe   Get rid of pdflus...
613
  	kfree(work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
616
617
618
619
  	printk("Emergency Remount complete
  ");
  }
  
  void emergency_remount(void)
  {
a2a9537ac   Jens Axboe   Get rid of pdflus...
620
621
622
623
624
625
626
  	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
627
628
629
630
631
632
  }
  
  /*
   * 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...
633
  static DEFINE_IDA(unnamed_dev_ida);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
  static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
c63e09ecc   Al Viro   Make allocation o...
635
  static int unnamed_dev_start = 0; /* don't bother trying below it */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
637
638
639
640
641
642
  
  int set_anon_super(struct super_block *s, void *data)
  {
  	int dev;
  	int error;
  
   retry:
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
643
  	if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
645
  		return -ENOMEM;
  	spin_lock(&unnamed_dev_lock);
c63e09ecc   Al Viro   Make allocation o...
646
  	error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev);
f21f62208   Al Viro   ... and the same ...
647
648
  	if (!error)
  		unnamed_dev_start = dev + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
650
651
652
653
654
655
656
657
  	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...
658
  		ida_remove(&unnamed_dev_ida, dev);
f21f62208   Al Viro   ... and the same ...
659
660
  		if (unnamed_dev_start > dev)
  			unnamed_dev_start = dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
661
662
663
664
  		spin_unlock(&unnamed_dev_lock);
  		return -EMFILE;
  	}
  	s->s_dev = MKDEV(0, dev & MINORMASK);
5129a469a   Jörn Engel   Catch filesystems...
665
  	s->s_bdi = &noop_backing_dev_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
667
668
669
670
671
672
673
674
675
676
  	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...
677
  	ida_remove(&unnamed_dev_ida, slot);
c63e09ecc   Al Viro   Make allocation o...
678
679
  	if (slot < unnamed_dev_start)
  		unnamed_dev_start = slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
681
682
683
  	spin_unlock(&unnamed_dev_lock);
  }
  
  EXPORT_SYMBOL(kill_anon_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
684
685
686
687
688
689
690
691
  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 ...
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
  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);
  }
  
  int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
  	int (*fill_super)(struct super_block *, void *, int),
  	struct vfsmount *mnt)
  {
  	struct super_block *sb;
  
  	sb = sget(fs_type, ns_test_super, ns_set_super, data);
  	if (IS_ERR(sb))
  		return PTR_ERR(sb);
  
  	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...
718
  			deactivate_locked_super(sb);
909e6d947   Serge E. Hallyn   namespaces: move ...
719
720
721
722
723
724
725
726
727
728
729
  			return err;
  		}
  
  		sb->s_flags |= MS_ACTIVE;
  	}
  
  	simple_set_mnt(mnt, sb);
  	return 0;
  }
  
  EXPORT_SYMBOL(get_sb_ns);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
730
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
732
733
734
  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...
735
736
737
738
739
740
  
  	/*
  	 * 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
741
742
743
744
745
746
747
  	return 0;
  }
  
  static int test_bdev_super(struct super_block *s, void *data)
  {
  	return (void *)s->s_bdev == data;
  }
454e2398b   David Howells   [PATCH] VFS: Perm...
748
  int get_sb_bdev(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
  	int flags, const char *dev_name, void *data,
454e2398b   David Howells   [PATCH] VFS: Perm...
750
751
  	int (*fill_super)(struct super_block *, void *, int),
  	struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
754
  {
  	struct block_device *bdev;
  	struct super_block *s;
30c40d2c0   Al Viro   [PATCH] propagate...
755
  	fmode_t mode = FMODE_READ;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
  	int error = 0;
30c40d2c0   Al Viro   [PATCH] propagate...
757
758
759
760
  	if (!(flags & MS_RDONLY))
  		mode |= FMODE_WRITE;
  
  	bdev = open_bdev_exclusive(dev_name, mode, fs_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
  	if (IS_ERR(bdev))
454e2398b   David Howells   [PATCH] VFS: Perm...
762
  		return PTR_ERR(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
789
790
791
792
793
794
  		/*
  		 * s_umount nests inside bd_mutex during
  		 * __invalidate_device().  close_bdev_exclusive()
  		 * 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.
  		 */
  		up_write(&s->s_umount);
30c40d2c0   Al Viro   [PATCH] propagate...
795
  		close_bdev_exclusive(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
  	}
a3ec947c8   Sukadev Bhattiprolu   vfs: simple_set_m...
813
814
  	simple_set_mnt(mnt, s);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815

454e2398b   David Howells   [PATCH] VFS: Perm...
816
817
818
  error_s:
  	error = PTR_ERR(s);
  error_bdev:
30c40d2c0   Al Viro   [PATCH] propagate...
819
  	close_bdev_exclusive(bdev, mode);
454e2398b   David Howells   [PATCH] VFS: Perm...
820
821
  error:
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
824
825
826
827
828
  }
  
  EXPORT_SYMBOL(get_sb_bdev);
  
  void kill_block_super(struct super_block *sb)
  {
  	struct block_device *bdev = sb->s_bdev;
30c40d2c0   Al Viro   [PATCH] propagate...
829
  	fmode_t mode = sb->s_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830

ddbaaf302   H Hartley Sweeten   NULL noise in fs/...
831
  	bdev->bd_super = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
833
  	generic_shutdown_super(sb);
  	sync_blockdev(bdev);
30c40d2c0   Al Viro   [PATCH] propagate...
834
  	close_bdev_exclusive(bdev, mode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
836
837
  }
  
  EXPORT_SYMBOL(kill_block_super);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
838
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839

454e2398b   David Howells   [PATCH] VFS: Perm...
840
  int get_sb_nodev(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
  	int flags, void *data,
454e2398b   David Howells   [PATCH] VFS: Perm...
842
843
  	int (*fill_super)(struct super_block *, void *, int),
  	struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
845
846
847
848
  {
  	int error;
  	struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
  
  	if (IS_ERR(s))
454e2398b   David Howells   [PATCH] VFS: Perm...
849
  		return PTR_ERR(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
851
  
  	s->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
852
  	error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
  	if (error) {
74dbbdd7f   Al Viro   New helper: deact...
854
  		deactivate_locked_super(s);
454e2398b   David Howells   [PATCH] VFS: Perm...
855
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
857
  	}
  	s->s_flags |= MS_ACTIVE;
a3ec947c8   Sukadev Bhattiprolu   vfs: simple_set_m...
858
859
  	simple_set_mnt(mnt, s);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
862
863
864
865
866
867
  }
  
  EXPORT_SYMBOL(get_sb_nodev);
  
  static int compare_single(struct super_block *s, void *p)
  {
  	return 1;
  }
454e2398b   David Howells   [PATCH] VFS: Perm...
868
  int get_sb_single(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
  	int flags, void *data,
454e2398b   David Howells   [PATCH] VFS: Perm...
870
871
  	int (*fill_super)(struct super_block *, void *, int),
  	struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
875
876
877
  {
  	struct super_block *s;
  	int error;
  
  	s = sget(fs_type, compare_single, set_anon_super, NULL);
  	if (IS_ERR(s))
454e2398b   David Howells   [PATCH] VFS: Perm...
878
  		return PTR_ERR(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
  	if (!s->s_root) {
  		s->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
881
  		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  		if (error) {
74dbbdd7f   Al Viro   New helper: deact...
883
  			deactivate_locked_super(s);
454e2398b   David Howells   [PATCH] VFS: Perm...
884
  			return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
886
  		}
  		s->s_flags |= MS_ACTIVE;
9329d1bea   Kay Sievers   vfs: get_sb_singl...
887
888
  	} else {
  		do_remount_sb(s, flags, data, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
889
  	}
a3ec947c8   Sukadev Bhattiprolu   vfs: simple_set_m...
890
891
  	simple_set_mnt(mnt, s);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
892
893
894
895
896
  }
  
  EXPORT_SYMBOL(get_sb_single);
  
  struct vfsmount *
bb4a58bf4   Trond Myklebust   VFS: Add GPL_EXPO...
897
  vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
  	struct vfsmount *mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900
  	char *secdata = NULL;
454e2398b   David Howells   [PATCH] VFS: Perm...
901
  	int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
904
  
  	if (!type)
  		return ERR_PTR(-ENODEV);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905

454e2398b   David Howells   [PATCH] VFS: Perm...
906
  	error = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907
908
909
  	mnt = alloc_vfsmnt(name);
  	if (!mnt)
  		goto out;
8089352a1   Al Viro   Mirror MS_KERNMOU...
910
911
  	if (flags & MS_KERNMOUNT)
  		mnt->mnt_flags = MNT_INTERNAL;
e00075298   Eric Paris   LSM/SELinux: Inte...
912
  	if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
  		secdata = alloc_secdata();
454e2398b   David Howells   [PATCH] VFS: Perm...
914
  		if (!secdata)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
  			goto out_mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
916

e00075298   Eric Paris   LSM/SELinux: Inte...
917
  		error = security_sb_copy_data(data, secdata);
454e2398b   David Howells   [PATCH] VFS: Perm...
918
  		if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  			goto out_free_secdata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
920
  	}
454e2398b   David Howells   [PATCH] VFS: Perm...
921
922
  	error = type->get_sb(type, flags, name, data, mnt);
  	if (error < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
923
  		goto out_free_secdata;
b4c07bce7   Lee Schermerhorn   hugetlbfs: handle...
924
  	BUG_ON(!mnt->mnt_sb);
5129a469a   Jörn Engel   Catch filesystems...
925
  	WARN_ON(!mnt->mnt_sb->s_bdi);
7a4dec538   Al Viro   Fix sget() race w...
926
  	mnt->mnt_sb->s_flags |= MS_BORN;
454e2398b   David Howells   [PATCH] VFS: Perm...
927

5129a469a   Jörn Engel   Catch filesystems...
928
929
930
  	error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
  	if (error)
  		goto out_sb;
454e2398b   David Howells   [PATCH] VFS: Perm...
931

42cb56ae2   Jeff Layton   vfs: change sb->s...
932
933
934
935
936
937
938
939
940
941
  	/*
  	 * 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.
  	 */
  	WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
  		"negative value (%lld)
  ", type->name, mnt->mnt_sb->s_maxbytes);
454e2398b   David Howells   [PATCH] VFS: Perm...
942
  	mnt->mnt_mountpoint = mnt->mnt_root;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
  	mnt->mnt_parent = mnt;
454e2398b   David Howells   [PATCH] VFS: Perm...
944
  	up_write(&mnt->mnt_sb->s_umount);
8680e22f2   Gerald Schaefer   [PATCH] VFS: memo...
945
  	free_secdata(secdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946
947
  	return mnt;
  out_sb:
454e2398b   David Howells   [PATCH] VFS: Perm...
948
  	dput(mnt->mnt_root);
74dbbdd7f   Al Viro   New helper: deact...
949
  	deactivate_locked_super(mnt->mnt_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
951
952
953
954
  out_free_secdata:
  	free_secdata(secdata);
  out_mnt:
  	free_vfsmnt(mnt);
  out:
454e2398b   David Howells   [PATCH] VFS: Perm...
955
  	return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
  }
bb4a58bf4   Trond Myklebust   VFS: Add GPL_EXPO...
957
  EXPORT_SYMBOL_GPL(vfs_kern_mount);
18e9e5104   Josef Bacik   Introduce freeze_...
958
  /**
7000d3c42   Randy Dunlap   fs/super: fix ker...
959
960
   * freeze_super - lock the filesystem and force it into a consistent state
   * @sb: the super to lock
18e9e5104   Josef Bacik   Introduce freeze_...
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
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
   *
   * 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);
79c0b2df7   Miklos Szeredi   add filesystem su...
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
  static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
  {
  	int err;
  	const char *subtype = strchr(fstype, '.');
  	if (subtype) {
  		subtype++;
  		err = -EINVAL;
  		if (!subtype[0])
  			goto err;
  	} else
  		subtype = "";
  
  	mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
  	err = -ENOMEM;
  	if (!mnt->mnt_sb->s_subtype)
  		goto err;
  	return mnt;
  
   err:
  	mntput(mnt);
  	return ERR_PTR(err);
  }
bb4a58bf4   Trond Myklebust   VFS: Add GPL_EXPO...
1071
1072
1073
1074
1075
1076
1077
1078
  struct vfsmount *
  do_kern_mount(const char *fstype, int flags, const char *name, void *data)
  {
  	struct file_system_type *type = get_fs_type(fstype);
  	struct vfsmount *mnt;
  	if (!type)
  		return ERR_PTR(-ENODEV);
  	mnt = vfs_kern_mount(type, flags, name, data);
79c0b2df7   Miklos Szeredi   add filesystem su...
1079
1080
1081
  	if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
  	    !mnt->mnt_sb->s_subtype)
  		mnt = fs_set_subtype(mnt, fstype);
bb4a58bf4   Trond Myklebust   VFS: Add GPL_EXPO...
1082
1083
1084
  	put_filesystem(type);
  	return mnt;
  }
8a4e98d9d   Al Viro   [PATCH] restore e...
1085
  EXPORT_SYMBOL_GPL(do_kern_mount);
bb4a58bf4   Trond Myklebust   VFS: Add GPL_EXPO...
1086

8bf9725c2   Pavel Emelyanov   pid namespaces: i...
1087
  struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1088
  {
8bf9725c2   Pavel Emelyanov   pid namespaces: i...
1089
  	return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
  }
8bf9725c2   Pavel Emelyanov   pid namespaces: i...
1091
  EXPORT_SYMBOL_GPL(kern_mount_data);