Commit 81b6b06197606b4bef4e427a197aeb808e8d89e1

Authored by Al Viro
1 parent 88b368f27a

fix EBUSY on umount() from MNT_SHRINKABLE

We need the parents of victims alive until namespace_unlock() gets to
dput() of the (ex-)mountpoints.  However, that screws up the "is it
busy" checks in case when we have shrinkable mounts that need to be
killed.  Solution: go ahead and decrement refcounts of parents right
in umount_tree(), increment them again just before dropping rwsem in
namespace_unlock() (and let the loop in the end of namespace_unlock()
finally drop those references for good, as we do now).  Parents can't
get freed until we drop rwsem - at least one reference is kept until
then, both in case when parent is among the victims and when it is
not.  So they'll still be around when we get to namespace_unlock().

Cc: stable@vger.kernel.org # 3.12+
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 6 additions and 0 deletions Side-by-side Diff

... ... @@ -1217,6 +1217,11 @@
1217 1217 head.first->pprev = &head.first;
1218 1218 INIT_HLIST_HEAD(&unmounted);
1219 1219  
  1220 + /* undo decrements we'd done in umount_tree() */
  1221 + hlist_for_each_entry(mnt, &head, mnt_hash)
  1222 + if (mnt->mnt_ex_mountpoint.mnt)
  1223 + mntget(mnt->mnt_ex_mountpoint.mnt);
  1224 +
1220 1225 up_write(&namespace_sem);
1221 1226  
1222 1227 synchronize_rcu();
... ... @@ -1268,6 +1273,7 @@
1268 1273 p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
1269 1274 if (mnt_has_parent(p)) {
1270 1275 put_mountpoint(p->mnt_mp);
  1276 + mnt_add_count(p->mnt_parent, -1);
1271 1277 /* move the reference to mountpoint into ->mnt_ex_mountpoint */
1272 1278 p->mnt_ex_mountpoint.dentry = p->mnt_mountpoint;
1273 1279 p->mnt_ex_mountpoint.mnt = &p->mnt_parent->mnt;