|
8 | 8 | struct mnt_namespace {
|
9 | 9 | struct ns_common ns;
|
10 | 10 | struct mount * root;
|
11 |
| - struct rb_root mounts; /* Protected by namespace_sem */ |
| 11 | + struct { |
| 12 | + struct rb_root mounts; /* Protected by namespace_sem */ |
| 13 | + struct rb_node *mnt_last_node; /* last (rightmost) mount in the rbtree */ |
| 14 | + struct rb_node *mnt_first_node; /* first (leftmost) mount in the rbtree */ |
| 15 | + }; |
12 | 16 | struct user_namespace *user_ns;
|
13 | 17 | struct ucounts *ucounts;
|
14 | 18 | u64 seq; /* Sequence number to prevent loops */
|
15 |
| - wait_queue_head_t poll; |
| 19 | + union { |
| 20 | + wait_queue_head_t poll; |
| 21 | + struct rcu_head mnt_ns_rcu; |
| 22 | + }; |
16 | 23 | u64 event;
|
17 | 24 | unsigned int nr_mounts; /* # of mounts in the namespace */
|
18 | 25 | unsigned int pending_mounts;
|
19 | 26 | struct rb_node mnt_ns_tree_node; /* node in the mnt_ns_tree */
|
| 27 | + struct list_head mnt_ns_list; /* entry in the sequential list of mounts namespace */ |
20 | 28 | refcount_t passive; /* number references not pinning @mounts */
|
21 | 29 | } __randomize_layout;
|
22 | 30 |
|
@@ -150,22 +158,21 @@ static inline bool mnt_ns_attached(const struct mount *mnt)
|
150 | 158 |
|
151 | 159 | static inline void move_from_ns(struct mount *mnt, struct list_head *dt_list)
|
152 | 160 | {
|
| 161 | + struct mnt_namespace *ns = mnt->mnt_ns; |
153 | 162 | WARN_ON(!mnt_ns_attached(mnt));
|
154 |
| - rb_erase(&mnt->mnt_node, &mnt->mnt_ns->mounts); |
| 163 | + if (ns->mnt_last_node == &mnt->mnt_node) |
| 164 | + ns->mnt_last_node = rb_prev(&mnt->mnt_node); |
| 165 | + if (ns->mnt_first_node == &mnt->mnt_node) |
| 166 | + ns->mnt_first_node = rb_next(&mnt->mnt_node); |
| 167 | + rb_erase(&mnt->mnt_node, &ns->mounts); |
155 | 168 | RB_CLEAR_NODE(&mnt->mnt_node);
|
156 | 169 | list_add_tail(&mnt->mnt_list, dt_list);
|
157 | 170 | }
|
158 | 171 |
|
159 | 172 | bool has_locked_children(struct mount *mnt, struct dentry *dentry);
|
160 |
| -struct mnt_namespace *__lookup_next_mnt_ns(struct mnt_namespace *mnt_ns, bool previous); |
161 |
| -static inline struct mnt_namespace *lookup_next_mnt_ns(struct mnt_namespace *mntns) |
162 |
| -{ |
163 |
| - return __lookup_next_mnt_ns(mntns, false); |
164 |
| -} |
165 |
| -static inline struct mnt_namespace *lookup_prev_mnt_ns(struct mnt_namespace *mntns) |
166 |
| -{ |
167 |
| - return __lookup_next_mnt_ns(mntns, true); |
168 |
| -} |
| 173 | +struct mnt_namespace *get_sequential_mnt_ns(struct mnt_namespace *mnt_ns, |
| 174 | + bool previous); |
| 175 | + |
169 | 176 | static inline struct mnt_namespace *to_mnt_ns(struct ns_common *ns)
|
170 | 177 | {
|
171 | 178 | return container_of(ns, struct mnt_namespace, ns);
|
|
0 commit comments