aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/super.c b/fs/super.c
index 73ab9f9b3571..e63c754447ce 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -243,6 +243,39 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
243} 243}
244 244
245/* 245/*
246 * grab_super_passive - acquire a passive reference
247 * @s: reference we are trying to grab
248 *
249 * Tries to acquire a passive reference. This is used in places where we
250 * cannot take an active reference but we need to ensure that the
251 * superblock does not go away while we are working on it. It returns
252 * false if a reference was not gained, and returns true with the s_umount
253 * lock held in read mode if a reference is gained. On successful return,
254 * the caller must drop the s_umount lock and the passive reference when
255 * done.
256 */
257bool grab_super_passive(struct super_block *sb)
258{
259 spin_lock(&sb_lock);
260 if (list_empty(&sb->s_instances)) {
261 spin_unlock(&sb_lock);
262 return false;
263 }
264
265 sb->s_count++;
266 spin_unlock(&sb_lock);
267
268 if (down_read_trylock(&sb->s_umount)) {
269 if (sb->s_root)
270 return true;
271 up_read(&sb->s_umount);
272 }
273
274 put_super(sb);
275 return false;
276}
277
278/*
246 * Superblock locking. We really ought to get rid of these two. 279 * Superblock locking. We really ought to get rid of these two.
247 */ 280 */
248void lock_super(struct super_block * sb) 281void lock_super(struct super_block * sb)