Commit f7a99c5b7c8bd3d3f533c8b38274e33f3da9096e

Authored by Al Viro
1 parent d187663ef2

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>

Showing 5 changed files with 26 additions and 72 deletions Side-by-side Diff

... ... @@ -2622,7 +2622,7 @@
2622 2622 if (!slash)
2623 2623 error = prepend(buffer, buflen, "/", 1);
2624 2624 if (!error)
2625   - error = real_mount(vfsmnt)->mnt_ns ? 1 : 2;
  2625 + error = is_mounted(vfsmnt) ? 1 : 2;
2626 2626 goto out;
2627 2627 }
2628 2628  
... ... @@ -6,18 +6,6 @@
6 6 #include <linux/fs_struct.h>
7 7 #include "internal.h"
8 8  
9   -static inline void path_get_longterm(struct path *path)
10   -{
11   - path_get(path);
12   - mnt_make_longterm(path->mnt);
13   -}
14   -
15   -static inline void path_put_longterm(struct path *path)
16   -{
17   - mnt_make_shortterm(path->mnt);
18   - path_put(path);
19   -}
20   -
21 9 /*
22 10 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
23 11 * It can block.
... ... @@ -26,7 +14,7 @@
26 14 {
27 15 struct path old_root;
28 16  
29   - path_get_longterm(path);
  17 + path_get(path);
30 18 spin_lock(&fs->lock);
31 19 write_seqcount_begin(&fs->seq);
32 20 old_root = fs->root;
... ... @@ -34,7 +22,7 @@
34 22 write_seqcount_end(&fs->seq);
35 23 spin_unlock(&fs->lock);
36 24 if (old_root.dentry)
37   - path_put_longterm(&old_root);
  25 + path_put(&old_root);
38 26 }
39 27  
40 28 /*
... ... @@ -45,7 +33,7 @@
45 33 {
46 34 struct path old_pwd;
47 35  
48   - path_get_longterm(path);
  36 + path_get(path);
49 37 spin_lock(&fs->lock);
50 38 write_seqcount_begin(&fs->seq);
51 39 old_pwd = fs->pwd;
... ... @@ -54,7 +42,7 @@
54 42 spin_unlock(&fs->lock);
55 43  
56 44 if (old_pwd.dentry)
57   - path_put_longterm(&old_pwd);
  45 + path_put(&old_pwd);
58 46 }
59 47  
60 48 static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
... ... @@ -84,7 +72,7 @@
84 72 write_seqcount_end(&fs->seq);
85 73 while (hits--) {
86 74 count++;
87   - path_get_longterm(new_root);
  75 + path_get(new_root);
88 76 }
89 77 spin_unlock(&fs->lock);
90 78 }
91 79  
... ... @@ -92,13 +80,13 @@
92 80 } while_each_thread(g, p);
93 81 read_unlock(&tasklist_lock);
94 82 while (count--)
95   - path_put_longterm(old_root);
  83 + path_put(old_root);
96 84 }
97 85  
98 86 void free_fs_struct(struct fs_struct *fs)
99 87 {
100   - path_put_longterm(&fs->root);
101   - path_put_longterm(&fs->pwd);
  88 + path_put(&fs->root);
  89 + path_put(&fs->pwd);
102 90 kmem_cache_free(fs_cachep, fs);
103 91 }
104 92  
105 93  
... ... @@ -132,9 +120,9 @@
132 120  
133 121 spin_lock(&old->lock);
134 122 fs->root = old->root;
135   - path_get_longterm(&fs->root);
  123 + path_get(&fs->root);
136 124 fs->pwd = old->pwd;
137   - path_get_longterm(&fs->pwd);
  125 + path_get(&fs->pwd);
138 126 spin_unlock(&old->lock);
139 127 }
140 128 return fs;
... ... @@ -50,8 +50,6 @@
50 50 extern struct vfsmount *lookup_mnt(struct path *);
51 51 extern int finish_automount(struct vfsmount *, struct path *);
52 52  
53   -extern void mnt_make_longterm(struct vfsmount *);
54   -extern void mnt_make_shortterm(struct vfsmount *);
55 53 extern int sb_prepare_remount_readonly(struct super_block *);
56 54  
57 55 extern void __init mnt_init(void);
... ... @@ -22,7 +22,6 @@
22 22 struct vfsmount mnt;
23 23 #ifdef CONFIG_SMP
24 24 struct mnt_pcp __percpu *mnt_pcp;
25   - atomic_t mnt_longterm; /* how many of the refs are longterm */
26 25 #else
27 26 int mnt_count;
28 27 int mnt_writers;
... ... @@ -49,6 +48,8 @@
49 48 int mnt_ghosts;
50 49 };
51 50  
  51 +#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
  52 +
52 53 static inline struct mount *real_mount(struct vfsmount *mnt)
53 54 {
54 55 return container_of(mnt, struct mount, mnt);
... ... @@ -57,6 +58,12 @@
57 58 static inline int mnt_has_parent(struct mount *mnt)
58 59 {
59 60 return mnt != mnt->mnt_parent;
  61 +}
  62 +
  63 +static inline int is_mounted(struct vfsmount *mnt)
  64 +{
  65 + /* neither detached nor internal? */
  66 + return !IS_ERR_OR_NULL(real_mount(mnt));
60 67 }
61 68  
62 69 extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
... ... @@ -621,21 +621,6 @@
621 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 625 * vfsmount lock must be held for write
641 626 */
642 627  
... ... @@ -649,10 +634,8 @@
649 634 BUG_ON(parent == mnt);
650 635  
651 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 638 m->mnt_ns = n;
654   - __mnt_make_longterm(m);
655   - }
656 639  
657 640 list_splice(&head, n->list.prev);
658 641  
... ... @@ -804,7 +787,8 @@
804 787 put_again:
805 788 #ifdef CONFIG_SMP
806 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 792 mnt_add_count(mnt, -1);
809 793 br_read_unlock(&vfsmount_lock);
810 794 return;
... ... @@ -1074,8 +1058,6 @@
1074 1058 list_del_init(&p->mnt_expire);
1075 1059 list_del_init(&p->mnt_list);
1076 1060 __touch_mnt_namespace(p->mnt_ns);
1077   - if (p->mnt_ns)
1078   - __mnt_make_shortterm(p);
1079 1061 p->mnt_ns = NULL;
1080 1062 list_del_init(&p->mnt_child);
1081 1063 if (mnt_has_parent(p)) {
... ... @@ -2209,23 +2191,6 @@
2209 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 2195 * Allocate a new namespace structure and populate it with contents
2231 2196 * copied from the namespace of the passed in task structure.
2232 2197  
2233 2198  
... ... @@ -2265,18 +2230,13 @@
2265 2230 q = new;
2266 2231 while (p) {
2267 2232 q->mnt_ns = new_ns;
2268   - __mnt_make_longterm(q);
2269 2233 if (fs) {
2270 2234 if (&p->mnt == fs->root.mnt) {
2271 2235 fs->root.mnt = mntget(&q->mnt);
2272   - __mnt_make_longterm(q);
2273   - mnt_make_shortterm(&p->mnt);
2274 2236 rootmnt = &p->mnt;
2275 2237 }
2276 2238 if (&p->mnt == fs->pwd.mnt) {
2277 2239 fs->pwd.mnt = mntget(&q->mnt);
2278   - __mnt_make_longterm(q);
2279   - mnt_make_shortterm(&p->mnt);
2280 2240 pwdmnt = &p->mnt;
2281 2241 }
2282 2242 }
... ... @@ -2320,7 +2280,6 @@
2320 2280 if (!IS_ERR(new_ns)) {
2321 2281 struct mount *mnt = real_mount(m);
2322 2282 mnt->mnt_ns = new_ns;
2323   - __mnt_make_longterm(mnt);
2324 2283 new_ns->root = mnt;
2325 2284 list_add(&new_ns->list, &mnt->mnt_list);
2326 2285 } else {
... ... @@ -2615,7 +2574,7 @@
2615 2574 * it is a longterm mount, don't release mnt until
2616 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 2579 return mnt;
2621 2580 }
... ... @@ -2625,7 +2584,9 @@
2625 2584 {
2626 2585 /* release long term mount so mount point can be released */
2627 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 2590 mntput(mnt);
2630 2591 }
2631 2592 }