diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-09 00:59:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-14 08:32:47 -0400 |
commit | f7a99c5b7c8bd3d3f533c8b38274e33f3da9096e (patch) | |
tree | 5c326c0ddd1f40eacbe2fd7c888f26b089389f99 /fs/namespace.c | |
parent | d187663ef24cd3d033f0cbf2867e70b36a3a90b8 (diff) |
get rid of ->mnt_longterm
it's enough to set ->mnt_ns of internal vfsmounts to something
distinct from all struct mnt_namespace out there; then we can
just use the check for ->mnt_ns != NULL in the fast path of
mntput_no_expire()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 53 |
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 | ||
624 | static 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 */ | ||
632 | static 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) | |||
804 | put_again: | 787 | put_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 | ||
2212 | void mnt_make_longterm(struct vfsmount *mnt) | ||
2213 | { | ||
2214 | __mnt_make_longterm(real_mount(mnt)); | ||
2215 | } | ||
2216 | |||
2217 | void 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 | } |