Loading Documentation/filesystems/proc.txt +6 −0 Original line number Diff line number Diff line Loading @@ -2374,8 +2374,14 @@ possible optional fields are: shared:X mount is shared in peer group X master:X mount is slave to peer group X propagate_from:X mount is slave and receives propagation from peer group X (*) unbindable mount is unbindable (*) X is the closest dominant peer group under the process's root. If X is the immediate master of the mount, or if there's no dominant peer group under the same root, then only the "master:X" field is present and not the "propagate_from:X" field. For more information on mount propagation see: Documentation/filesystems/sharedsubtree.txt Loading fs/namespace.c +7 −2 Original line number Diff line number Diff line Loading @@ -850,8 +850,13 @@ static int show_mountinfo(struct seq_file *m, void *v) /* Tagged fields ("foo:X" or "bar") */ if (IS_MNT_SHARED(mnt)) seq_printf(m, " shared:%i", mnt->mnt_group_id); if (IS_MNT_SLAVE(mnt)) seq_printf(m, " master:%i", mnt->mnt_master->mnt_group_id); if (IS_MNT_SLAVE(mnt)) { int master = mnt->mnt_master->mnt_group_id; int dom = get_dominating_id(mnt, &p->root); seq_printf(m, " master:%i", master); if (dom && dom != master) seq_printf(m, " propagate_from:%i", dom); } if (IS_MNT_UNBINDABLE(mnt)) seq_puts(m, " unbindable"); Loading fs/pnode.c +51 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,57 @@ static inline struct vfsmount *next_slave(struct vfsmount *p) return list_entry(p->mnt_slave.next, struct vfsmount, mnt_slave); } /* * Return true if path is reachable from root * * namespace_sem is held, and mnt is attached */ static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, const struct path *root) { while (mnt != root->mnt && mnt->mnt_parent != mnt) { dentry = mnt->mnt_mountpoint; mnt = mnt->mnt_parent; } return mnt == root->mnt && is_subdir(dentry, root->dentry); } static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, struct mnt_namespace *ns, const struct path *root) { struct vfsmount *m = mnt; do { /* Check the namespace first for optimization */ if (m->mnt_ns == ns && is_path_reachable(m, m->mnt_root, root)) return m; m = next_peer(m); } while (m != mnt); return NULL; } /* * Get ID of closest dominating peer group having a representative * under the given root. * * Caller must hold namespace_sem */ int get_dominating_id(struct vfsmount *mnt, const struct path *root) { struct vfsmount *m; for (m = mnt->mnt_master; m != NULL; m = m->mnt_master) { struct vfsmount *d = get_peer_under_root(m, mnt->mnt_ns, root); if (d) return d->mnt_group_id; } return 0; } static int do_make_slave(struct vfsmount *mnt) { struct vfsmount *peer_mnt = mnt, *master = mnt->mnt_master; Loading fs/pnode.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,5 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, int propagate_umount(struct list_head *); int propagate_mount_busy(struct vfsmount *, int); void mnt_release_group_id(struct vfsmount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); #endif /* _LINUX_PNODE_H */ Loading
Documentation/filesystems/proc.txt +6 −0 Original line number Diff line number Diff line Loading @@ -2374,8 +2374,14 @@ possible optional fields are: shared:X mount is shared in peer group X master:X mount is slave to peer group X propagate_from:X mount is slave and receives propagation from peer group X (*) unbindable mount is unbindable (*) X is the closest dominant peer group under the process's root. If X is the immediate master of the mount, or if there's no dominant peer group under the same root, then only the "master:X" field is present and not the "propagate_from:X" field. For more information on mount propagation see: Documentation/filesystems/sharedsubtree.txt Loading
fs/namespace.c +7 −2 Original line number Diff line number Diff line Loading @@ -850,8 +850,13 @@ static int show_mountinfo(struct seq_file *m, void *v) /* Tagged fields ("foo:X" or "bar") */ if (IS_MNT_SHARED(mnt)) seq_printf(m, " shared:%i", mnt->mnt_group_id); if (IS_MNT_SLAVE(mnt)) seq_printf(m, " master:%i", mnt->mnt_master->mnt_group_id); if (IS_MNT_SLAVE(mnt)) { int master = mnt->mnt_master->mnt_group_id; int dom = get_dominating_id(mnt, &p->root); seq_printf(m, " master:%i", master); if (dom && dom != master) seq_printf(m, " propagate_from:%i", dom); } if (IS_MNT_UNBINDABLE(mnt)) seq_puts(m, " unbindable"); Loading
fs/pnode.c +51 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,57 @@ static inline struct vfsmount *next_slave(struct vfsmount *p) return list_entry(p->mnt_slave.next, struct vfsmount, mnt_slave); } /* * Return true if path is reachable from root * * namespace_sem is held, and mnt is attached */ static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, const struct path *root) { while (mnt != root->mnt && mnt->mnt_parent != mnt) { dentry = mnt->mnt_mountpoint; mnt = mnt->mnt_parent; } return mnt == root->mnt && is_subdir(dentry, root->dentry); } static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, struct mnt_namespace *ns, const struct path *root) { struct vfsmount *m = mnt; do { /* Check the namespace first for optimization */ if (m->mnt_ns == ns && is_path_reachable(m, m->mnt_root, root)) return m; m = next_peer(m); } while (m != mnt); return NULL; } /* * Get ID of closest dominating peer group having a representative * under the given root. * * Caller must hold namespace_sem */ int get_dominating_id(struct vfsmount *mnt, const struct path *root) { struct vfsmount *m; for (m = mnt->mnt_master; m != NULL; m = m->mnt_master) { struct vfsmount *d = get_peer_under_root(m, mnt->mnt_ns, root); if (d) return d->mnt_group_id; } return 0; } static int do_make_slave(struct vfsmount *mnt) { struct vfsmount *peer_mnt = mnt, *master = mnt->mnt_master; Loading
fs/pnode.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,5 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, int propagate_umount(struct list_head *); int propagate_mount_busy(struct vfsmount *, int); void mnt_release_group_id(struct vfsmount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); #endif /* _LINUX_PNODE_H */