VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   35 Branches   59 Tags
b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100   1) // SPDX-License-Identifier: GPL-2.0
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   2) /*
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   3)  * fs/proc_namespace.c - handling of /proc/<pid>/{mounts,mountinfo,mountstats}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   4)  *
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   5)  * In fact, that's a piece of procfs; it's *almost* isolated from
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   6)  * the rest of fs/proc, but has rather close relationships with
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   7)  * fs/namespace.c, thus here instead of fs/proc
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   8)  *
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500   9)  */
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  10) #include <linux/mnt_namespace.h>
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  11) #include <linux/nsproxy.h>
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  12) #include <linux/security.h>
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  13) #include <linux/fs_struct.h>
f719ff9bcee2a (Ingo Molnar        2017-02-06 10:57:33 +0100  14) #include <linux/sched/task.h>
f719ff9bcee2a (Ingo Molnar        2017-02-06 10:57:33 +0100  15) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  16) #include "proc/internal.h" /* only for get_proc_task() in ->open() */
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  17) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  18) #include "pnode.h"
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  19) #include "internal.h"
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  20) 
076ccb76e1a6c (Al Viro            2017-07-03 01:02:18 -0400  21) static __poll_t mounts_poll(struct file *file, poll_table *wait)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  22) {
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700  23) 	struct seq_file *m = file->private_data;
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700  24) 	struct proc_mounts *p = m->private;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  25) 	struct mnt_namespace *ns = p->ns;
a9a08845e9acb (Linus Torvalds     2018-02-11 14:34:03 -0800  26) 	__poll_t res = EPOLLIN | EPOLLRDNORM;
aab407fc5c0ce (Al Viro            2013-09-29 10:59:59 -0400  27) 	int event;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  28) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  29) 	poll_wait(file, &p->ns->poll, wait);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  30) 
6aa7de059173a (Mark Rutland       2017-10-23 14:07:29 -0700  31) 	event = READ_ONCE(ns->event);
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700  32) 	if (m->poll_event != event) {
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700  33) 		m->poll_event = event;
a9a08845e9acb (Linus Torvalds     2018-02-11 14:34:03 -0800  34) 		res |= EPOLLERR | EPOLLPRI;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  35) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  36) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  37) 	return res;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  38) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  39) 
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  40) struct proc_fs_opts {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  41) 	int flag;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  42) 	const char *str;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  43) };
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  44) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  45) static int show_sb_opts(struct seq_file *m, struct super_block *sb)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  46) {
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  47) 	static const struct proc_fs_opts fs_opts[] = {
1751e8a6cb935 (Linus Torvalds     2017-11-27 13:05:09 -0800  48) 		{ SB_SYNCHRONOUS, ",sync" },
1751e8a6cb935 (Linus Torvalds     2017-11-27 13:05:09 -0800  49) 		{ SB_DIRSYNC, ",dirsync" },
1751e8a6cb935 (Linus Torvalds     2017-11-27 13:05:09 -0800  50) 		{ SB_MANDLOCK, ",mand" },
1751e8a6cb935 (Linus Torvalds     2017-11-27 13:05:09 -0800  51) 		{ SB_LAZYTIME, ",lazytime" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  52) 		{ 0, NULL }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  53) 	};
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  54) 	const struct proc_fs_opts *fs_infop;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  55) 
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  56) 	for (fs_infop = fs_opts; fs_infop->flag; fs_infop++) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  57) 		if (sb->s_flags & fs_infop->flag)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  58) 			seq_puts(m, fs_infop->str);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  59) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  60) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  61) 	return security_sb_show_options(m, sb);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  62) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  63) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  64) static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  65) {
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  66) 	static const struct proc_fs_opts mnt_opts[] = {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  67) 		{ MNT_NOSUID, ",nosuid" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  68) 		{ MNT_NODEV, ",nodev" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  69) 		{ MNT_NOEXEC, ",noexec" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  70) 		{ MNT_NOATIME, ",noatime" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  71) 		{ MNT_NODIRATIME, ",nodiratime" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  72) 		{ MNT_RELATIME, ",relatime" },
dab741e0e02bd (Mattias Nissler    2020-08-27 11:09:46 -0600  73) 		{ MNT_NOSYMFOLLOW, ",nosymfollow" },
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  74) 		{ 0, NULL }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  75) 	};
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  76) 	const struct proc_fs_opts *fs_infop;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  77) 
1e88c420190be (Alexey Gladkov     2020-04-19 16:10:51 +0200  78) 	for (fs_infop = mnt_opts; fs_infop->flag; fs_infop++) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  79) 		if (mnt->mnt_flags & fs_infop->flag)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  80) 			seq_puts(m, fs_infop->str);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  81) 	}
9caccd41541a6 (Christian Brauner  2021-01-21 14:19:54 +0100  82) 
9caccd41541a6 (Christian Brauner  2021-01-21 14:19:54 +0100  83) 	if (mnt_user_ns(mnt) != &init_user_ns)
9caccd41541a6 (Christian Brauner  2021-01-21 14:19:54 +0100  84) 		seq_puts(m, ",idmapped");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  85) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  86) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  87) static inline void mangle(struct seq_file *m, const char *s)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  88) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  89) 	seq_escape(m, s, " \t\n\\");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  90) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  91) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  92) static void show_type(struct seq_file *m, struct super_block *sb)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  93) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  94) 	mangle(m, sb->s_type->name);
c7eb6869632a5 (David Howells      2019-03-25 16:38:31 +0000  95) 	if (sb->s_subtype) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  96) 		seq_putc(m, '.');
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  97) 		mangle(m, sb->s_subtype);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  98) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500  99) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 100) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 101) static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 102) {
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 103) 	struct proc_mounts *p = m->private;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 104) 	struct mount *r = real_mount(mnt);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 105) 	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 106) 	struct super_block *sb = mnt_path.dentry->d_sb;
5d9f3c7b620f6 (Dmitry V. Levin    2015-11-19 00:57:52 +0300 107) 	int err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 108) 
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 109) 	if (sb->s_op->show_devname) {
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 110) 		err = sb->s_op->show_devname(m, mnt_path.dentry);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 111) 		if (err)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 112) 			goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 113) 	} else {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 114) 		mangle(m, r->mnt_devname ? r->mnt_devname : "none");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 115) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 116) 	seq_putc(m, ' ');
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 117) 	/* mountpoints outside of chroot jail will give SEQ_SKIP on this */
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 118) 	err = seq_path_root(m, &mnt_path, &p->root, " \t\n\\");
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 119) 	if (err)
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 120) 		goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 121) 	seq_putc(m, ' ');
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 122) 	show_type(m, sb);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 123) 	seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 124) 	err = show_sb_opts(m, sb);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 125) 	if (err)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 126) 		goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 127) 	show_mnt_opts(m, mnt);
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 128) 	if (sb->s_op->show_options)
34c80b1d93e6e (Al Viro            2011-12-08 21:32:45 -0500 129) 		err = sb->s_op->show_options(m, mnt_path.dentry);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 130) 	seq_puts(m, " 0 0\n");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 131) out:
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 132) 	return err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 133) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 134) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 135) static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 136) {
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 137) 	struct proc_mounts *p = m->private;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 138) 	struct mount *r = real_mount(mnt);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 139) 	struct super_block *sb = mnt->mnt_sb;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 140) 	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 141) 	int err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 142) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 143) 	seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 144) 		   MAJOR(sb->s_dev), MINOR(sb->s_dev));
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 145) 	if (sb->s_op->show_path) {
a6322de67b58a (Al Viro            2011-12-08 21:37:57 -0500 146) 		err = sb->s_op->show_path(m, mnt->mnt_root);
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 147) 		if (err)
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 148) 			goto out;
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 149) 	} else {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 150) 		seq_dentry(m, mnt->mnt_root, " \t\n\\");
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 151) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 152) 	seq_putc(m, ' ');
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 153) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 154) 	/* mountpoints outside of chroot jail will give SEQ_SKIP on this */
9ad4dc4f73180 (Dmitry V. Levin    2012-10-17 20:29:36 +0400 155) 	err = seq_path_root(m, &mnt_path, &p->root, " \t\n\\");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 156) 	if (err)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 157) 		goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 158) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 159) 	seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 160) 	show_mnt_opts(m, mnt);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 161) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 162) 	/* Tagged fields ("foo:X" or "bar") */
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 163) 	if (IS_MNT_SHARED(r))
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 164) 		seq_printf(m, " shared:%i", r->mnt_group_id);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 165) 	if (IS_MNT_SLAVE(r)) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 166) 		int master = r->mnt_master->mnt_group_id;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 167) 		int dom = get_dominating_id(r, &p->root);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 168) 		seq_printf(m, " master:%i", master);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 169) 		if (dom && dom != master)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 170) 			seq_printf(m, " propagate_from:%i", dom);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 171) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 172) 	if (IS_MNT_UNBINDABLE(r))
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 173) 		seq_puts(m, " unbindable");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 174) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 175) 	/* Filesystem specific data */
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 176) 	seq_puts(m, " - ");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 177) 	show_type(m, sb);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 178) 	seq_putc(m, ' ');
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 179) 	if (sb->s_op->show_devname) {
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 180) 		err = sb->s_op->show_devname(m, mnt->mnt_root);
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 181) 		if (err)
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 182) 			goto out;
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 183) 	} else {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 184) 		mangle(m, r->mnt_devname ? r->mnt_devname : "none");
6ce4bca0adfde (Dmitry V. Levin    2015-11-19 00:58:20 +0300 185) 	}
bc98a42c1f7d0 (David Howells      2017-07-17 08:45:34 +0100 186) 	seq_puts(m, sb_rdonly(sb) ? " ro" : " rw");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 187) 	err = show_sb_opts(m, sb);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 188) 	if (err)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 189) 		goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 190) 	if (sb->s_op->show_options)
34c80b1d93e6e (Al Viro            2011-12-08 21:32:45 -0500 191) 		err = sb->s_op->show_options(m, mnt->mnt_root);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 192) 	seq_putc(m, '\n');
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 193) out:
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 194) 	return err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 195) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 196) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 197) static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 198) {
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 199) 	struct proc_mounts *p = m->private;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 200) 	struct mount *r = real_mount(mnt);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 201) 	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
64132379d5091 (Al Viro            2011-12-08 20:51:13 -0500 202) 	struct super_block *sb = mnt_path.dentry->d_sb;
b896fb35ca904 (Dmitry V. Levin    2015-11-19 00:58:32 +0300 203) 	int err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 204) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 205) 	/* device */
64132379d5091 (Al Viro            2011-12-08 20:51:13 -0500 206) 	if (sb->s_op->show_devname) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 207) 		seq_puts(m, "device ");
d861c630e99fe (Al Viro            2011-12-08 21:32:45 -0500 208) 		err = sb->s_op->show_devname(m, mnt_path.dentry);
5f8d498d4364f (Dmitry V. Levin    2015-03-19 11:10:54 +0000 209) 		if (err)
5f8d498d4364f (Dmitry V. Levin    2015-03-19 11:10:54 +0000 210) 			goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 211) 	} else {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 212) 		if (r->mnt_devname) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 213) 			seq_puts(m, "device ");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 214) 			mangle(m, r->mnt_devname);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 215) 		} else
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 216) 			seq_puts(m, "no device");
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 217) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 218) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 219) 	/* mount point */
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 220) 	seq_puts(m, " mounted on ");
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 221) 	/* mountpoints outside of chroot jail will give SEQ_SKIP on this */
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 222) 	err = seq_path_root(m, &mnt_path, &p->root, " \t\n\\");
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 223) 	if (err)
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 224) 		goto out;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 225) 	seq_putc(m, ' ');
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 226) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 227) 	/* file system type */
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 228) 	seq_puts(m, "with fstype ");
64132379d5091 (Al Viro            2011-12-08 20:51:13 -0500 229) 	show_type(m, sb);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 230) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 231) 	/* optional statistics */
64132379d5091 (Al Viro            2011-12-08 20:51:13 -0500 232) 	if (sb->s_op->show_stats) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 233) 		seq_putc(m, ' ');
b896fb35ca904 (Dmitry V. Levin    2015-11-19 00:58:32 +0300 234) 		err = sb->s_op->show_stats(m, mnt_path.dentry);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 235) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 236) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 237) 	seq_putc(m, '\n');
9d4d65748a5ca (Dmitry V. Levin    2014-12-16 06:59:37 +0300 238) out:
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 239) 	return err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 240) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 241) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 242) static int mounts_open_common(struct inode *inode, struct file *file,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 243) 			      int (*show)(struct seq_file *, struct vfsmount *))
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 244) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 245) 	struct task_struct *task = get_proc_task(inode);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 246) 	struct nsproxy *nsp;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 247) 	struct mnt_namespace *ns = NULL;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 248) 	struct path root;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 249) 	struct proc_mounts *p;
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 250) 	struct seq_file *m;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 251) 	int ret = -EINVAL;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 252) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 253) 	if (!task)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 254) 		goto err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 255) 
728dba3a39c66 (Eric W. Biederman  2014-02-03 19:13:49 -0800 256) 	task_lock(task);
728dba3a39c66 (Eric W. Biederman  2014-02-03 19:13:49 -0800 257) 	nsp = task->nsproxy;
3d93116cef306 (Axel Lin           2014-01-23 15:55:44 -0800 258) 	if (!nsp || !nsp->mnt_ns) {
728dba3a39c66 (Eric W. Biederman  2014-02-03 19:13:49 -0800 259) 		task_unlock(task);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 260) 		put_task_struct(task);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 261) 		goto err;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 262) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 263) 	ns = nsp->mnt_ns;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 264) 	get_mnt_ns(ns);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 265) 	if (!task->fs) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 266) 		task_unlock(task);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 267) 		put_task_struct(task);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 268) 		ret = -ENOENT;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 269) 		goto err_put_ns;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 270) 	}
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 271) 	get_fs_root(task->fs, &root);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 272) 	task_unlock(task);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 273) 	put_task_struct(task);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 274) 
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 275) 	ret = seq_open_private(file, &mounts_op, sizeof(struct proc_mounts));
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 276) 	if (ret)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 277) 		goto err_put_path;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 278) 
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 279) 	m = file->private_data;
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 280) 	m->poll_event = ns->event;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 281) 
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 282) 	p = m->private;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 283) 	p->ns = ns;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 284) 	p->root = root;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 285) 	p->show = show;
9f6c61f96f2d9 (Miklos Szeredi     2020-05-14 16:44:24 +0200 286) 	INIT_LIST_HEAD(&p->cursor.mnt_list);
9f6c61f96f2d9 (Miklos Szeredi     2020-05-14 16:44:24 +0200 287) 	p->cursor.mnt.mnt_flags = MNT_CURSOR;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 288) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 289) 	return 0;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 290) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 291)  err_put_path:
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 292) 	path_put(&root);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 293)  err_put_ns:
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 294) 	put_mnt_ns(ns);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 295)  err:
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 296) 	return ret;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 297) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 298) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 299) static int mounts_release(struct inode *inode, struct file *file)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 300) {
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 301) 	struct seq_file *m = file->private_data;
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 302) 	struct proc_mounts *p = m->private;
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 303) 	path_put(&p->root);
9f6c61f96f2d9 (Miklos Szeredi     2020-05-14 16:44:24 +0200 304) 	mnt_cursor_del(p->ns, &p->cursor);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 305) 	put_mnt_ns(p->ns);
ede1bf0dcff2b (Yann Droneaud      2015-06-30 14:57:30 -0700 306) 	return seq_release_private(inode, file);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 307) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 308) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 309) static int mounts_open(struct inode *inode, struct file *file)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 310) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 311) 	return mounts_open_common(inode, file, show_vfsmnt);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 312) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 313) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 314) static int mountinfo_open(struct inode *inode, struct file *file)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 315) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 316) 	return mounts_open_common(inode, file, show_mountinfo);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 317) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 318) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 319) static int mountstats_open(struct inode *inode, struct file *file)
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 320) {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 321) 	return mounts_open_common(inode, file, show_vfsstat);
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 322) }
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 323) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 324) const struct file_operations proc_mounts_operations = {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 325) 	.open		= mounts_open,
14e3e989f6a5d (Linus Torvalds     2020-12-27 10:56:33 -0800 326) 	.read_iter	= seq_read_iter,
14e3e989f6a5d (Linus Torvalds     2020-12-27 10:56:33 -0800 327) 	.splice_read	= generic_file_splice_read,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 328) 	.llseek		= seq_lseek,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 329) 	.release	= mounts_release,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 330) 	.poll		= mounts_poll,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 331) };
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 332) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 333) const struct file_operations proc_mountinfo_operations = {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 334) 	.open		= mountinfo_open,
14e3e989f6a5d (Linus Torvalds     2020-12-27 10:56:33 -0800 335) 	.read_iter	= seq_read_iter,
14e3e989f6a5d (Linus Torvalds     2020-12-27 10:56:33 -0800 336) 	.splice_read	= generic_file_splice_read,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 337) 	.llseek		= seq_lseek,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 338) 	.release	= mounts_release,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 339) 	.poll		= mounts_poll,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 340) };
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 341) 
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 342) const struct file_operations proc_mountstats_operations = {
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 343) 	.open		= mountstats_open,
14e3e989f6a5d (Linus Torvalds     2020-12-27 10:56:33 -0800 344) 	.read_iter	= seq_read_iter,
14e3e989f6a5d (Linus Torvalds     2020-12-27 10:56:33 -0800 345) 	.splice_read	= generic_file_splice_read,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 346) 	.llseek		= seq_lseek,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 347) 	.release	= mounts_release,
0226f4923f6c9 (Al Viro            2011-12-06 12:21:54 -0500 348) };