lkml.org 
[lkml]   [2015]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.0 113/220] mnt: Dont propagate unmounts to locked mounts
    Date
    4.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: "Eric W. Biederman" <ebiederm@xmission.com>

    commit 0c56fe31420ca599c90240315f7959bf1b4eb6ce upstream.

    If the first mount in shared subtree is locked don't unmount the
    shared subtree.

    This is ensured by walking through the mounts parents before children
    and marking a mount as unmountable if it is not locked or it is locked
    but it's parent is marked.

    This allows recursive mount detach to propagate through a set of
    mounts when unmounting them would not reveal what is under any locked
    mount.

    Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/pnode.c | 32 +++++++++++++++++++++++++++++---
    fs/pnode.h | 1 +
    2 files changed, 30 insertions(+), 3 deletions(-)

    --- a/fs/pnode.c
    +++ b/fs/pnode.c
    @@ -382,6 +382,26 @@ void propagate_mount_unlock(struct mount
    }

    /*
    + * Mark all mounts that the MNT_LOCKED logic will allow to be unmounted.
    + */
    +static void mark_umount_candidates(struct mount *mnt)
    +{
    + struct mount *parent = mnt->mnt_parent;
    + struct mount *m;
    +
    + BUG_ON(parent == mnt);
    +
    + for (m = propagation_next(parent, parent); m;
    + m = propagation_next(m, parent)) {
    + struct mount *child = __lookup_mnt_last(&m->mnt,
    + mnt->mnt_mountpoint);
    + if (child && (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m))) {
    + SET_MNT_MARK(child);
    + }
    + }
    +}
    +
    +/*
    * NOTE: unmounting 'mnt' naturally propagates to all other mounts its
    * parent propagates to.
    */
    @@ -398,10 +418,13 @@ static void __propagate_umount(struct mo
    struct mount *child = __lookup_mnt_last(&m->mnt,
    mnt->mnt_mountpoint);
    /*
    - * umount the child only if the child has no
    - * other children
    + * umount the child only if the child has no children
    + * and the child is marked safe to unmount.
    */
    - if (child && list_empty(&child->mnt_mounts)) {
    + if (!child || !IS_MNT_MARKED(child))
    + continue;
    + CLEAR_MNT_MARK(child);
    + if (list_empty(&child->mnt_mounts)) {
    list_del_init(&child->mnt_child);
    child->mnt.mnt_flags |= MNT_UMOUNT;
    list_move_tail(&child->mnt_list, &mnt->mnt_list);
    @@ -420,6 +443,9 @@ int propagate_umount(struct list_head *l
    {
    struct mount *mnt;

    + list_for_each_entry_reverse(mnt, list, mnt_list)
    + mark_umount_candidates(mnt);
    +
    list_for_each_entry(mnt, list, mnt_list)
    __propagate_umount(mnt);
    return 0;
    --- a/fs/pnode.h
    +++ b/fs/pnode.h
    @@ -19,6 +19,7 @@
    #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED)
    #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 CL_EXPIRE 0x01
    #define CL_SLAVE 0x02



    \
     
     \ /
      Last update: 2015-05-02 21:21    [W:7.094 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site