Patch "mnt: Clarify and correct the disconnect logic in umount_tree" has been added to the 4.1-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
mnt: Clarify and correct the disconnect logic in umount_tree
to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mnt-clarify-and-correct-the-disconnect-logic-in-umount_tree.patch
and it can be found in the queue-4.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
f2d0a123bcf16d1a9cf7942ddc98e0ef77862c2bMon Sep 17 00:00:00 2001
From: "Eric W. Biederman" <[email protected]>
Date: Fri, 17 Jul 2015 14:15:30 -0500
Subject: mnt: Clarify and correct the disconnect logic in umount_tree
From: "Eric W. Biederman" <[email protected]>
commit f2d0a123bcf16d1a9cf7942ddc98e0ef77862c2b upstream.
rmdir mntpoint will result in an infinite loop when there is a mount locked on the mountpoint in another mount namespace.
This is because the logic to test to see if a mount should be disconnected in umount_tree is buggy.
Move the logic to decide if a mount should remain connected to it's mountpoint into it's own function disconnect_mount so that clarity of expression instead of terseness of expression becomes a virtue.
When the conditions where it is invalid to leave a mount connected are first ruled out, the logic for deciding if a mount should be disconnected becomes much clearer and simpler.
--- fs/namespace.c | 35 +++++++++++++++++++++++++++++++---- fs/pnode.h | 2 -- 2 files changed, 31 insertions(+), 6 deletions(-)
fs/namespace.c +31 -4
@@ -1350,6 +1350,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
@@ -1387,10 +1417,7 @@ static void umount_tree(struct mount *mnif (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 );
fs/pnode.h +0 -2
@@ -20,8 +20,6 @@#define SET_MNT_MARK (m) ((m)->mnt.mnt_flags |= MNT_MARKED)#define CLEAR_MNT_MARK (m) ((m)->mnt.mnt_flags &= ~MNT_MARKED)#define IS_MNT_LOCKED (m) ((m)->mnt.mnt_flags & MNT_LOCKED) -#define IS_MNT_LOCKED_AND_LAZY (m) \ - (((m)->mnt.mnt_flags & (MNT_LOCKED|MNT_SYNC_UMOUNT)) == MNT_LOCKED)#define CL_EXPIRE 0x01#define CL_SLAVE 0x02
Patches currently in stable-queue which might be from [email protected] are
queue-4.1/mnt-clarify-and-correct-the-disconnect-logic-in-umount_tree.patch queue-4.1/mnt-in-detach_mounts-detach-the-appropriate-unmounted-mount.patch