aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-12-22 23:04:31 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2016-12-22 23:04:31 -0500
commitfaf0dcebd7b387187f29ff811d47df465ea4c9f9 (patch)
tree77077e72fe22222a369aa36da2f12e064a91bbe9
parent128394eff343fc6d2f32172f03e24829539c5835 (diff)
parent5235d448c48e1f5a4a34bf90d412775cb75ffb32 (diff)
Merge branch 'work.namespace' into for-linus
-rw-r--r--fs/namespace.c8
-rw-r--r--fs/pnode.c74
2 files changed, 38 insertions, 44 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index f7e28f8ea04d..b5b1259e064f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -96,10 +96,6 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry)
96 return &mountpoint_hashtable[tmp & mp_hash_mask]; 96 return &mountpoint_hashtable[tmp & mp_hash_mask];
97} 97}
98 98
99/*
100 * allocation is serialized by namespace_sem, but we need the spinlock to
101 * serialize with freeing.
102 */
103static int mnt_alloc_id(struct mount *mnt) 99static int mnt_alloc_id(struct mount *mnt)
104{ 100{
105 int res; 101 int res;
@@ -1034,6 +1030,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
1034 if (IS_MNT_SLAVE(old)) 1030 if (IS_MNT_SLAVE(old))
1035 list_add(&mnt->mnt_slave, &old->mnt_slave); 1031 list_add(&mnt->mnt_slave, &old->mnt_slave);
1036 mnt->mnt_master = old->mnt_master; 1032 mnt->mnt_master = old->mnt_master;
1033 } else {
1034 CLEAR_MNT_SHARED(mnt);
1037 } 1035 }
1038 if (flag & CL_MAKE_SHARED) 1036 if (flag & CL_MAKE_SHARED)
1039 set_mnt_shared(mnt); 1037 set_mnt_shared(mnt);
@@ -1828,9 +1826,7 @@ struct vfsmount *clone_private_mount(const struct path *path)
1828 if (IS_MNT_UNBINDABLE(old_mnt)) 1826 if (IS_MNT_UNBINDABLE(old_mnt))
1829 return ERR_PTR(-EINVAL); 1827 return ERR_PTR(-EINVAL);
1830 1828
1831 down_read(&namespace_sem);
1832 new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); 1829 new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
1833 up_read(&namespace_sem);
1834 if (IS_ERR(new_mnt)) 1830 if (IS_ERR(new_mnt))
1835 return ERR_CAST(new_mnt); 1831 return ERR_CAST(new_mnt);
1836 1832
diff --git a/fs/pnode.c b/fs/pnode.c
index 234a9ac49958..06a793f4ae38 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -67,49 +67,47 @@ int get_dominating_id(struct mount *mnt, const struct path *root)
67 67
68static int do_make_slave(struct mount *mnt) 68static int do_make_slave(struct mount *mnt)
69{ 69{
70 struct mount *peer_mnt = mnt, *master = mnt->mnt_master; 70 struct mount *master, *slave_mnt;
71 struct mount *slave_mnt;
72 71
73 /* 72 if (list_empty(&mnt->mnt_share)) {
74 * slave 'mnt' to a peer mount that has the 73 if (IS_MNT_SHARED(mnt)) {
75 * same root dentry. If none is available then 74 mnt_release_group_id(mnt);
76 * slave it to anything that is available. 75 CLEAR_MNT_SHARED(mnt);
77 */ 76 }
78 while ((peer_mnt = next_peer(peer_mnt)) != mnt && 77 master = mnt->mnt_master;
79 peer_mnt->mnt.mnt_root != mnt->mnt.mnt_root) ; 78 if (!master) {
80 79 struct list_head *p = &mnt->mnt_slave_list;
81 if (peer_mnt == mnt) { 80 while (!list_empty(p)) {
82 peer_mnt = next_peer(mnt); 81 slave_mnt = list_first_entry(p,
83 if (peer_mnt == mnt) 82 struct mount, mnt_slave);
84 peer_mnt = NULL; 83 list_del_init(&slave_mnt->mnt_slave);
85 } 84 slave_mnt->mnt_master = NULL;
86 if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) && 85 }
87 list_empty(&mnt->mnt_share)) 86 return 0;
88 mnt_release_group_id(mnt); 87 }
89
90 list_del_init(&mnt->mnt_share);
91 mnt->mnt_group_id = 0;
92
93 if (peer_mnt)
94 master = peer_mnt;
95
96 if (master) {
97 list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave)
98 slave_mnt->mnt_master = master;
99 list_move(&mnt->mnt_slave, &master->mnt_slave_list);
100 list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev);
101 INIT_LIST_HEAD(&mnt->mnt_slave_list);
102 } else { 88 } else {
103 struct list_head *p = &mnt->mnt_slave_list; 89 struct mount *m;
104 while (!list_empty(p)) { 90 /*
105 slave_mnt = list_first_entry(p, 91 * slave 'mnt' to a peer mount that has the
106 struct mount, mnt_slave); 92 * same root dentry. If none is available then
107 list_del_init(&slave_mnt->mnt_slave); 93 * slave it to anything that is available.
108 slave_mnt->mnt_master = NULL; 94 */
95 for (m = master = next_peer(mnt); m != mnt; m = next_peer(m)) {
96 if (m->mnt.mnt_root == mnt->mnt.mnt_root) {
97 master = m;
98 break;
99 }
109 } 100 }
101 list_del_init(&mnt->mnt_share);
102 mnt->mnt_group_id = 0;
103 CLEAR_MNT_SHARED(mnt);
110 } 104 }
105 list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave)
106 slave_mnt->mnt_master = master;
107 list_move(&mnt->mnt_slave, &master->mnt_slave_list);
108 list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev);
109 INIT_LIST_HEAD(&mnt->mnt_slave_list);
111 mnt->mnt_master = master; 110 mnt->mnt_master = master;
112 CLEAR_MNT_SHARED(mnt);
113 return 0; 111 return 0;
114} 112}
115 113