Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #include <linux/mount.h>
0003 #include <linux/seq_file.h>
0004 #include <linux/poll.h>
0005 #include <linux/ns_common.h>
0006 #include <linux/fs_pin.h>
0007 
0008 struct mnt_namespace {
0009     struct ns_common    ns;
0010     struct mount *  root;
0011     /*
0012      * Traversal and modification of .list is protected by either
0013      * - taking namespace_sem for write, OR
0014      * - taking namespace_sem for read AND taking .ns_lock.
0015      */
0016     struct list_head    list;
0017     spinlock_t      ns_lock;
0018     struct user_namespace   *user_ns;
0019     struct ucounts      *ucounts;
0020     u64         seq;    /* Sequence number to prevent loops */
0021     wait_queue_head_t poll;
0022     u64 event;
0023     unsigned int        mounts; /* # of mounts in the namespace */
0024     unsigned int        pending_mounts;
0025 } __randomize_layout;
0026 
0027 struct mnt_pcp {
0028     int mnt_count;
0029     int mnt_writers;
0030 };
0031 
0032 struct mountpoint {
0033     struct hlist_node m_hash;
0034     struct dentry *m_dentry;
0035     struct hlist_head m_list;
0036     int m_count;
0037 };
0038 
0039 struct mount {
0040     struct hlist_node mnt_hash;
0041     struct mount *mnt_parent;
0042     struct dentry *mnt_mountpoint;
0043     struct vfsmount mnt;
0044     union {
0045         struct rcu_head mnt_rcu;
0046         struct llist_node mnt_llist;
0047     };
0048 #ifdef CONFIG_SMP
0049     struct mnt_pcp __percpu *mnt_pcp;
0050 #else
0051     int mnt_count;
0052     int mnt_writers;
0053 #endif
0054     struct list_head mnt_mounts;    /* list of children, anchored here */
0055     struct list_head mnt_child; /* and going through their mnt_child */
0056     struct list_head mnt_instance;  /* mount instance on sb->s_mounts */
0057     const char *mnt_devname;    /* Name of device e.g. /dev/dsk/hda1 */
0058     struct list_head mnt_list;
0059     struct list_head mnt_expire;    /* link in fs-specific expiry list */
0060     struct list_head mnt_share; /* circular list of shared mounts */
0061     struct list_head mnt_slave_list;/* list of slave mounts */
0062     struct list_head mnt_slave; /* slave list entry */
0063     struct mount *mnt_master;   /* slave is on master->mnt_slave_list */
0064     struct mnt_namespace *mnt_ns;   /* containing namespace */
0065     struct mountpoint *mnt_mp;  /* where is it mounted */
0066     union {
0067         struct hlist_node mnt_mp_list;  /* list mounts with the same mountpoint */
0068         struct hlist_node mnt_umount;
0069     };
0070     struct list_head mnt_umounting; /* list entry for umount propagation */
0071 #ifdef CONFIG_FSNOTIFY
0072     struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks;
0073     __u32 mnt_fsnotify_mask;
0074 #endif
0075     int mnt_id;         /* mount identifier */
0076     int mnt_group_id;       /* peer group identifier */
0077     int mnt_expiry_mark;        /* true if marked for expiry */
0078     struct hlist_head mnt_pins;
0079     struct hlist_head mnt_stuck_children;
0080 } __randomize_layout;
0081 
0082 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
0083 
0084 static inline struct mount *real_mount(struct vfsmount *mnt)
0085 {
0086     return container_of(mnt, struct mount, mnt);
0087 }
0088 
0089 static inline int mnt_has_parent(struct mount *mnt)
0090 {
0091     return mnt != mnt->mnt_parent;
0092 }
0093 
0094 static inline int is_mounted(struct vfsmount *mnt)
0095 {
0096     /* neither detached nor internal? */
0097     return !IS_ERR_OR_NULL(real_mount(mnt)->mnt_ns);
0098 }
0099 
0100 extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
0101 
0102 extern int __legitimize_mnt(struct vfsmount *, unsigned);
0103 
0104 static inline bool __path_is_mountpoint(const struct path *path)
0105 {
0106     struct mount *m = __lookup_mnt(path->mnt, path->dentry);
0107     return m && likely(!(m->mnt.mnt_flags & MNT_SYNC_UMOUNT));
0108 }
0109 
0110 extern void __detach_mounts(struct dentry *dentry);
0111 
0112 static inline void detach_mounts(struct dentry *dentry)
0113 {
0114     if (!d_mountpoint(dentry))
0115         return;
0116     __detach_mounts(dentry);
0117 }
0118 
0119 static inline void get_mnt_ns(struct mnt_namespace *ns)
0120 {
0121     refcount_inc(&ns->ns.count);
0122 }
0123 
0124 extern seqlock_t mount_lock;
0125 
0126 struct proc_mounts {
0127     struct mnt_namespace *ns;
0128     struct path root;
0129     int (*show)(struct seq_file *, struct vfsmount *);
0130     struct mount cursor;
0131 };
0132 
0133 extern const struct seq_operations mounts_op;
0134 
0135 extern bool __is_local_mountpoint(struct dentry *dentry);
0136 static inline bool is_local_mountpoint(struct dentry *dentry)
0137 {
0138     if (!d_mountpoint(dentry))
0139         return false;
0140 
0141     return __is_local_mountpoint(dentry);
0142 }
0143 
0144 static inline bool is_anon_ns(struct mnt_namespace *ns)
0145 {
0146     return ns->seq == 0;
0147 }
0148 
0149 extern void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor);