Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0200894d authored by Al Viro's avatar Al Viro
Browse files

new helper: destroy_unused_super()



Used for disposal of super_block instances that had never been reachable
via any shared data structures.  No need for RCU delay in there, everything
can be called directly.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 6aa211e8
Loading
Loading
Loading
Loading
+19 −12
Original line number Diff line number Diff line
@@ -171,6 +171,21 @@ static void destroy_super(struct super_block *s)
	call_rcu(&s->rcu, destroy_super_rcu);
}

/* Free a superblock that has never been seen by anyone */
static void destroy_unused_super(struct super_block *s)
{
	if (!s)
		return;
	up_write(&s->s_umount);
	list_lru_destroy(&s->s_dentry_lru);
	list_lru_destroy(&s->s_inode_lru);
	security_sb_free(s);
	put_user_ns(s->s_user_ns);
	kfree(s->s_subtype);
	/* no delays needed */
	destroy_super_work(&s->destroy_work);
}

/**
 *	alloc_super	-	create new superblock
 *	@type:	filesystem type superblock should belong to
@@ -256,7 +271,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
	return s;

fail:
	destroy_super(s);
	destroy_unused_super(s);
	return NULL;
}

@@ -484,19 +499,12 @@ struct super_block *sget_userns(struct file_system_type *type,
				continue;
			if (user_ns != old->s_user_ns) {
				spin_unlock(&sb_lock);
				if (s) {
					up_write(&s->s_umount);
					destroy_super(s);
				}
				destroy_unused_super(s);
				return ERR_PTR(-EBUSY);
			}
			if (!grab_super(old))
				goto retry;
			if (s) {
				up_write(&s->s_umount);
				destroy_super(s);
				s = NULL;
			}
			destroy_unused_super(s);
			return old;
		}
	}
@@ -511,8 +519,7 @@ struct super_block *sget_userns(struct file_system_type *type,
	err = set(s, data);
	if (err) {
		spin_unlock(&sb_lock);
		up_write(&s->s_umount);
		destroy_super(s);
		destroy_unused_super(s);
		return ERR_PTR(err);
	}
	s->s_type = type;