aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/mount.h2
-rw-r--r--fs/namespace.c22
-rw-r--r--fs/pnode.c3
3 files changed, 9 insertions, 18 deletions
diff --git a/fs/mount.h b/fs/mount.h
index 64a858143ff9..3168dc41bad5 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -55,7 +55,7 @@ struct mount {
55 int mnt_group_id; /* peer group identifier */ 55 int mnt_group_id; /* peer group identifier */
56 int mnt_expiry_mark; /* true if marked for expiry */ 56 int mnt_expiry_mark; /* true if marked for expiry */
57 int mnt_pinned; 57 int mnt_pinned;
58 int mnt_ghosts; 58 struct path mnt_ex_mountpoint;
59}; 59};
60 60
61#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ 61#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namespace.c b/fs/namespace.c
index c8d214ce30c6..846ea43ab0c6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1136,20 +1136,8 @@ static void namespace_unlock(void)
1136 while (!list_empty(&head)) { 1136 while (!list_empty(&head)) {
1137 mnt = list_first_entry(&head, struct mount, mnt_hash); 1137 mnt = list_first_entry(&head, struct mount, mnt_hash);
1138 list_del_init(&mnt->mnt_hash); 1138 list_del_init(&mnt->mnt_hash);
1139 if (mnt_has_parent(mnt)) { 1139 if (mnt->mnt_ex_mountpoint.mnt)
1140 struct dentry *dentry; 1140 path_put(&mnt->mnt_ex_mountpoint);
1141 struct mount *m;
1142
1143 br_write_lock(&vfsmount_lock);
1144 dentry = mnt->mnt_mountpoint;
1145 m = mnt->mnt_parent;
1146 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
1147 mnt->mnt_parent = mnt;
1148 m->mnt_ghosts--;
1149 br_write_unlock(&vfsmount_lock);
1150 dput(dentry);
1151 mntput(&m->mnt);
1152 }
1153 mntput(&mnt->mnt); 1141 mntput(&mnt->mnt);
1154 } 1142 }
1155} 1143}
@@ -1181,8 +1169,12 @@ void umount_tree(struct mount *mnt, int propagate)
1181 p->mnt_ns = NULL; 1169 p->mnt_ns = NULL;
1182 list_del_init(&p->mnt_child); 1170 list_del_init(&p->mnt_child);
1183 if (mnt_has_parent(p)) { 1171 if (mnt_has_parent(p)) {
1184 p->mnt_parent->mnt_ghosts++;
1185 put_mountpoint(p->mnt_mp); 1172 put_mountpoint(p->mnt_mp);
1173 /* move the reference to mountpoint into ->mnt_ex_mountpoint */
1174 p->mnt_ex_mountpoint.dentry = p->mnt_mountpoint;
1175 p->mnt_ex_mountpoint.mnt = &p->mnt_parent->mnt;
1176 p->mnt_mountpoint = p->mnt.mnt_root;
1177 p->mnt_parent = p;
1186 p->mnt_mp = NULL; 1178 p->mnt_mp = NULL;
1187 } 1179 }
1188 change_mnt_propagation(p, MS_PRIVATE); 1180 change_mnt_propagation(p, MS_PRIVATE);
diff --git a/fs/pnode.c b/fs/pnode.c
index 9af0df15256e..3cfd48cf887e 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -278,8 +278,7 @@ out:
278 */ 278 */
279static inline int do_refcount_check(struct mount *mnt, int count) 279static inline int do_refcount_check(struct mount *mnt, int count)
280{ 280{
281 int mycount = mnt_get_count(mnt) - mnt->mnt_ghosts; 281 return mnt_get_count(mnt) > count;
282 return (mycount > count);
283} 282}
284 283
285/* 284/*