1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #include <linux/mount.h>
3*4882a593Smuzhiyun #include <linux/seq_file.h>
4*4882a593Smuzhiyun #include <linux/poll.h>
5*4882a593Smuzhiyun #include <linux/ns_common.h>
6*4882a593Smuzhiyun #include <linux/fs_pin.h>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun struct mnt_namespace {
9*4882a593Smuzhiyun atomic_t count;
10*4882a593Smuzhiyun struct ns_common ns;
11*4882a593Smuzhiyun struct mount * root;
12*4882a593Smuzhiyun /*
13*4882a593Smuzhiyun * Traversal and modification of .list is protected by either
14*4882a593Smuzhiyun * - taking namespace_sem for write, OR
15*4882a593Smuzhiyun * - taking namespace_sem for read AND taking .ns_lock.
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun struct list_head list;
18*4882a593Smuzhiyun spinlock_t ns_lock;
19*4882a593Smuzhiyun struct user_namespace *user_ns;
20*4882a593Smuzhiyun struct ucounts *ucounts;
21*4882a593Smuzhiyun u64 seq; /* Sequence number to prevent loops */
22*4882a593Smuzhiyun wait_queue_head_t poll;
23*4882a593Smuzhiyun u64 event;
24*4882a593Smuzhiyun unsigned int mounts; /* # of mounts in the namespace */
25*4882a593Smuzhiyun unsigned int pending_mounts;
26*4882a593Smuzhiyun } __randomize_layout;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun struct mnt_pcp {
29*4882a593Smuzhiyun int mnt_count;
30*4882a593Smuzhiyun int mnt_writers;
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun struct mountpoint {
34*4882a593Smuzhiyun struct hlist_node m_hash;
35*4882a593Smuzhiyun struct dentry *m_dentry;
36*4882a593Smuzhiyun struct hlist_head m_list;
37*4882a593Smuzhiyun int m_count;
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun struct mount {
41*4882a593Smuzhiyun struct hlist_node mnt_hash;
42*4882a593Smuzhiyun struct mount *mnt_parent;
43*4882a593Smuzhiyun struct dentry *mnt_mountpoint;
44*4882a593Smuzhiyun struct vfsmount mnt;
45*4882a593Smuzhiyun union {
46*4882a593Smuzhiyun struct rcu_head mnt_rcu;
47*4882a593Smuzhiyun struct llist_node mnt_llist;
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun #ifdef CONFIG_SMP
50*4882a593Smuzhiyun struct mnt_pcp __percpu *mnt_pcp;
51*4882a593Smuzhiyun #else
52*4882a593Smuzhiyun int mnt_count;
53*4882a593Smuzhiyun int mnt_writers;
54*4882a593Smuzhiyun #endif
55*4882a593Smuzhiyun struct list_head mnt_mounts; /* list of children, anchored here */
56*4882a593Smuzhiyun struct list_head mnt_child; /* and going through their mnt_child */
57*4882a593Smuzhiyun struct list_head mnt_instance; /* mount instance on sb->s_mounts */
58*4882a593Smuzhiyun const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
59*4882a593Smuzhiyun struct list_head mnt_list;
60*4882a593Smuzhiyun struct list_head mnt_expire; /* link in fs-specific expiry list */
61*4882a593Smuzhiyun struct list_head mnt_share; /* circular list of shared mounts */
62*4882a593Smuzhiyun struct list_head mnt_slave_list;/* list of slave mounts */
63*4882a593Smuzhiyun struct list_head mnt_slave; /* slave list entry */
64*4882a593Smuzhiyun struct mount *mnt_master; /* slave is on master->mnt_slave_list */
65*4882a593Smuzhiyun struct mnt_namespace *mnt_ns; /* containing namespace */
66*4882a593Smuzhiyun struct mountpoint *mnt_mp; /* where is it mounted */
67*4882a593Smuzhiyun union {
68*4882a593Smuzhiyun struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */
69*4882a593Smuzhiyun struct hlist_node mnt_umount;
70*4882a593Smuzhiyun };
71*4882a593Smuzhiyun struct list_head mnt_umounting; /* list entry for umount propagation */
72*4882a593Smuzhiyun #ifdef CONFIG_FSNOTIFY
73*4882a593Smuzhiyun struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks;
74*4882a593Smuzhiyun __u32 mnt_fsnotify_mask;
75*4882a593Smuzhiyun #endif
76*4882a593Smuzhiyun int mnt_id; /* mount identifier */
77*4882a593Smuzhiyun int mnt_group_id; /* peer group identifier */
78*4882a593Smuzhiyun int mnt_expiry_mark; /* true if marked for expiry */
79*4882a593Smuzhiyun struct hlist_head mnt_pins;
80*4882a593Smuzhiyun struct hlist_head mnt_stuck_children;
81*4882a593Smuzhiyun } __randomize_layout;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
84*4882a593Smuzhiyun
real_mount(struct vfsmount * mnt)85*4882a593Smuzhiyun static inline struct mount *real_mount(struct vfsmount *mnt)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun return container_of(mnt, struct mount, mnt);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
mnt_has_parent(struct mount * mnt)90*4882a593Smuzhiyun static inline int mnt_has_parent(struct mount *mnt)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun return mnt != mnt->mnt_parent;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
is_mounted(struct vfsmount * mnt)95*4882a593Smuzhiyun static inline int is_mounted(struct vfsmount *mnt)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun /* neither detached nor internal? */
98*4882a593Smuzhiyun return !IS_ERR_OR_NULL(real_mount(mnt)->mnt_ns);
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun extern int __legitimize_mnt(struct vfsmount *, unsigned);
104*4882a593Smuzhiyun extern bool legitimize_mnt(struct vfsmount *, unsigned);
105*4882a593Smuzhiyun
__path_is_mountpoint(const struct path * path)106*4882a593Smuzhiyun static inline bool __path_is_mountpoint(const struct path *path)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun struct mount *m = __lookup_mnt(path->mnt, path->dentry);
109*4882a593Smuzhiyun return m && likely(!(m->mnt.mnt_flags & MNT_SYNC_UMOUNT));
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun extern void __detach_mounts(struct dentry *dentry);
113*4882a593Smuzhiyun
detach_mounts(struct dentry * dentry)114*4882a593Smuzhiyun static inline void detach_mounts(struct dentry *dentry)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun if (!d_mountpoint(dentry))
117*4882a593Smuzhiyun return;
118*4882a593Smuzhiyun __detach_mounts(dentry);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
get_mnt_ns(struct mnt_namespace * ns)121*4882a593Smuzhiyun static inline void get_mnt_ns(struct mnt_namespace *ns)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun atomic_inc(&ns->count);
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun extern seqlock_t mount_lock;
127*4882a593Smuzhiyun
lock_mount_hash(void)128*4882a593Smuzhiyun static inline void lock_mount_hash(void)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun write_seqlock(&mount_lock);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
unlock_mount_hash(void)133*4882a593Smuzhiyun static inline void unlock_mount_hash(void)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun write_sequnlock(&mount_lock);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun struct proc_mounts {
139*4882a593Smuzhiyun struct mnt_namespace *ns;
140*4882a593Smuzhiyun struct path root;
141*4882a593Smuzhiyun int (*show)(struct seq_file *, struct vfsmount *);
142*4882a593Smuzhiyun struct mount cursor;
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun extern const struct seq_operations mounts_op;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun extern bool __is_local_mountpoint(struct dentry *dentry);
is_local_mountpoint(struct dentry * dentry)148*4882a593Smuzhiyun static inline bool is_local_mountpoint(struct dentry *dentry)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun if (!d_mountpoint(dentry))
151*4882a593Smuzhiyun return false;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun return __is_local_mountpoint(dentry);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
is_anon_ns(struct mnt_namespace * ns)156*4882a593Smuzhiyun static inline bool is_anon_ns(struct mnt_namespace *ns)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun return ns->seq == 0;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun extern void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor);
162