aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c53
1 files changed, 7 insertions, 46 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 1e4a5fe3d7b7..a524ea4dbd80 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -621,21 +621,6 @@ static void attach_mnt(struct mount *mnt, struct path *path)
621 list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts); 621 list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts);
622} 622}
623 623
624static inline void __mnt_make_longterm(struct mount *mnt)
625{
626#ifdef CONFIG_SMP
627 atomic_inc(&mnt->mnt_longterm);
628#endif
629}
630
631/* needs vfsmount lock for write */
632static inline void __mnt_make_shortterm(struct mount *mnt)
633{
634#ifdef CONFIG_SMP
635 atomic_dec(&mnt->mnt_longterm);
636#endif
637}
638
639/* 624/*
640 * vfsmount lock must be held for write 625 * vfsmount lock must be held for write
641 */ 626 */
@@ -649,10 +634,8 @@ static void commit_tree(struct mount *mnt)
649 BUG_ON(parent == mnt); 634 BUG_ON(parent == mnt);
650 635
651 list_add_tail(&head, &mnt->mnt_list); 636 list_add_tail(&head, &mnt->mnt_list);
652 list_for_each_entry(m, &head, mnt_list) { 637 list_for_each_entry(m, &head, mnt_list)
653 m->mnt_ns = n; 638 m->mnt_ns = n;
654 __mnt_make_longterm(m);
655 }
656 639
657 list_splice(&head, n->list.prev); 640 list_splice(&head, n->list.prev);
658 641
@@ -804,7 +787,8 @@ static void mntput_no_expire(struct mount *mnt)
804put_again: 787put_again:
805#ifdef CONFIG_SMP 788#ifdef CONFIG_SMP
806 br_read_lock(&vfsmount_lock); 789 br_read_lock(&vfsmount_lock);
807 if (likely(atomic_read(&mnt->mnt_longterm))) { 790 if (likely(mnt->mnt_ns)) {
791 /* shouldn't be the last one */
808 mnt_add_count(mnt, -1); 792 mnt_add_count(mnt, -1);
809 br_read_unlock(&vfsmount_lock); 793 br_read_unlock(&vfsmount_lock);
810 return; 794 return;
@@ -1074,8 +1058,6 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
1074 list_del_init(&p->mnt_expire); 1058 list_del_init(&p->mnt_expire);
1075 list_del_init(&p->mnt_list); 1059 list_del_init(&p->mnt_list);
1076 __touch_mnt_namespace(p->mnt_ns); 1060 __touch_mnt_namespace(p->mnt_ns);
1077 if (p->mnt_ns)
1078 __mnt_make_shortterm(p);
1079 p->mnt_ns = NULL; 1061 p->mnt_ns = NULL;
1080 list_del_init(&p->mnt_child); 1062 list_del_init(&p->mnt_child);
1081 if (mnt_has_parent(p)) { 1063 if (mnt_has_parent(p)) {
@@ -2209,23 +2191,6 @@ static struct mnt_namespace *alloc_mnt_ns(void)
2209 return new_ns; 2191 return new_ns;
2210} 2192}
2211 2193
2212void mnt_make_longterm(struct vfsmount *mnt)
2213{
2214 __mnt_make_longterm(real_mount(mnt));
2215}
2216
2217void mnt_make_shortterm(struct vfsmount *m)
2218{
2219#ifdef CONFIG_SMP
2220 struct mount *mnt = real_mount(m);
2221 if (atomic_add_unless(&mnt->mnt_longterm, -1, 1))
2222 return;
2223 br_write_lock(&vfsmount_lock);
2224 atomic_dec(&mnt->mnt_longterm);
2225 br_write_unlock(&vfsmount_lock);
2226#endif
2227}
2228
2229/* 2194/*
2230 * Allocate a new namespace structure and populate it with contents 2195 * Allocate a new namespace structure and populate it with contents
2231 * copied from the namespace of the passed in task structure. 2196 * copied from the namespace of the passed in task structure.
@@ -2265,18 +2230,13 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2265 q = new; 2230 q = new;
2266 while (p) { 2231 while (p) {
2267 q->mnt_ns = new_ns; 2232 q->mnt_ns = new_ns;
2268 __mnt_make_longterm(q);
2269 if (fs) { 2233 if (fs) {
2270 if (&p->mnt == fs->root.mnt) { 2234 if (&p->mnt == fs->root.mnt) {
2271 fs->root.mnt = mntget(&q->mnt); 2235 fs->root.mnt = mntget(&q->mnt);
2272 __mnt_make_longterm(q);
2273 mnt_make_shortterm(&p->mnt);
2274 rootmnt = &p->mnt; 2236 rootmnt = &p->mnt;
2275 } 2237 }
2276 if (&p->mnt == fs->pwd.mnt) { 2238 if (&p->mnt == fs->pwd.mnt) {
2277 fs->pwd.mnt = mntget(&q->mnt); 2239 fs->pwd.mnt = mntget(&q->mnt);
2278 __mnt_make_longterm(q);
2279 mnt_make_shortterm(&p->mnt);
2280 pwdmnt = &p->mnt; 2240 pwdmnt = &p->mnt;
2281 } 2241 }
2282 } 2242 }
@@ -2320,7 +2280,6 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)
2320 if (!IS_ERR(new_ns)) { 2280 if (!IS_ERR(new_ns)) {
2321 struct mount *mnt = real_mount(m); 2281 struct mount *mnt = real_mount(m);
2322 mnt->mnt_ns = new_ns; 2282 mnt->mnt_ns = new_ns;
2323 __mnt_make_longterm(mnt);
2324 new_ns->root = mnt; 2283 new_ns->root = mnt;
2325 list_add(&new_ns->list, &mnt->mnt_list); 2284 list_add(&new_ns->list, &mnt->mnt_list);
2326 } else { 2285 } else {
@@ -2615,7 +2574,7 @@ struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
2615 * it is a longterm mount, don't release mnt until 2574 * it is a longterm mount, don't release mnt until
2616 * we unmount before file sys is unregistered 2575 * we unmount before file sys is unregistered
2617 */ 2576 */
2618 mnt_make_longterm(mnt); 2577 real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
2619 } 2578 }
2620 return mnt; 2579 return mnt;
2621} 2580}
@@ -2625,7 +2584,9 @@ void kern_unmount(struct vfsmount *mnt)
2625{ 2584{
2626 /* release long term mount so mount point can be released */ 2585 /* release long term mount so mount point can be released */
2627 if (!IS_ERR_OR_NULL(mnt)) { 2586 if (!IS_ERR_OR_NULL(mnt)) {
2628 mnt_make_shortterm(mnt); 2587 br_write_lock(&vfsmount_lock);
2588 real_mount(mnt)->mnt_ns = NULL;
2589 br_write_unlock(&vfsmount_lock);
2629 mntput(mnt); 2590 mntput(mnt);
2630 } 2591 }
2631} 2592}