18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#include <linux/mount.h> 38c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 48c2ecf20Sopenharmony_ci#include <linux/poll.h> 58c2ecf20Sopenharmony_ci#include <linux/ns_common.h> 68c2ecf20Sopenharmony_ci#include <linux/fs_pin.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_cistruct mnt_namespace { 98c2ecf20Sopenharmony_ci atomic_t count; 108c2ecf20Sopenharmony_ci struct ns_common ns; 118c2ecf20Sopenharmony_ci struct mount * root; 128c2ecf20Sopenharmony_ci /* 138c2ecf20Sopenharmony_ci * Traversal and modification of .list is protected by either 148c2ecf20Sopenharmony_ci * - taking namespace_sem for write, OR 158c2ecf20Sopenharmony_ci * - taking namespace_sem for read AND taking .ns_lock. 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci struct list_head list; 188c2ecf20Sopenharmony_ci spinlock_t ns_lock; 198c2ecf20Sopenharmony_ci struct user_namespace *user_ns; 208c2ecf20Sopenharmony_ci struct ucounts *ucounts; 218c2ecf20Sopenharmony_ci u64 seq; /* Sequence number to prevent loops */ 228c2ecf20Sopenharmony_ci wait_queue_head_t poll; 238c2ecf20Sopenharmony_ci u64 event; 248c2ecf20Sopenharmony_ci unsigned int mounts; /* # of mounts in the namespace */ 258c2ecf20Sopenharmony_ci unsigned int pending_mounts; 268c2ecf20Sopenharmony_ci} __randomize_layout; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistruct mnt_pcp { 298c2ecf20Sopenharmony_ci int mnt_count; 308c2ecf20Sopenharmony_ci int mnt_writers; 318c2ecf20Sopenharmony_ci}; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistruct mountpoint { 348c2ecf20Sopenharmony_ci struct hlist_node m_hash; 358c2ecf20Sopenharmony_ci struct dentry *m_dentry; 368c2ecf20Sopenharmony_ci struct hlist_head m_list; 378c2ecf20Sopenharmony_ci int m_count; 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistruct mount { 418c2ecf20Sopenharmony_ci struct hlist_node mnt_hash; 428c2ecf20Sopenharmony_ci struct mount *mnt_parent; 438c2ecf20Sopenharmony_ci struct dentry *mnt_mountpoint; 448c2ecf20Sopenharmony_ci struct vfsmount mnt; 458c2ecf20Sopenharmony_ci union { 468c2ecf20Sopenharmony_ci struct rcu_head mnt_rcu; 478c2ecf20Sopenharmony_ci struct llist_node mnt_llist; 488c2ecf20Sopenharmony_ci }; 498c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 508c2ecf20Sopenharmony_ci struct mnt_pcp __percpu *mnt_pcp; 518c2ecf20Sopenharmony_ci#else 528c2ecf20Sopenharmony_ci int mnt_count; 538c2ecf20Sopenharmony_ci int mnt_writers; 548c2ecf20Sopenharmony_ci#endif 558c2ecf20Sopenharmony_ci struct list_head mnt_mounts; /* list of children, anchored here */ 568c2ecf20Sopenharmony_ci struct list_head mnt_child; /* and going through their mnt_child */ 578c2ecf20Sopenharmony_ci struct list_head mnt_instance; /* mount instance on sb->s_mounts */ 588c2ecf20Sopenharmony_ci const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ 598c2ecf20Sopenharmony_ci struct list_head mnt_list; 608c2ecf20Sopenharmony_ci struct list_head mnt_expire; /* link in fs-specific expiry list */ 618c2ecf20Sopenharmony_ci struct list_head mnt_share; /* circular list of shared mounts */ 628c2ecf20Sopenharmony_ci struct list_head mnt_slave_list;/* list of slave mounts */ 638c2ecf20Sopenharmony_ci struct list_head mnt_slave; /* slave list entry */ 648c2ecf20Sopenharmony_ci struct mount *mnt_master; /* slave is on master->mnt_slave_list */ 658c2ecf20Sopenharmony_ci struct mnt_namespace *mnt_ns; /* containing namespace */ 668c2ecf20Sopenharmony_ci struct mountpoint *mnt_mp; /* where is it mounted */ 678c2ecf20Sopenharmony_ci union { 688c2ecf20Sopenharmony_ci struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */ 698c2ecf20Sopenharmony_ci struct hlist_node mnt_umount; 708c2ecf20Sopenharmony_ci }; 718c2ecf20Sopenharmony_ci struct list_head mnt_umounting; /* list entry for umount propagation */ 728c2ecf20Sopenharmony_ci#ifdef CONFIG_FSNOTIFY 738c2ecf20Sopenharmony_ci struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks; 748c2ecf20Sopenharmony_ci __u32 mnt_fsnotify_mask; 758c2ecf20Sopenharmony_ci#endif 768c2ecf20Sopenharmony_ci int mnt_id; /* mount identifier */ 778c2ecf20Sopenharmony_ci int mnt_group_id; /* peer group identifier */ 788c2ecf20Sopenharmony_ci int mnt_expiry_mark; /* true if marked for expiry */ 798c2ecf20Sopenharmony_ci struct hlist_head mnt_pins; 808c2ecf20Sopenharmony_ci struct hlist_head mnt_stuck_children; 818c2ecf20Sopenharmony_ci} __randomize_layout; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic inline struct mount *real_mount(struct vfsmount *mnt) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci return container_of(mnt, struct mount, mnt); 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic inline int mnt_has_parent(struct mount *mnt) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci return mnt != mnt->mnt_parent; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic inline int is_mounted(struct vfsmount *mnt) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci /* neither detached nor internal? */ 988c2ecf20Sopenharmony_ci return !IS_ERR_OR_NULL(real_mount(mnt)->mnt_ns); 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ciextern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ciextern int __legitimize_mnt(struct vfsmount *, unsigned); 1048c2ecf20Sopenharmony_ciextern bool legitimize_mnt(struct vfsmount *, unsigned); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic inline bool __path_is_mountpoint(const struct path *path) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci struct mount *m = __lookup_mnt(path->mnt, path->dentry); 1098c2ecf20Sopenharmony_ci return m && likely(!(m->mnt.mnt_flags & MNT_SYNC_UMOUNT)); 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ciextern void __detach_mounts(struct dentry *dentry); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic inline void detach_mounts(struct dentry *dentry) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci if (!d_mountpoint(dentry)) 1178c2ecf20Sopenharmony_ci return; 1188c2ecf20Sopenharmony_ci __detach_mounts(dentry); 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic inline void get_mnt_ns(struct mnt_namespace *ns) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci atomic_inc(&ns->count); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ciextern seqlock_t mount_lock; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistatic inline void lock_mount_hash(void) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci write_seqlock(&mount_lock); 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic inline void unlock_mount_hash(void) 1348c2ecf20Sopenharmony_ci{ 1358c2ecf20Sopenharmony_ci write_sequnlock(&mount_lock); 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct proc_mounts { 1398c2ecf20Sopenharmony_ci struct mnt_namespace *ns; 1408c2ecf20Sopenharmony_ci struct path root; 1418c2ecf20Sopenharmony_ci int (*show)(struct seq_file *, struct vfsmount *); 1428c2ecf20Sopenharmony_ci struct mount cursor; 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ciextern const struct seq_operations mounts_op; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ciextern bool __is_local_mountpoint(struct dentry *dentry); 1488c2ecf20Sopenharmony_cistatic inline bool is_local_mountpoint(struct dentry *dentry) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci if (!d_mountpoint(dentry)) 1518c2ecf20Sopenharmony_ci return false; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci return __is_local_mountpoint(dentry); 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic inline bool is_anon_ns(struct mnt_namespace *ns) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci return ns->seq == 0; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ciextern void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor); 162