Blame view

fs/super.c 29.2 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>
c515e1fd3   Dan Magenheimer   mm/fs: add hooks ...
33
  #include <linux/cleancache.h>
6d59e7f58   Al Viro   [PATCH] move a bu...
34
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
  LIST_HEAD(super_blocks);
  DEFINE_SPINLOCK(sb_lock);
b0d40c92a   Dave Chinner   superblock: intro...
38
39
40
41
42
43
44
45
46
47
  /*
   * One thing we have to be careful of with a per-sb shrinker is that we don't
   * drop the last active reference to the superblock from within the shrinker.
   * If that happens we could trigger unregistering the shrinker from within the
   * shrinker path and that leads to deadlock on the shrinker_rwsem. Hence we
   * take a passive reference to the superblock to avoid this from occurring.
   */
  static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
  {
  	struct super_block *sb;
0e1fdafd9   Dave Chinner   superblock: add f...
48
49
  	int	fs_objects = 0;
  	int	total_objects;
b0d40c92a   Dave Chinner   superblock: intro...
50
51
52
53
54
55
56
57
58
59
60
  
  	sb = container_of(shrink, struct super_block, s_shrink);
  
  	/*
  	 * Deadlock avoidance.  We may hold various FS locks, and we don't want
  	 * to recurse into the FS that called us in clear_inode() and friends..
  	 */
  	if (sc->nr_to_scan && !(sc->gfp_mask & __GFP_FS))
  		return -1;
  
  	if (!grab_super_passive(sb))
09f363c73   Mikulas Patocka   vmscan: fix shrin...
61
  		return !sc->nr_to_scan ? 0 : -1;
b0d40c92a   Dave Chinner   superblock: intro...
62

0e1fdafd9   Dave Chinner   superblock: add f...
63
64
65
66
67
  	if (sb->s_op && sb->s_op->nr_cached_objects)
  		fs_objects = sb->s_op->nr_cached_objects(sb);
  
  	total_objects = sb->s_nr_dentry_unused +
  			sb->s_nr_inodes_unused + fs_objects + 1;
b0d40c92a   Dave Chinner   superblock: intro...
68
  	if (sc->nr_to_scan) {
0e1fdafd9   Dave Chinner   superblock: add f...
69
70
  		int	dentries;
  		int	inodes;
b0d40c92a   Dave Chinner   superblock: intro...
71

0e1fdafd9   Dave Chinner   superblock: add f...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  		/* proportion the scan between the caches */
  		dentries = (sc->nr_to_scan * sb->s_nr_dentry_unused) /
  							total_objects;
  		inodes = (sc->nr_to_scan * sb->s_nr_inodes_unused) /
  							total_objects;
  		if (fs_objects)
  			fs_objects = (sc->nr_to_scan * fs_objects) /
  							total_objects;
  		/*
  		 * prune the dcache first as the icache is pinned by it, then
  		 * prune the icache, followed by the filesystem specific caches
  		 */
  		prune_dcache_sb(sb, dentries);
  		prune_icache_sb(sb, inodes);
b0d40c92a   Dave Chinner   superblock: intro...
86

0e1fdafd9   Dave Chinner   superblock: add f...
87
88
89
90
91
92
  		if (fs_objects && sb->s_op->free_cached_objects) {
  			sb->s_op->free_cached_objects(sb, fs_objects);
  			fs_objects = sb->s_op->nr_cached_objects(sb);
  		}
  		total_objects = sb->s_nr_dentry_unused +
  				sb->s_nr_inodes_unused + fs_objects;
b0d40c92a   Dave Chinner   superblock: intro...
93
  	}
0e1fdafd9   Dave Chinner   superblock: add f...
94
  	total_objects = (total_objects / 100) * sysctl_vfs_cache_pressure;
b0d40c92a   Dave Chinner   superblock: intro...
95
  	drop_super(sb);
0e1fdafd9   Dave Chinner   superblock: add f...
96
  	return total_objects;
b0d40c92a   Dave Chinner   superblock: intro...
97
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
99
  /**
   *	alloc_super	-	create new superblock
fe2bbc483   Henrik Kretzschmar   [PATCH] add missi...
100
   *	@type:	filesystem type superblock should belong to
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
   *
   *	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: ...
105
  static struct super_block *alloc_super(struct file_system_type *type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  {
11b0b5abb   Oliver Neukum   [PATCH] use kzall...
107
  	struct super_block *s = kzalloc(sizeof(struct super_block),  GFP_USER);
b87221de6   Alexey Dobriyan   const: mark remai...
108
  	static const struct super_operations default_op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
  
  	if (s) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
115
  		if (security_sb_alloc(s)) {
  			kfree(s);
  			s = NULL;
  			goto out;
  		}
6416ccb78   Nick Piggin   fs: scale files_lock
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  #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
130
  		INIT_LIST_HEAD(&s->s_files);
6416ccb78   Nick Piggin   fs: scale files_lock
131
  #endif
95f28604a   Jens Axboe   fs: assign sb->s_...
132
  		s->s_bdi = &default_backing_dev_info;
a5166169f   Al Viro   vfs: convert fs_s...
133
  		INIT_HLIST_NODE(&s->s_instances);
ceb5bdc2d   Nick Piggin   fs: dcache per-bu...
134
  		INIT_HLIST_BL_HEAD(&s->s_anon);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  		INIT_LIST_HEAD(&s->s_inodes);
da3bbdd46   Kentaro Makita   fix soft lock up ...
136
  		INIT_LIST_HEAD(&s->s_dentry_lru);
98b745c64   Dave Chinner   inode: Make unuse...
137
  		INIT_LIST_HEAD(&s->s_inode_lru);
09cc9fc7a   Dave Chinner   inode: move to pe...
138
  		spin_lock_init(&s->s_inode_lru_lock);
39f7c4db1   Miklos Szeredi   vfs: keep list of...
139
  		INIT_LIST_HEAD(&s->s_mounts);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  		init_rwsem(&s->s_umount);
7892f2f48   Ingo Molnar   [PATCH] mutex sub...
141
  		mutex_init(&s->s_lock);
897c6ff95   Arjan van de Ven   [PATCH] lockdep: ...
142
  		lockdep_set_class(&s->s_umount, &type->s_umount_key);
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
143
144
145
146
147
148
  		/*
  		 * 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...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  		/*
  		 * 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
165
  		s->s_count = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
  		atomic_set(&s->s_active, 1);
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
167
  		mutex_init(&s->s_vfs_rename_mutex);
51ee049e7   Roland Dreier   vfs: add lockdep ...
168
  		lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
169
170
  		mutex_init(&s->s_dquot.dqio_mutex);
  		mutex_init(&s->s_dquot.dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
172
173
  		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
174
175
  		s->s_op = &default_op;
  		s->s_time_gran = 1000000000;
c515e1fd3   Dan Magenheimer   mm/fs: add hooks ...
176
  		s->cleancache_poolid = -1;
b0d40c92a   Dave Chinner   superblock: intro...
177
178
179
  
  		s->s_shrink.seeks = DEFAULT_SEEKS;
  		s->s_shrink.shrink = prune_super;
8ab47664d   Dave Chinner   vfs: increase shr...
180
  		s->s_shrink.batch = 1024;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
184
185
186
187
188
189
190
191
192
193
  	}
  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
194
195
196
  #ifdef CONFIG_SMP
  	free_percpu(s->s_files);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
  	security_sb_free(s);
39f7c4db1   Miklos Szeredi   vfs: keep list of...
198
  	WARN_ON(!list_empty(&s->s_mounts));
79c0b2df7   Miklos Szeredi   add filesystem su...
199
  	kfree(s->s_subtype);
b3b304a23   Miklos Szeredi   mount options: ad...
200
  	kfree(s->s_options);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
206
  	kfree(s);
  }
  
  /* Superblock refcounting  */
  
  /*
35cf7ba0b   Al Viro   Bury __put_super_...
207
   * Drop a superblock's refcount.  The caller must hold sb_lock.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
   */
f47ec3f28   Al Viro   trim fs/internal.h
209
  static void __put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  	if (!--sb->s_count) {
551de6f34   Al Viro   Leave superblocks...
212
  		list_del_init(&sb->s_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  		destroy_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
217
218
219
220
221
222
223
  }
  
  /**
   *	put_super	-	drop a temporary reference to superblock
   *	@sb: superblock in question
   *
   *	Drops a temporary reference, frees superblock if there's no
   *	references left.
   */
f47ec3f28   Al Viro   trim fs/internal.h
224
  static void put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
227
228
229
230
231
232
  {
  	spin_lock(&sb_lock);
  	__put_super(sb);
  	spin_unlock(&sb_lock);
  }
  
  
  /**
1712ac8fd   Al Viro   Saner locking aro...
233
   *	deactivate_locked_super	-	drop an active reference to superblock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
   *	@s: superblock to deactivate
   *
1712ac8fd   Al Viro   Saner locking aro...
236
237
   *	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
238
239
   *	tell fs driver to shut it down and drop the temporary reference we
   *	had just acquired.
1712ac8fd   Al Viro   Saner locking aro...
240
241
   *
   *	Caller holds exclusive lock on superblock; that lock is released.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
   */
1712ac8fd   Al Viro   Saner locking aro...
243
  void deactivate_locked_super(struct super_block *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
  {
  	struct file_system_type *fs = s->s_type;
b20bd1a5e   Al Viro   get rid of S_BIAS
246
  	if (atomic_dec_and_test(&s->s_active)) {
c515e1fd3   Dan Magenheimer   mm/fs: add hooks ...
247
  		cleancache_flush_fs(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
  		fs->kill_sb(s);
b0d40c92a   Dave Chinner   superblock: intro...
249
250
251
  
  		/* caches are now gone, we can safely kill the shrinker now */
  		unregister_shrinker(&s->s_shrink);
d863b50ab   Boaz Harrosh   vfs: call rcu_bar...
252
253
254
255
256
  		/*
  		 * 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
257
258
  		put_filesystem(fs);
  		put_super(s);
1712ac8fd   Al Viro   Saner locking aro...
259
260
  	} else {
  		up_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
  	}
  }
1712ac8fd   Al Viro   Saner locking aro...
263
  EXPORT_SYMBOL(deactivate_locked_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
265
  
  /**
1712ac8fd   Al Viro   Saner locking aro...
266
   *	deactivate_super	-	drop an active reference to superblock
74dbbdd7f   Al Viro   New helper: deact...
267
268
   *	@s: superblock to deactivate
   *
1712ac8fd   Al Viro   Saner locking aro...
269
270
271
   *	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...
272
   */
1712ac8fd   Al Viro   Saner locking aro...
273
  void deactivate_super(struct super_block *s)
74dbbdd7f   Al Viro   New helper: deact...
274
  {
1712ac8fd   Al Viro   Saner locking aro...
275
276
277
          if (!atomic_add_unless(&s->s_active, -1, 1)) {
  		down_write(&s->s_umount);
  		deactivate_locked_super(s);
74dbbdd7f   Al Viro   New helper: deact...
278
279
  	}
  }
1712ac8fd   Al Viro   Saner locking aro...
280
  EXPORT_SYMBOL(deactivate_super);
74dbbdd7f   Al Viro   New helper: deact...
281
282
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
285
286
287
288
289
290
291
292
   *	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...
293
  static int grab_super(struct super_block *s) __releases(sb_lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
  {
b20bd1a5e   Al Viro   get rid of S_BIAS
295
296
  	if (atomic_inc_not_zero(&s->s_active)) {
  		spin_unlock(&sb_lock);
b20bd1a5e   Al Viro   get rid of S_BIAS
297
298
299
  		return 1;
  	}
  	/* it's going away */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
  	s->s_count++;
  	spin_unlock(&sb_lock);
1712ac8fd   Al Viro   Saner locking aro...
302
  	/* wait for it to die */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	down_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
  	up_write(&s->s_umount);
  	put_super(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
  	return 0;
  }
cf9a2ae8d   David Howells   [PATCH] BLOCK: Mo...
308
  /*
12ad3ab66   Dave Chinner   superblock: move ...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
   *	grab_super_passive - acquire a passive reference
   *	@s: reference we are trying to grab
   *
   *	Tries to acquire a passive reference. This is used in places where we
   *	cannot take an active reference but we need to ensure that the
   *	superblock does not go away while we are working on it. It returns
   *	false if a reference was not gained, and returns true with the s_umount
   *	lock held in read mode if a reference is gained. On successful return,
   *	the caller must drop the s_umount lock and the passive reference when
   *	done.
   */
  bool grab_super_passive(struct super_block *sb)
  {
  	spin_lock(&sb_lock);
a5166169f   Al Viro   vfs: convert fs_s...
323
  	if (hlist_unhashed(&sb->s_instances)) {
12ad3ab66   Dave Chinner   superblock: move ...
324
325
326
327
328
329
330
331
  		spin_unlock(&sb_lock);
  		return false;
  	}
  
  	sb->s_count++;
  	spin_unlock(&sb_lock);
  
  	if (down_read_trylock(&sb->s_umount)) {
dabe0dc19   Al Viro   vfs: fix the rest...
332
  		if (sb->s_root && (sb->s_flags & MS_BORN))
12ad3ab66   Dave Chinner   superblock: move ...
333
334
335
336
337
338
339
340
341
  			return true;
  		up_read(&sb->s_umount);
  	}
  
  	put_super(sb);
  	return false;
  }
  
  /*
914e26379   Al Viro   [PATCH] severing ...
342
343
344
345
   * Superblock locking.  We really ought to get rid of these two.
   */
  void lock_super(struct super_block * sb)
  {
914e26379   Al Viro   [PATCH] severing ...
346
347
348
349
350
  	mutex_lock(&sb->s_lock);
  }
  
  void unlock_super(struct super_block * sb)
  {
914e26379   Al Viro   [PATCH] severing ...
351
352
353
354
355
  	mutex_unlock(&sb->s_lock);
  }
  
  EXPORT_SYMBOL(lock_super);
  EXPORT_SYMBOL(unlock_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
357
358
359
360
361
362
363
364
  /**
   *	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...
365
366
367
368
   *
   *	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
369
370
371
   */
  void generic_shutdown_super(struct super_block *sb)
  {
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
372
  	const struct super_operations *sop = sb->s_op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373

c636ebdb1   David Howells   [PATCH] VFS: Dest...
374
375
  	if (sb->s_root) {
  		shrink_dcache_for_umount(sb);
60b0680fa   Jan Kara   vfs: Rename fsync...
376
  		sync_filesystem(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  		sb->s_flags &= ~MS_ACTIVE;
efaee1920   Arjan van de Ven   async: make the f...
378

63997e98a   Al Viro   split invalidate_...
379
380
381
  		fsnotify_unmount_inodes(&sb->s_inodes);
  
  		evict_inodes(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
  		if (sop->put_super)
  			sop->put_super(sb);
63997e98a   Al Viro   split invalidate_...
385
  		if (!list_empty(&sb->s_inodes)) {
7b4fe29e0   Dave Jones   [PATCH] More info...
386
387
388
389
  			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
390
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
393
  	}
  	spin_lock(&sb_lock);
  	/* should be initialized for __put_super_and_need_restart() */
a5166169f   Al Viro   vfs: convert fs_s...
394
  	hlist_del_init(&sb->s_instances);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
  	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;
a5166169f   Al Viro   vfs: convert fs_s...
414
  	struct hlist_node *node;
d47301271   Matthias Kaehlcke   fs/super.c: use l...
415
  	struct super_block *old;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
419
  	int err;
  
  retry:
  	spin_lock(&sb_lock);
d47301271   Matthias Kaehlcke   fs/super.c: use l...
420
  	if (test) {
a5166169f   Al Viro   vfs: convert fs_s...
421
  		hlist_for_each_entry(old, node, &type->fs_supers, s_instances) {
d47301271   Matthias Kaehlcke   fs/super.c: use l...
422
423
424
425
  			if (!test(old, data))
  				continue;
  			if (!grab_super(old))
  				goto retry;
a3cfbb53b   Li Zefan   vfs: add missing ...
426
427
  			if (s) {
  				up_write(&s->s_umount);
d47301271   Matthias Kaehlcke   fs/super.c: use l...
428
  				destroy_super(s);
7a4dec538   Al Viro   Fix sget() race w...
429
  				s = NULL;
a3cfbb53b   Li Zefan   vfs: add missing ...
430
  			}
d3f214730   Al Viro   Move grabbing s_u...
431
  			down_write(&old->s_umount);
7a4dec538   Al Viro   Fix sget() race w...
432
433
434
435
  			if (unlikely(!(old->s_flags & MS_BORN))) {
  				deactivate_locked_super(old);
  				goto retry;
  			}
d47301271   Matthias Kaehlcke   fs/super.c: use l...
436
437
  			return old;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
  	}
  	if (!s) {
  		spin_unlock(&sb_lock);
cf5162499   Ingo Molnar   [PATCH] lockdep: ...
441
  		s = alloc_super(type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
445
446
447
448
449
  		if (!s)
  			return ERR_PTR(-ENOMEM);
  		goto retry;
  	}
  		
  	err = set(s, data);
  	if (err) {
  		spin_unlock(&sb_lock);
a3cfbb53b   Li Zefan   vfs: add missing ...
450
  		up_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
454
455
456
  		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);
a5166169f   Al Viro   vfs: convert fs_s...
457
  	hlist_add_head(&s->s_instances, &type->fs_supers);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
459
  	spin_unlock(&sb_lock);
  	get_filesystem(type);
b0d40c92a   Dave Chinner   superblock: intro...
460
  	register_shrinker(&s->s_shrink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
462
463
464
465
466
467
468
469
470
471
472
  	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
473
474
475
476
477
478
479
480
  /**
   * 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
481
482
483
484
485
486
   * 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_...
487
  	struct super_block *sb, *p = NULL;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
488

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
490
  	list_for_each_entry(sb, &super_blocks, s_list) {
a5166169f   Al Viro   vfs: convert fs_s...
491
  		if (hlist_unhashed(&sb->s_instances))
551de6f34   Al Viro   Leave superblocks...
492
  			continue;
e50047533   Christoph Hellwig   cleanup sync_supers
493
  		if (sb->s_op->write_super && sb->s_dirt) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
  			sb->s_count++;
  			spin_unlock(&sb_lock);
e50047533   Christoph Hellwig   cleanup sync_supers
496

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
  			down_read(&sb->s_umount);
dabe0dc19   Al Viro   vfs: fix the rest...
498
  			if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN))
e50047533   Christoph Hellwig   cleanup sync_supers
499
  				sb->s_op->write_super(sb);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
500
  			up_read(&sb->s_umount);
e50047533   Christoph Hellwig   cleanup sync_supers
501

618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
502
  			spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
503
504
505
  			if (p)
  				__put_super(p);
  			p = sb;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
506
507
  		}
  	}
dca332528   Al Viro   no need for list_...
508
509
  	if (p)
  		__put_super(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
  	spin_unlock(&sb_lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  /**
01a05b337   Al Viro   new helper: itera...
513
514
515
516
517
518
519
520
521
   *	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_...
522
  	struct super_block *sb, *p = NULL;
01a05b337   Al Viro   new helper: itera...
523
524
  
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
525
  	list_for_each_entry(sb, &super_blocks, s_list) {
a5166169f   Al Viro   vfs: convert fs_s...
526
  		if (hlist_unhashed(&sb->s_instances))
01a05b337   Al Viro   new helper: itera...
527
528
529
530
531
  			continue;
  		sb->s_count++;
  		spin_unlock(&sb_lock);
  
  		down_read(&sb->s_umount);
dabe0dc19   Al Viro   vfs: fix the rest...
532
  		if (sb->s_root && (sb->s_flags & MS_BORN))
01a05b337   Al Viro   new helper: itera...
533
534
535
536
  			f(sb, arg);
  		up_read(&sb->s_umount);
  
  		spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
537
538
539
  		if (p)
  			__put_super(p);
  		p = sb;
01a05b337   Al Viro   new helper: itera...
540
  	}
dca332528   Al Viro   no need for list_...
541
542
  	if (p)
  		__put_super(p);
01a05b337   Al Viro   new helper: itera...
543
544
545
546
  	spin_unlock(&sb_lock);
  }
  
  /**
43e15cdbe   Al Viro   new helper: itera...
547
548
549
550
551
552
553
554
555
556
557
558
   *	iterate_supers_type - call function for superblocks of given type
   *	@type: fs type
   *	@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_type(struct file_system_type *type,
  	void (*f)(struct super_block *, void *), void *arg)
  {
  	struct super_block *sb, *p = NULL;
a5166169f   Al Viro   vfs: convert fs_s...
559
  	struct hlist_node *node;
43e15cdbe   Al Viro   new helper: itera...
560
561
  
  	spin_lock(&sb_lock);
a5166169f   Al Viro   vfs: convert fs_s...
562
  	hlist_for_each_entry(sb, node, &type->fs_supers, s_instances) {
43e15cdbe   Al Viro   new helper: itera...
563
564
565
566
  		sb->s_count++;
  		spin_unlock(&sb_lock);
  
  		down_read(&sb->s_umount);
dabe0dc19   Al Viro   vfs: fix the rest...
567
  		if (sb->s_root && (sb->s_flags & MS_BORN))
43e15cdbe   Al Viro   new helper: itera...
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  			f(sb, arg);
  		up_read(&sb->s_umount);
  
  		spin_lock(&sb_lock);
  		if (p)
  			__put_super(p);
  		p = sb;
  	}
  	if (p)
  		__put_super(p);
  	spin_unlock(&sb_lock);
  }
  
  EXPORT_SYMBOL(iterate_supers_type);
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584
585
586
587
588
589
   *	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...
590
  struct super_block *get_super(struct block_device *bdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
  {
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
592
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
  	if (!bdev)
  		return NULL;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
595

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
  	spin_lock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
597
598
  rescan:
  	list_for_each_entry(sb, &super_blocks, s_list) {
a5166169f   Al Viro   vfs: convert fs_s...
599
  		if (hlist_unhashed(&sb->s_instances))
551de6f34   Al Viro   Leave superblocks...
600
  			continue;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
601
602
  		if (sb->s_bdev == bdev) {
  			sb->s_count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
  			spin_unlock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
604
  			down_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
605
  			/* still alive? */
dabe0dc19   Al Viro   vfs: fix the rest...
606
  			if (sb->s_root && (sb->s_flags & MS_BORN))
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
607
608
  				return sb;
  			up_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
609
  			/* nope, got unmounted */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
610
  			spin_lock(&sb_lock);
df40c01a9   Al Viro   In get_super() an...
611
612
  			__put_super(sb);
  			goto rescan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
614
615
616
617
618
619
  		}
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
  
  EXPORT_SYMBOL(get_super);
4504230a7   Christoph Hellwig   freeze_bdev: grab...
620
621
622
623
624
625
626
  
  /**
   * 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...
627
   * reference or %NULL if none was found.
4504230a7   Christoph Hellwig   freeze_bdev: grab...
628
629
630
631
632
633
634
   */
  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...
635
  restart:
4504230a7   Christoph Hellwig   freeze_bdev: grab...
636
637
  	spin_lock(&sb_lock);
  	list_for_each_entry(sb, &super_blocks, s_list) {
a5166169f   Al Viro   vfs: convert fs_s...
638
  		if (hlist_unhashed(&sb->s_instances))
551de6f34   Al Viro   Leave superblocks...
639
  			continue;
1494583de   Al Viro   fix get_active_su...
640
641
642
643
644
645
  		if (sb->s_bdev == bdev) {
  			if (grab_super(sb)) /* drops sb_lock */
  				return sb;
  			else
  				goto restart;
  		}
4504230a7   Christoph Hellwig   freeze_bdev: grab...
646
647
648
649
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
   
df40c01a9   Al Viro   In get_super() an...
651
  struct super_block *user_get_super(dev_t dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
  {
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
653
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
  	spin_lock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
656
657
  rescan:
  	list_for_each_entry(sb, &super_blocks, s_list) {
a5166169f   Al Viro   vfs: convert fs_s...
658
  		if (hlist_unhashed(&sb->s_instances))
551de6f34   Al Viro   Leave superblocks...
659
  			continue;
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
660
661
  		if (sb->s_dev ==  dev) {
  			sb->s_count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  			spin_unlock(&sb_lock);
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
663
  			down_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
664
  			/* still alive? */
dabe0dc19   Al Viro   vfs: fix the rest...
665
  			if (sb->s_root && (sb->s_flags & MS_BORN))
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
666
667
  				return sb;
  			up_read(&sb->s_umount);
df40c01a9   Al Viro   In get_super() an...
668
  			/* nope, got unmounted */
618f06362   Kirill Korotaev   [PATCH] O(1) sb l...
669
  			spin_lock(&sb_lock);
df40c01a9   Al Viro   In get_super() an...
670
671
  			__put_super(sb);
  			goto rescan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
674
675
676
  		}
  	}
  	spin_unlock(&sb_lock);
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
679
680
681
682
683
684
685
686
687
688
   *	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...
689
  	int remount_ro;
4504230a7   Christoph Hellwig   freeze_bdev: grab...
690
691
692
  
  	if (sb->s_frozen != SB_UNFROZEN)
  		return -EBUSY;
9361401eb   David Howells   [PATCH] BLOCK: Ma...
693
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
695
  	if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
  		return -EACCES;
9361401eb   David Howells   [PATCH] BLOCK: Ma...
696
  #endif
4504230a7   Christoph Hellwig   freeze_bdev: grab...
697

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
699
700
  	if (flags & MS_RDONLY)
  		acct_auto_close(sb);
  	shrink_dcache_sb(sb);
60b0680fa   Jan Kara   vfs: Rename fsync...
701
  	sync_filesystem(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
706
  	/* 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...
707
  	if (remount_ro) {
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
708
  		if (force) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  			mark_files_ro(sb);
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
710
711
712
713
  		} else {
  			retval = sb_prepare_remount_readonly(sb);
  			if (retval)
  				return retval;
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
714
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
716
717
  	}
  
  	if (sb->s_op->remount_fs) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718
  		retval = sb->s_op->remount_fs(sb, &flags, data);
2833eb2b4   Miklos Szeredi   vfs: ignore error...
719
720
  		if (retval) {
  			if (!force)
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
721
  				goto cancel_readonly;
2833eb2b4   Miklos Szeredi   vfs: ignore error...
722
723
724
725
726
  			/* If forced remount, go ahead despite any errors */
  			WARN(1, "forced remount of a %s fs returned %i
  ",
  			     sb->s_type->name, retval);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
  	}
  	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
729
730
731
  	/* Needs to be ordered wrt mnt_is_readonly() */
  	smp_wmb();
  	sb->s_readonly_remount = 0;
c79d967de   Christoph Hellwig   quota: move remou...
732

d208bbdda   Nick Piggin   fs: improve remou...
733
734
735
736
737
738
739
740
741
742
  	/*
  	 * 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
743
  	return 0;
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
744
745
746
747
  
  cancel_readonly:
  	sb->s_readonly_remount = 0;
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
  }
a2a9537ac   Jens Axboe   Get rid of pdflus...
749
  static void do_emergency_remount(struct work_struct *work)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
  {
dca332528   Al Viro   no need for list_...
751
  	struct super_block *sb, *p = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
  
  	spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
754
  	list_for_each_entry(sb, &super_blocks, s_list) {
a5166169f   Al Viro   vfs: convert fs_s...
755
  		if (hlist_unhashed(&sb->s_instances))
551de6f34   Al Viro   Leave superblocks...
756
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
  		sb->s_count++;
  		spin_unlock(&sb_lock);
443b94baa   Al Viro   Make sure that al...
759
  		down_write(&sb->s_umount);
dabe0dc19   Al Viro   vfs: fix the rest...
760
761
  		if (sb->s_root && sb->s_bdev && (sb->s_flags & MS_BORN) &&
  		    !(sb->s_flags & MS_RDONLY)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
  			/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
763
764
  			 * What lock protects sb->s_flags??
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765
  			do_remount_sb(sb, MS_RDONLY, NULL, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
  		}
443b94baa   Al Viro   Make sure that al...
767
  		up_write(&sb->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
768
  		spin_lock(&sb_lock);
dca332528   Al Viro   no need for list_...
769
770
771
  		if (p)
  			__put_super(p);
  		p = sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
772
  	}
dca332528   Al Viro   no need for list_...
773
774
  	if (p)
  		__put_super(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
  	spin_unlock(&sb_lock);
a2a9537ac   Jens Axboe   Get rid of pdflus...
776
  	kfree(work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
778
779
780
781
782
  	printk("Emergency Remount complete
  ");
  }
  
  void emergency_remount(void)
  {
a2a9537ac   Jens Axboe   Get rid of pdflus...
783
784
785
786
787
788
789
  	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
790
791
792
793
794
795
  }
  
  /*
   * 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...
796
  static DEFINE_IDA(unnamed_dev_ida);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
  static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
c63e09ecc   Al Viro   Make allocation o...
798
  static int unnamed_dev_start = 0; /* don't bother trying below it */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799

0ee5dc676   Al Viro   btrfs: kill magic...
800
  int get_anon_bdev(dev_t *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
802
803
804
805
  {
  	int dev;
  	int error;
  
   retry:
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
806
  	if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
807
808
  		return -ENOMEM;
  	spin_lock(&unnamed_dev_lock);
c63e09ecc   Al Viro   Make allocation o...
809
  	error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev);
f21f62208   Al Viro   ... and the same ...
810
811
  	if (!error)
  		unnamed_dev_start = dev + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
813
814
815
816
817
818
819
820
  	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...
821
  		ida_remove(&unnamed_dev_ida, dev);
f21f62208   Al Viro   ... and the same ...
822
823
  		if (unnamed_dev_start > dev)
  			unnamed_dev_start = dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824
825
826
  		spin_unlock(&unnamed_dev_lock);
  		return -EMFILE;
  	}
0ee5dc676   Al Viro   btrfs: kill magic...
827
  	*p = MKDEV(0, dev & MINORMASK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
  	return 0;
  }
0ee5dc676   Al Viro   btrfs: kill magic...
830
  EXPORT_SYMBOL(get_anon_bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831

0ee5dc676   Al Viro   btrfs: kill magic...
832
  void free_anon_bdev(dev_t dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  {
0ee5dc676   Al Viro   btrfs: kill magic...
834
  	int slot = MINOR(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
  	spin_lock(&unnamed_dev_lock);
ad76cbc63   Alexey Dobriyan   [PATCH 2/2] anond...
836
  	ida_remove(&unnamed_dev_ida, slot);
c63e09ecc   Al Viro   Make allocation o...
837
838
  	if (slot < unnamed_dev_start)
  		unnamed_dev_start = slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
840
  	spin_unlock(&unnamed_dev_lock);
  }
0ee5dc676   Al Viro   btrfs: kill magic...
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
  EXPORT_SYMBOL(free_anon_bdev);
  
  int set_anon_super(struct super_block *s, void *data)
  {
  	int error = get_anon_bdev(&s->s_dev);
  	if (!error)
  		s->s_bdi = &noop_backing_dev_info;
  	return error;
  }
  
  EXPORT_SYMBOL(set_anon_super);
  
  void kill_anon_super(struct super_block *sb)
  {
  	dev_t dev = sb->s_dev;
  	generic_shutdown_super(sb);
  	free_anon_bdev(dev);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
860
  
  EXPORT_SYMBOL(kill_anon_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
862
863
864
865
866
867
868
  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 ...
869
870
871
872
873
874
875
876
877
878
  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(...
879
880
  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 ...
881
882
883
884
885
  {
  	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(...
886
  		return ERR_CAST(sb);
909e6d947   Serge E. Hallyn   namespaces: move ...
887
888
889
890
891
892
  
  	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...
893
  			deactivate_locked_super(sb);
ceefda693   Al Viro   switch get_sb_ns(...
894
  			return ERR_PTR(err);
909e6d947   Serge E. Hallyn   namespaces: move ...
895
896
897
898
  		}
  
  		sb->s_flags |= MS_ACTIVE;
  	}
ceefda693   Al Viro   switch get_sb_ns(...
899
  	return dget(sb->s_root);
909e6d947   Serge E. Hallyn   namespaces: move ...
900
  }
ceefda693   Al Viro   switch get_sb_ns(...
901
  EXPORT_SYMBOL(mount_ns);
909e6d947   Serge E. Hallyn   namespaces: move ...
902

9361401eb   David Howells   [PATCH] BLOCK: Ma...
903
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904
905
906
907
  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...
908
909
910
911
912
913
  
  	/*
  	 * 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
914
915
916
917
918
919
920
  	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...
921
  struct dentry *mount_bdev(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
  	int flags, const char *dev_name, void *data,
152a08366   Al Viro   new helper: mount...
923
  	int (*fill_super)(struct super_block *, void *, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
924
925
926
  {
  	struct block_device *bdev;
  	struct super_block *s;
d4d776299   Tejun Heo   block: clean up b...
927
  	fmode_t mode = FMODE_READ | FMODE_EXCL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
  	int error = 0;
30c40d2c0   Al Viro   [PATCH] propagate...
929
930
  	if (!(flags & MS_RDONLY))
  		mode |= FMODE_WRITE;
d4d776299   Tejun Heo   block: clean up b...
931
  	bdev = blkdev_get_by_path(dev_name, mode, fs_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
  	if (IS_ERR(bdev))
152a08366   Al Viro   new helper: mount...
933
  		return ERR_CAST(bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
935
936
937
938
939
  
  	/*
  	 * 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...
940
941
942
943
944
945
  	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
946
  	s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
4fadd7bb2   Christoph Hellwig   freeze_bdev: kill...
947
  	mutex_unlock(&bdev->bd_fsfreeze_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
948
  	if (IS_ERR(s))
454e2398b   David Howells   [PATCH] VFS: Perm...
949
  		goto error_s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
951
952
  
  	if (s->s_root) {
  		if ((flags ^ s->s_flags) & MS_RDONLY) {
74dbbdd7f   Al Viro   New helper: deact...
953
  			deactivate_locked_super(s);
454e2398b   David Howells   [PATCH] VFS: Perm...
954
955
  			error = -EBUSY;
  			goto error_bdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
  		}
454e2398b   David Howells   [PATCH] VFS: Perm...
957

4f331f01b   Tejun Heo   vfs: don't hold s...
958
959
  		/*
  		 * s_umount nests inside bd_mutex during
e525fd89d   Tejun Heo   block: make blkde...
960
961
962
963
  		 * __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...
964
965
  		 */
  		up_write(&s->s_umount);
d4d776299   Tejun Heo   block: clean up b...
966
  		blkdev_put(bdev, mode);
4f331f01b   Tejun Heo   vfs: don't hold s...
967
  		down_write(&s->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
969
  	} else {
  		char b[BDEVNAME_SIZE];
9e1f1de02   Al Viro   more conservative...
970
  		s->s_flags = flags | MS_NOSEC;
30c40d2c0   Al Viro   [PATCH] propagate...
971
  		s->s_mode = mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
972
  		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
e78c9a004   Pekka Enberg   [PATCH] fs: remov...
973
  		sb_set_blocksize(s, block_size(bdev));
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
974
  		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  		if (error) {
74dbbdd7f   Al Viro   New helper: deact...
976
  			deactivate_locked_super(s);
454e2398b   David Howells   [PATCH] VFS: Perm...
977
  			goto error;
fa675765a   Greg Kroah-Hartman   Revert mount/umou...
978
  		}
454e2398b   David Howells   [PATCH] VFS: Perm...
979
980
  
  		s->s_flags |= MS_ACTIVE;
87d8fe1ee   Theodore Ts'o   add releasepage h...
981
  		bdev->bd_super = s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
982
  	}
152a08366   Al Viro   new helper: mount...
983
  	return dget(s->s_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984

454e2398b   David Howells   [PATCH] VFS: Perm...
985
986
987
  error_s:
  	error = PTR_ERR(s);
  error_bdev:
d4d776299   Tejun Heo   block: clean up b...
988
  	blkdev_put(bdev, mode);
454e2398b   David Howells   [PATCH] VFS: Perm...
989
  error:
152a08366   Al Viro   new helper: mount...
990
991
992
  	return ERR_PTR(error);
  }
  EXPORT_SYMBOL(mount_bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
994
995
  void kill_block_super(struct super_block *sb)
  {
  	struct block_device *bdev = sb->s_bdev;
30c40d2c0   Al Viro   [PATCH] propagate...
996
  	fmode_t mode = sb->s_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997

ddbaaf302   H Hartley Sweeten   NULL noise in fs/...
998
  	bdev->bd_super = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
1000
  	generic_shutdown_super(sb);
  	sync_blockdev(bdev);
d4d776299   Tejun Heo   block: clean up b...
1001
  	WARN_ON_ONCE(!(mode & FMODE_EXCL));
e525fd89d   Tejun Heo   block: make blkde...
1002
  	blkdev_put(bdev, mode | FMODE_EXCL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
1005
  }
  
  EXPORT_SYMBOL(kill_block_super);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
1006
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007

3c26ff6e4   Al Viro   convert get_sb_no...
1008
  struct dentry *mount_nodev(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
  	int flags, void *data,
3c26ff6e4   Al Viro   convert get_sb_no...
1010
  	int (*fill_super)(struct super_block *, void *, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
1012
1013
1014
1015
  {
  	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...
1016
  		return ERR_CAST(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
  
  	s->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
1019
  	error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1020
  	if (error) {
74dbbdd7f   Al Viro   New helper: deact...
1021
  		deactivate_locked_super(s);
3c26ff6e4   Al Viro   convert get_sb_no...
1022
  		return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
1024
  	}
  	s->s_flags |= MS_ACTIVE;
3c26ff6e4   Al Viro   convert get_sb_no...
1025
  	return dget(s->s_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
  }
3c26ff6e4   Al Viro   convert get_sb_no...
1027
  EXPORT_SYMBOL(mount_nodev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1028
1029
1030
1031
  static int compare_single(struct super_block *s, void *p)
  {
  	return 1;
  }
fc14f2fef   Al Viro   convert get_sb_si...
1032
  struct dentry *mount_single(struct file_system_type *fs_type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
  	int flags, void *data,
fc14f2fef   Al Viro   convert get_sb_si...
1034
  	int (*fill_super)(struct super_block *, void *, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
1036
1037
1038
1039
1040
  {
  	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...
1041
  		return ERR_CAST(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1042
1043
  	if (!s->s_root) {
  		s->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
1044
  		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  		if (error) {
74dbbdd7f   Al Viro   New helper: deact...
1046
  			deactivate_locked_super(s);
fc14f2fef   Al Viro   convert get_sb_si...
1047
  			return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1048
1049
  		}
  		s->s_flags |= MS_ACTIVE;
9329d1bea   Kay Sievers   vfs: get_sb_singl...
1050
1051
  	} else {
  		do_remount_sb(s, flags, data, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1052
  	}
fc14f2fef   Al Viro   convert get_sb_si...
1053
1054
1055
  	return dget(s->s_root);
  }
  EXPORT_SYMBOL(mount_single);
9d412a43c   Al Viro   vfs: split off vf...
1056
1057
  struct dentry *
  mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1058
  {
c96e41e92   Al Viro   beginning of tran...
1059
  	struct dentry *root;
9d412a43c   Al Viro   vfs: split off vf...
1060
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
  	char *secdata = NULL;
9d412a43c   Al Viro   vfs: split off vf...
1062
  	int error = -ENOMEM;
8089352a1   Al Viro   Mirror MS_KERNMOU...
1063

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

e00075298   Eric Paris   LSM/SELinux: Inte...
1069
  		error = security_sb_copy_data(data, secdata);
454e2398b   David Howells   [PATCH] VFS: Perm...
1070
  		if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
  			goto out_free_secdata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1072
  	}
1a102ff92   Al Viro   vfs: bury ->get_sb()
1073
1074
1075
1076
  	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...
1077
  	}
9d412a43c   Al Viro   vfs: split off vf...
1078
1079
1080
  	sb = root->d_sb;
  	BUG_ON(!sb);
  	WARN_ON(!sb->s_bdi);
6c5103890   Linus Torvalds   Merge branch 'for...
1081
  	WARN_ON(sb->s_bdi == &default_backing_dev_info);
9d412a43c   Al Viro   vfs: split off vf...
1082
  	sb->s_flags |= MS_BORN;
454e2398b   David Howells   [PATCH] VFS: Perm...
1083

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

42cb56ae2   Jeff Layton   vfs: change sb->s...
1088
1089
1090
1091
  	/*
  	 * 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
4358b5678   Jeff Layton   VFS: trivial: fix...
1092
  	 * violate this rule.
42cb56ae2   Jeff Layton   vfs: change sb->s...
1093
  	 */
9d412a43c   Al Viro   vfs: split off vf...
1094
1095
1096
  	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...
1097

9d412a43c   Al Viro   vfs: split off vf...
1098
  	up_write(&sb->s_umount);
8680e22f2   Gerald Schaefer   [PATCH] VFS: memo...
1099
  	free_secdata(secdata);
9d412a43c   Al Viro   vfs: split off vf...
1100
  	return root;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
  out_sb:
9d412a43c   Al Viro   vfs: split off vf...
1102
1103
  	dput(root);
  	deactivate_locked_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104
1105
  out_free_secdata:
  	free_secdata(secdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106
  out:
454e2398b   David Howells   [PATCH] VFS: Perm...
1107
  	return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1108
  }
18e9e5104   Josef Bacik   Introduce freeze_...
1109
  /**
7000d3c42   Randy Dunlap   fs/super: fix ker...
1110
1111
   * freeze_super - lock the filesystem and force it into a consistent state
   * @sb: the super to lock
18e9e5104   Josef Bacik   Introduce freeze_...
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
   *
   * 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;
  	}
dabe0dc19   Al Viro   vfs: fix the rest...
1127
1128
1129
1130
  	if (!(sb->s_flags & MS_BORN)) {
  		up_write(&sb->s_umount);
  		return 0;	/* sic - it's "nothing to do" */
  	}
18e9e5104   Josef Bacik   Introduce freeze_...
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
  	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);