Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull mount fixes from Al Viro:
"A couple of races around legalize_mnt vs umount (both fairly old and
hard to hit) plus two bugs in move_mount(2) - both around 'move
detached subtree in place' logics"

* tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fix IS_MNT_PROPAGATING uses
do_move_mount(): don't leak MNTNS_PROPAGATING on failures
do_umount(): add missing barrier before refcount checks in sync case
__legitimize_mnt(): check for MNT_SYNC_UMOUNT should be under mount_lock

+17 -19
+7 -10
fs/namespace.c
··· 787 787 return 0; 788 788 mnt = real_mount(bastard); 789 789 mnt_add_count(mnt, 1); 790 - smp_mb(); // see mntput_no_expire() 790 + smp_mb(); // see mntput_no_expire() and do_umount() 791 791 if (likely(!read_seqretry(&mount_lock, seq))) 792 792 return 0; 793 - if (bastard->mnt_flags & MNT_SYNC_UMOUNT) { 794 - mnt_add_count(mnt, -1); 795 - return 1; 796 - } 797 793 lock_mount_hash(); 798 - if (unlikely(bastard->mnt_flags & MNT_DOOMED)) { 794 + if (unlikely(bastard->mnt_flags & (MNT_SYNC_UMOUNT | MNT_DOOMED))) { 799 795 mnt_add_count(mnt, -1); 800 796 unlock_mount_hash(); 801 797 return 1; ··· 2044 2048 umount_tree(mnt, UMOUNT_PROPAGATE); 2045 2049 retval = 0; 2046 2050 } else { 2051 + smp_mb(); // paired with __legitimize_mnt() 2047 2052 shrink_submounts(mnt); 2048 2053 retval = -EBUSY; 2049 2054 if (!propagate_mount_busy(mnt, 2)) { ··· 3557 3560 * @mnt_from itself. This defeats the whole purpose of mounting 3558 3561 * @mnt_from beneath @mnt_to. 3559 3562 */ 3560 - if (propagation_would_overmount(parent_mnt_to, mnt_from, mp)) 3563 + if (check_mnt(mnt_from) && 3564 + propagation_would_overmount(parent_mnt_to, mnt_from, mp)) 3561 3565 return -EINVAL; 3562 3566 3563 3567 return 0; ··· 3716 3718 if (err) 3717 3719 goto out; 3718 3720 3719 - if (is_anon_ns(ns)) 3720 - ns->mntns_flags &= ~MNTNS_PROPAGATING; 3721 - 3722 3721 /* if the mount is moved, it should no longer be expire 3723 3722 * automatically */ 3724 3723 list_del_init(&old->mnt_expire); 3725 3724 if (attached) 3726 3725 put_mountpoint(old_mp); 3727 3726 out: 3727 + if (is_anon_ns(ns)) 3728 + ns->mntns_flags &= ~MNTNS_PROPAGATING; 3728 3729 unlock_mount(mp); 3729 3730 if (!err) { 3730 3731 if (attached) {
+9 -8
fs/pnode.c
··· 150 150 struct mount *origin) 151 151 { 152 152 /* are there any slaves of this mount? */ 153 - if (!IS_MNT_PROPAGATED(m) && !list_empty(&m->mnt_slave_list)) 153 + if (!IS_MNT_NEW(m) && !list_empty(&m->mnt_slave_list)) 154 154 return first_slave(m); 155 155 156 156 while (1) { ··· 174 174 * Advance m such that propagation_next will not return 175 175 * the slaves of m. 176 176 */ 177 - if (!IS_MNT_PROPAGATED(m) && !list_empty(&m->mnt_slave_list)) 177 + if (!IS_MNT_NEW(m) && !list_empty(&m->mnt_slave_list)) 178 178 m = last_slave(m); 179 179 180 180 return m; ··· 185 185 while (1) { 186 186 while (1) { 187 187 struct mount *next; 188 - if (!IS_MNT_PROPAGATED(m) && !list_empty(&m->mnt_slave_list)) 188 + if (!IS_MNT_NEW(m) && !list_empty(&m->mnt_slave_list)) 189 189 return first_slave(m); 190 190 next = next_peer(m); 191 191 if (m->mnt_group_id == origin->mnt_group_id) { ··· 226 226 struct mount *child; 227 227 int type; 228 228 /* skip ones added by this propagate_mnt() */ 229 - if (IS_MNT_PROPAGATED(m)) 229 + if (IS_MNT_NEW(m)) 230 230 return 0; 231 - /* skip if mountpoint isn't covered by it */ 231 + /* skip if mountpoint isn't visible in m */ 232 232 if (!is_subdir(dest_mp->m_dentry, m->mnt.mnt_root)) 233 233 return 0; 234 + /* skip if m is in the anon_ns we are emptying */ 235 + if (m->mnt_ns->mntns_flags & MNTNS_PROPAGATING) 236 + return 0; 237 + 234 238 if (peers(m, last_dest)) { 235 239 type = CL_MAKE_SHARED; 236 240 } else { ··· 382 378 const struct mountpoint *mp) 383 379 { 384 380 if (!IS_MNT_SHARED(from)) 385 - return false; 386 - 387 - if (IS_MNT_PROPAGATED(to)) 388 381 return false; 389 382 390 383 if (to->mnt.mnt_root != mp->m_dentry)
+1 -1
fs/pnode.h
··· 12 12 13 13 #define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED) 14 14 #define IS_MNT_SLAVE(m) ((m)->mnt_master) 15 - #define IS_MNT_PROPAGATED(m) (!(m)->mnt_ns || ((m)->mnt_ns->mntns_flags & MNTNS_PROPAGATING)) 15 + #define IS_MNT_NEW(m) (!(m)->mnt_ns) 16 16 #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) 17 17 #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) 18 18 #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED)