Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[patch 7/7] vfs: mountinfo: show dominating group id

Show peer group ID of nearest dominating group that has intersection
with the mount's namespace.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Miklos Szeredi and committed by
Al Viro
97e7e0f7 2d4d4864

+65 -2
+6
Documentation/filesystems/proc.txt
··· 2374 2374 2375 2375 shared:X mount is shared in peer group X 2376 2376 master:X mount is slave to peer group X 2377 + propagate_from:X mount is slave and receives propagation from peer group X (*) 2377 2378 unbindable mount is unbindable 2379 + 2380 + (*) X is the closest dominant peer group under the process's root. If 2381 + X is the immediate master of the mount, or if there's no dominant peer 2382 + group under the same root, then only the "master:X" field is present 2383 + and not the "propagate_from:X" field. 2378 2384 2379 2385 For more information on mount propagation see: 2380 2386
+7 -2
fs/namespace.c
··· 850 850 /* Tagged fields ("foo:X" or "bar") */ 851 851 if (IS_MNT_SHARED(mnt)) 852 852 seq_printf(m, " shared:%i", mnt->mnt_group_id); 853 - if (IS_MNT_SLAVE(mnt)) 854 - seq_printf(m, " master:%i", mnt->mnt_master->mnt_group_id); 853 + if (IS_MNT_SLAVE(mnt)) { 854 + int master = mnt->mnt_master->mnt_group_id; 855 + int dom = get_dominating_id(mnt, &p->root); 856 + seq_printf(m, " master:%i", master); 857 + if (dom && dom != master) 858 + seq_printf(m, " propagate_from:%i", dom); 859 + } 855 860 if (IS_MNT_UNBINDABLE(mnt)) 856 861 seq_puts(m, " unbindable"); 857 862
+51
fs/pnode.c
··· 28 28 return list_entry(p->mnt_slave.next, struct vfsmount, mnt_slave); 29 29 } 30 30 31 + /* 32 + * Return true if path is reachable from root 33 + * 34 + * namespace_sem is held, and mnt is attached 35 + */ 36 + static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, 37 + const struct path *root) 38 + { 39 + while (mnt != root->mnt && mnt->mnt_parent != mnt) { 40 + dentry = mnt->mnt_mountpoint; 41 + mnt = mnt->mnt_parent; 42 + } 43 + return mnt == root->mnt && is_subdir(dentry, root->dentry); 44 + } 45 + 46 + static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, 47 + struct mnt_namespace *ns, 48 + const struct path *root) 49 + { 50 + struct vfsmount *m = mnt; 51 + 52 + do { 53 + /* Check the namespace first for optimization */ 54 + if (m->mnt_ns == ns && is_path_reachable(m, m->mnt_root, root)) 55 + return m; 56 + 57 + m = next_peer(m); 58 + } while (m != mnt); 59 + 60 + return NULL; 61 + } 62 + 63 + /* 64 + * Get ID of closest dominating peer group having a representative 65 + * under the given root. 66 + * 67 + * Caller must hold namespace_sem 68 + */ 69 + int get_dominating_id(struct vfsmount *mnt, const struct path *root) 70 + { 71 + struct vfsmount *m; 72 + 73 + for (m = mnt->mnt_master; m != NULL; m = m->mnt_master) { 74 + struct vfsmount *d = get_peer_under_root(m, mnt->mnt_ns, root); 75 + if (d) 76 + return d->mnt_group_id; 77 + } 78 + 79 + return 0; 80 + } 81 + 31 82 static int do_make_slave(struct vfsmount *mnt) 32 83 { 33 84 struct vfsmount *peer_mnt = mnt, *master = mnt->mnt_master;
+1
fs/pnode.h
··· 36 36 int propagate_umount(struct list_head *); 37 37 int propagate_mount_busy(struct vfsmount *, int); 38 38 void mnt_release_group_id(struct vfsmount *); 39 + int get_dominating_id(struct vfsmount *mnt, const struct path *root); 39 40 #endif /* _LINUX_PNODE_H */