mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
namespace: record fully visible mounts in list
Instead of wading through all the mounts in the mount namespace rbtree to find fully visible procfs and sysfs mounts, be honest about them being special cruft and record them in a separate per-mount namespace list. Link: https://patch.msgid.link/684859a8e0ac929cb89c1fbe16ce15b30c70eb1f.1777278334.git.legion@kernel.org Reviewed-by: Aleksa Sarai <aleksa@amutable.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
e75c21d5ad
commit
672697c37c
|
|
@ -25,6 +25,7 @@ struct mnt_namespace {
|
|||
__u32 n_fsnotify_mask;
|
||||
struct fsnotify_mark_connector __rcu *n_fsnotify_marks;
|
||||
#endif
|
||||
struct hlist_head mnt_visible_mounts; /* SB_I_USERNS_VISIBLE mounts */
|
||||
unsigned int nr_mounts; /* # of mounts in the namespace */
|
||||
unsigned int pending_mounts;
|
||||
refcount_t passive; /* number references not pinning @mounts */
|
||||
|
|
@ -90,6 +91,7 @@ struct mount {
|
|||
int mnt_expiry_mark; /* true if marked for expiry */
|
||||
struct hlist_head mnt_pins;
|
||||
struct hlist_head mnt_stuck_children;
|
||||
struct hlist_node mnt_ns_visible; /* link in ns->mnt_visible_mounts */
|
||||
struct mount *overmount; /* mounted on ->mnt_root */
|
||||
} __randomize_layout;
|
||||
|
||||
|
|
@ -207,6 +209,8 @@ static inline void move_from_ns(struct mount *mnt)
|
|||
ns->mnt_first_node = rb_next(&mnt->mnt_node);
|
||||
rb_erase(&mnt->mnt_node, &ns->mounts);
|
||||
RB_CLEAR_NODE(&mnt->mnt_node);
|
||||
if (!hlist_unhashed(&mnt->mnt_ns_visible))
|
||||
hlist_del_init(&mnt->mnt_ns_visible);
|
||||
}
|
||||
|
||||
bool has_locked_children(struct mount *mnt, struct dentry *dentry);
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ static struct mount *alloc_vfsmnt(const char *name)
|
|||
INIT_HLIST_NODE(&mnt->mnt_slave);
|
||||
INIT_HLIST_NODE(&mnt->mnt_mp_list);
|
||||
INIT_HLIST_HEAD(&mnt->mnt_stuck_children);
|
||||
INIT_HLIST_NODE(&mnt->mnt_ns_visible);
|
||||
RB_CLEAR_NODE(&mnt->mnt_node);
|
||||
mnt->mnt.mnt_idmap = &nop_mnt_idmap;
|
||||
}
|
||||
|
|
@ -1098,6 +1099,10 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt)
|
|||
rb_link_node(&mnt->mnt_node, parent, link);
|
||||
rb_insert_color(&mnt->mnt_node, &ns->mounts);
|
||||
|
||||
if ((mnt->mnt.mnt_sb->s_iflags & SB_I_USERNS_VISIBLE) &&
|
||||
mnt->mnt.mnt_root == mnt->mnt.mnt_sb->s_root)
|
||||
hlist_add_head(&mnt->mnt_ns_visible, &ns->mnt_visible_mounts);
|
||||
|
||||
mnt_notify_add(mnt);
|
||||
}
|
||||
|
||||
|
|
@ -6340,22 +6345,20 @@ static bool mnt_already_visible(struct mnt_namespace *ns,
|
|||
int *new_mnt_flags)
|
||||
{
|
||||
int new_flags = *new_mnt_flags;
|
||||
struct mount *mnt, *n;
|
||||
struct mount *mnt;
|
||||
|
||||
/* Don't acquire namespace semaphore without a good reason. */
|
||||
if (hlist_empty(&ns->mnt_visible_mounts))
|
||||
return false;
|
||||
|
||||
guard(namespace_shared)();
|
||||
rbtree_postorder_for_each_entry_safe(mnt, n, &ns->mounts, mnt_node) {
|
||||
hlist_for_each_entry(mnt, &ns->mnt_visible_mounts, mnt_ns_visible) {
|
||||
struct mount *child;
|
||||
int mnt_flags;
|
||||
|
||||
if (mnt->mnt.mnt_sb->s_type != sb->s_type)
|
||||
continue;
|
||||
|
||||
/* This mount is not fully visible if it's root directory
|
||||
* is not the root directory of the filesystem.
|
||||
*/
|
||||
if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
|
||||
continue;
|
||||
|
||||
/* A local view of the mount flags */
|
||||
mnt_flags = mnt->mnt.mnt_flags;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user