2 * fs/proc_namespace.c - handling of /proc/<pid>/{mounts,mountinfo,mountstats}
4 * In fact, that's a piece of procfs; it's *almost* isolated from
5 * the rest of fs/proc, but has rather close relationships with
6 * fs/namespace.c, thus here instead of fs/proc
9 #include <linux/mnt_namespace.h>
10 #include <linux/nsproxy.h>
11 #include <linux/security.h>
12 #include <linux/fs_struct.h>
13 #include "proc/internal.h" /* only for get_proc_task() in ->open() */
18 static unsigned mounts_poll(struct file
*file
, poll_table
*wait
)
20 struct proc_mounts
*p
= file
->private_data
;
21 struct mnt_namespace
*ns
= p
->ns
;
22 unsigned res
= POLLIN
| POLLRDNORM
;
24 poll_wait(file
, &p
->ns
->poll
, wait
);
26 br_read_lock(vfsmount_lock
);
27 if (p
->m
.poll_event
!= ns
->event
) {
28 p
->m
.poll_event
= ns
->event
;
29 res
|= POLLERR
| POLLPRI
;
31 br_read_unlock(vfsmount_lock
);
41 static int show_sb_opts(struct seq_file
*m
, struct super_block
*sb
)
43 static const struct proc_fs_info fs_info
[] = {
44 { MS_SYNCHRONOUS
, ",sync" },
45 { MS_DIRSYNC
, ",dirsync" },
46 { MS_MANDLOCK
, ",mand" },
49 const struct proc_fs_info
*fs_infop
;
51 for (fs_infop
= fs_info
; fs_infop
->flag
; fs_infop
++) {
52 if (sb
->s_flags
& fs_infop
->flag
)
53 seq_puts(m
, fs_infop
->str
);
56 return security_sb_show_options(m
, sb
);
59 static void show_mnt_opts(struct seq_file
*m
, struct vfsmount
*mnt
)
61 static const struct proc_fs_info mnt_info
[] = {
62 { MNT_NOSUID
, ",nosuid" },
63 { MNT_NODEV
, ",nodev" },
64 { MNT_NOEXEC
, ",noexec" },
65 { MNT_NOATIME
, ",noatime" },
66 { MNT_NODIRATIME
, ",nodiratime" },
67 { MNT_RELATIME
, ",relatime" },
70 const struct proc_fs_info
*fs_infop
;
72 for (fs_infop
= mnt_info
; fs_infop
->flag
; fs_infop
++) {
73 if (mnt
->mnt_flags
& fs_infop
->flag
)
74 seq_puts(m
, fs_infop
->str
);
78 static inline void mangle(struct seq_file
*m
, const char *s
)
80 seq_escape(m
, s
, " \t\n\\");
83 static void show_type(struct seq_file
*m
, struct super_block
*sb
)
85 mangle(m
, sb
->s_type
->name
);
86 if (sb
->s_subtype
&& sb
->s_subtype
[0]) {
88 mangle(m
, sb
->s_subtype
);
92 static int show_vfsmnt(struct seq_file
*m
, struct vfsmount
*mnt
)
94 struct mount
*r
= real_mount(mnt
);
96 struct path mnt_path
= { .dentry
= mnt
->mnt_root
, .mnt
= mnt
};
98 if (mnt
->mnt_sb
->s_op
->show_devname
) {
99 err
= mnt
->mnt_sb
->s_op
->show_devname(m
, mnt
);
103 mangle(m
, r
->mnt_devname
? r
->mnt_devname
: "none");
106 seq_path(m
, &mnt_path
, " \t\n\\");
108 show_type(m
, mnt
->mnt_sb
);
109 seq_puts(m
, __mnt_is_readonly(mnt
) ? " ro" : " rw");
110 err
= show_sb_opts(m
, mnt
->mnt_sb
);
113 show_mnt_opts(m
, mnt
);
114 if (mnt
->mnt_sb
->s_op
->show_options
)
115 err
= mnt
->mnt_sb
->s_op
->show_options(m
, mnt
);
116 seq_puts(m
, " 0 0\n");
121 static int show_mountinfo(struct seq_file
*m
, struct vfsmount
*mnt
)
123 struct proc_mounts
*p
= m
->private;
124 struct mount
*r
= real_mount(mnt
);
125 struct super_block
*sb
= mnt
->mnt_sb
;
126 struct path mnt_path
= { .dentry
= mnt
->mnt_root
, .mnt
= mnt
};
127 struct path root
= p
->root
;
130 seq_printf(m
, "%i %i %u:%u ", r
->mnt_id
, r
->mnt_parent
->mnt_id
,
131 MAJOR(sb
->s_dev
), MINOR(sb
->s_dev
));
132 if (sb
->s_op
->show_path
)
133 err
= sb
->s_op
->show_path(m
, mnt
);
135 seq_dentry(m
, mnt
->mnt_root
, " \t\n\\");
140 /* mountpoints outside of chroot jail will give SEQ_SKIP on this */
141 err
= seq_path_root(m
, &mnt_path
, &root
, " \t\n\\");
145 seq_puts(m
, mnt
->mnt_flags
& MNT_READONLY
? " ro" : " rw");
146 show_mnt_opts(m
, mnt
);
148 /* Tagged fields ("foo:X" or "bar") */
149 if (IS_MNT_SHARED(r
))
150 seq_printf(m
, " shared:%i", r
->mnt_group_id
);
151 if (IS_MNT_SLAVE(r
)) {
152 int master
= r
->mnt_master
->mnt_group_id
;
153 int dom
= get_dominating_id(r
, &p
->root
);
154 seq_printf(m
, " master:%i", master
);
155 if (dom
&& dom
!= master
)
156 seq_printf(m
, " propagate_from:%i", dom
);
158 if (IS_MNT_UNBINDABLE(r
))
159 seq_puts(m
, " unbindable");
161 /* Filesystem specific data */
165 if (sb
->s_op
->show_devname
)
166 err
= sb
->s_op
->show_devname(m
, mnt
);
168 mangle(m
, r
->mnt_devname
? r
->mnt_devname
: "none");
171 seq_puts(m
, sb
->s_flags
& MS_RDONLY
? " ro" : " rw");
172 err
= show_sb_opts(m
, sb
);
175 if (sb
->s_op
->show_options
)
176 err
= sb
->s_op
->show_options(m
, mnt
);
182 static int show_vfsstat(struct seq_file
*m
, struct vfsmount
*mnt
)
184 struct mount
*r
= real_mount(mnt
);
185 struct path mnt_path
= { .dentry
= mnt
->mnt_root
, .mnt
= mnt
};
189 if (mnt
->mnt_sb
->s_op
->show_devname
) {
190 seq_puts(m
, "device ");
191 err
= mnt
->mnt_sb
->s_op
->show_devname(m
, mnt
);
193 if (r
->mnt_devname
) {
194 seq_puts(m
, "device ");
195 mangle(m
, r
->mnt_devname
);
197 seq_puts(m
, "no device");
201 seq_puts(m
, " mounted on ");
202 seq_path(m
, &mnt_path
, " \t\n\\");
205 /* file system type */
206 seq_puts(m
, "with fstype ");
207 show_type(m
, mnt
->mnt_sb
);
209 /* optional statistics */
210 if (mnt
->mnt_sb
->s_op
->show_stats
) {
213 err
= mnt
->mnt_sb
->s_op
->show_stats(m
, mnt
);
220 static int mounts_open_common(struct inode
*inode
, struct file
*file
,
221 int (*show
)(struct seq_file
*, struct vfsmount
*))
223 struct task_struct
*task
= get_proc_task(inode
);
225 struct mnt_namespace
*ns
= NULL
;
227 struct proc_mounts
*p
;
234 nsp
= task_nsproxy(task
);
237 put_task_struct(task
);
243 put_task_struct(task
);
251 put_task_struct(task
);
255 get_fs_root(task
->fs
, &root
);
257 put_task_struct(task
);
260 p
= kmalloc(sizeof(struct proc_mounts
), GFP_KERNEL
);
264 file
->private_data
= &p
->m
;
265 ret
= seq_open(file
, &mounts_op
);
272 p
->m
.poll_event
= ns
->event
;
287 static int mounts_release(struct inode
*inode
, struct file
*file
)
289 struct proc_mounts
*p
= file
->private_data
;
292 return seq_release(inode
, file
);
295 static int mounts_open(struct inode
*inode
, struct file
*file
)
297 return mounts_open_common(inode
, file
, show_vfsmnt
);
300 static int mountinfo_open(struct inode
*inode
, struct file
*file
)
302 return mounts_open_common(inode
, file
, show_mountinfo
);
305 static int mountstats_open(struct inode
*inode
, struct file
*file
)
307 return mounts_open_common(inode
, file
, show_vfsstat
);
310 const struct file_operations proc_mounts_operations
= {
314 .release
= mounts_release
,
318 const struct file_operations proc_mountinfo_operations
= {
319 .open
= mountinfo_open
,
322 .release
= mounts_release
,
326 const struct file_operations proc_mountstats_operations
= {
327 .open
= mountstats_open
,
330 .release
= mounts_release
,