diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-08-07 13:53:41 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-08-07 13:53:41 +0200 |
commit | 6ac7ada210a8d23a56fbf18b6e1e00528844565c (patch) | |
tree | f62352a9b08e560f41cd4008ec0029b6b026d3a5 /fs/namespace.c | |
parent | 73851b36fe73819f8c201971e913324d4846a7ea (diff) | |
parent | d00a9e02178401433fc386e69c936f2039f07b57 (diff) | |
download | lwn-6ac7ada210a8d23a56fbf18b6e1e00528844565c.tar.gz lwn-6ac7ada210a8d23a56fbf18b6e1e00528844565c.zip |
Merge tag 'asoc-fix-v4.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v4.2
There are a couple of small driver specific fixes here but the
overwhelming bulk of these changes are fixes to the topology ABI that
has been newly introduced in v4.2. Once this makes it into a release we
will have to firm this up but for now getting enhancements in before
they've made it into a release is the most expedient thing.
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index c7cb8a526c05..2b8aa15fd6df 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1361,6 +1361,36 @@ enum umount_tree_flags { UMOUNT_PROPAGATE = 2, UMOUNT_CONNECTED = 4, }; + +static bool disconnect_mount(struct mount *mnt, enum umount_tree_flags how) +{ + /* Leaving mounts connected is only valid for lazy umounts */ + if (how & UMOUNT_SYNC) + return true; + + /* A mount without a parent has nothing to be connected to */ + if (!mnt_has_parent(mnt)) + return true; + + /* Because the reference counting rules change when mounts are + * unmounted and connected, umounted mounts may not be + * connected to mounted mounts. + */ + if (!(mnt->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) + return true; + + /* Has it been requested that the mount remain connected? */ + if (how & UMOUNT_CONNECTED) + return false; + + /* Is the mount locked such that it needs to remain connected? */ + if (IS_MNT_LOCKED(mnt)) + return false; + + /* By default disconnect the mount */ + return true; +} + /* * mount_lock must be held * namespace_sem must be held for write @@ -1398,10 +1428,7 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) if (how & UMOUNT_SYNC) p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; - disconnect = !(((how & UMOUNT_CONNECTED) && - mnt_has_parent(p) && - (p->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) || - IS_MNT_LOCKED_AND_LAZY(p)); + disconnect = disconnect_mount(p, how); pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, disconnect ? &unmounted : NULL); @@ -1538,11 +1565,8 @@ void __detach_mounts(struct dentry *dentry) while (!hlist_empty(&mp->m_list)) { mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); if (mnt->mnt.mnt_flags & MNT_UMOUNT) { - struct mount *p, *tmp; - list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts, mnt_child) { - hlist_add_head(&p->mnt_umount.s_list, &unmounted); - umount_mnt(p); - } + hlist_add_head(&mnt->mnt_umount.s_list, &unmounted); + umount_mnt(mnt); } else umount_tree(mnt, UMOUNT_CONNECTED); } |