xref: /openbmc/linux/fs/notify/fdinfo.c (revision aad29a73199b7fbccfbabea3f1ee627ad1924f52)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2be77196bSCyrill Gorcunov #include <linux/file.h>
3be77196bSCyrill Gorcunov #include <linux/fs.h>
4be77196bSCyrill Gorcunov #include <linux/fsnotify_backend.h>
5be77196bSCyrill Gorcunov #include <linux/idr.h>
6be77196bSCyrill Gorcunov #include <linux/init.h>
7be77196bSCyrill Gorcunov #include <linux/inotify.h>
8be77196bSCyrill Gorcunov #include <linux/fanotify.h>
9be77196bSCyrill Gorcunov #include <linux/kernel.h>
10be77196bSCyrill Gorcunov #include <linux/namei.h>
11be77196bSCyrill Gorcunov #include <linux/sched.h>
12be77196bSCyrill Gorcunov #include <linux/types.h>
13be77196bSCyrill Gorcunov #include <linux/seq_file.h>
14be77196bSCyrill Gorcunov #include <linux/exportfs.h>
15be77196bSCyrill Gorcunov 
16be77196bSCyrill Gorcunov #include "inotify/inotify.h"
174adce25cSAmir Goldstein #include "fanotify/fanotify.h"
18d6f7aa98SEric Biggers #include "fdinfo.h"
1936f10f55SAmir Goldstein #include "fsnotify.h"
20be77196bSCyrill Gorcunov 
21be77196bSCyrill Gorcunov #if defined(CONFIG_PROC_FS)
22be77196bSCyrill Gorcunov 
23be77196bSCyrill Gorcunov #if defined(CONFIG_INOTIFY_USER) || defined(CONFIG_FANOTIFY)
24be77196bSCyrill Gorcunov 
show_fdinfo(struct seq_file * m,struct file * f,void (* show)(struct seq_file * m,struct fsnotify_mark * mark))25a3816ab0SJoe Perches static void show_fdinfo(struct seq_file *m, struct file *f,
26a3816ab0SJoe Perches 			void (*show)(struct seq_file *m,
27a3816ab0SJoe Perches 				     struct fsnotify_mark *mark))
28be77196bSCyrill Gorcunov {
29be77196bSCyrill Gorcunov 	struct fsnotify_group *group = f->private_data;
30be77196bSCyrill Gorcunov 	struct fsnotify_mark *mark;
31be77196bSCyrill Gorcunov 
3243b245a7SAmir Goldstein 	fsnotify_group_lock(group);
33be77196bSCyrill Gorcunov 	list_for_each_entry(mark, &group->marks_list, g_list) {
34a3816ab0SJoe Perches 		show(m, mark);
35a3816ab0SJoe Perches 		if (seq_has_overflowed(m))
36be77196bSCyrill Gorcunov 			break;
37be77196bSCyrill Gorcunov 	}
3843b245a7SAmir Goldstein 	fsnotify_group_unlock(group);
39be77196bSCyrill Gorcunov }
40be77196bSCyrill Gorcunov 
41be77196bSCyrill Gorcunov #if defined(CONFIG_EXPORTFS)
show_mark_fhandle(struct seq_file * m,struct inode * inode)42a3816ab0SJoe Perches static void show_mark_fhandle(struct seq_file *m, struct inode *inode)
43be77196bSCyrill Gorcunov {
44be77196bSCyrill Gorcunov 	struct {
45be77196bSCyrill Gorcunov 		struct file_handle handle;
461fc98d11SAndrey Vagin 		u8 pad[MAX_HANDLE_SZ];
47be77196bSCyrill Gorcunov 	} f;
48be77196bSCyrill Gorcunov 	int size, ret, i;
49be77196bSCyrill Gorcunov 
50be77196bSCyrill Gorcunov 	f.handle.handle_bytes = sizeof(f.pad);
51be77196bSCyrill Gorcunov 	size = f.handle.handle_bytes >> 2;
52be77196bSCyrill Gorcunov 
53304e9c83SAmir Goldstein 	ret = exportfs_encode_fid(inode, (struct fid *)f.handle.f_handle, &size);
54*f47c834aSAmir Goldstein 	if ((ret == FILEID_INVALID) || (ret < 0))
55a3816ab0SJoe Perches 		return;
56be77196bSCyrill Gorcunov 
57be77196bSCyrill Gorcunov 	f.handle.handle_type = ret;
58be77196bSCyrill Gorcunov 	f.handle.handle_bytes = size * sizeof(u32);
59be77196bSCyrill Gorcunov 
60a3816ab0SJoe Perches 	seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:",
61be77196bSCyrill Gorcunov 		   f.handle.handle_bytes, f.handle.handle_type);
62be77196bSCyrill Gorcunov 
63be77196bSCyrill Gorcunov 	for (i = 0; i < f.handle.handle_bytes; i++)
64a3816ab0SJoe Perches 		seq_printf(m, "%02x", (int)f.handle.f_handle[i]);
65be77196bSCyrill Gorcunov }
66be77196bSCyrill Gorcunov #else
show_mark_fhandle(struct seq_file * m,struct inode * inode)67a3816ab0SJoe Perches static void show_mark_fhandle(struct seq_file *m, struct inode *inode)
68be77196bSCyrill Gorcunov {
69be77196bSCyrill Gorcunov }
70be77196bSCyrill Gorcunov #endif
71be77196bSCyrill Gorcunov 
72be77196bSCyrill Gorcunov #ifdef CONFIG_INOTIFY_USER
73be77196bSCyrill Gorcunov 
inotify_fdinfo(struct seq_file * m,struct fsnotify_mark * mark)74a3816ab0SJoe Perches static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
75be77196bSCyrill Gorcunov {
76be77196bSCyrill Gorcunov 	struct inotify_inode_mark *inode_mark;
77be77196bSCyrill Gorcunov 	struct inode *inode;
78be77196bSCyrill Gorcunov 
79d6f7b98bSAmir Goldstein 	if (mark->connector->type != FSNOTIFY_OBJ_TYPE_INODE)
80a3816ab0SJoe Perches 		return;
81be77196bSCyrill Gorcunov 
82be77196bSCyrill Gorcunov 	inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
8336f10f55SAmir Goldstein 	inode = igrab(fsnotify_conn_inode(mark->connector));
84be77196bSCyrill Gorcunov 	if (inode) {
85a32e697cSAmir Goldstein 		seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:0 ",
86a3816ab0SJoe Perches 			   inode_mark->wd, inode->i_ino, inode->i_sb->s_dev,
87a32e697cSAmir Goldstein 			   inotify_mark_user_mask(mark));
88a3816ab0SJoe Perches 		show_mark_fhandle(m, inode);
89a3816ab0SJoe Perches 		seq_putc(m, '\n');
90be77196bSCyrill Gorcunov 		iput(inode);
91be77196bSCyrill Gorcunov 	}
92be77196bSCyrill Gorcunov }
93be77196bSCyrill Gorcunov 
inotify_show_fdinfo(struct seq_file * m,struct file * f)94a3816ab0SJoe Perches void inotify_show_fdinfo(struct seq_file *m, struct file *f)
95be77196bSCyrill Gorcunov {
96a3816ab0SJoe Perches 	show_fdinfo(m, f, inotify_fdinfo);
97be77196bSCyrill Gorcunov }
98be77196bSCyrill Gorcunov 
99be77196bSCyrill Gorcunov #endif /* CONFIG_INOTIFY_USER */
100be77196bSCyrill Gorcunov 
101be77196bSCyrill Gorcunov #ifdef CONFIG_FANOTIFY
102be77196bSCyrill Gorcunov 
fanotify_fdinfo(struct seq_file * m,struct fsnotify_mark * mark)103a3816ab0SJoe Perches static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
104be77196bSCyrill Gorcunov {
1054adce25cSAmir Goldstein 	unsigned int mflags = fanotify_mark_user_flags(mark);
106be77196bSCyrill Gorcunov 	struct inode *inode;
107be77196bSCyrill Gorcunov 
108d6f7b98bSAmir Goldstein 	if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
10936f10f55SAmir Goldstein 		inode = igrab(fsnotify_conn_inode(mark->connector));
110be77196bSCyrill Gorcunov 		if (!inode)
111a3816ab0SJoe Perches 			return;
112a3816ab0SJoe Perches 		seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ",
113be77196bSCyrill Gorcunov 			   inode->i_ino, inode->i_sb->s_dev,
11431a371e4SAmir Goldstein 			   mflags, mark->mask, mark->ignore_mask);
115a3816ab0SJoe Perches 		show_mark_fhandle(m, inode);
116a3816ab0SJoe Perches 		seq_putc(m, '\n');
117be77196bSCyrill Gorcunov 		iput(inode);
118d6f7b98bSAmir Goldstein 	} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
11936f10f55SAmir Goldstein 		struct mount *mnt = fsnotify_conn_mount(mark->connector);
120be77196bSCyrill Gorcunov 
121a3816ab0SJoe Perches 		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
12231a371e4SAmir Goldstein 			   mnt->mnt_id, mflags, mark->mask, mark->ignore_mask);
1231e6cb723SAmir Goldstein 	} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_SB) {
1241e6cb723SAmir Goldstein 		struct super_block *sb = fsnotify_conn_sb(mark->connector);
1251e6cb723SAmir Goldstein 
1261e6cb723SAmir Goldstein 		seq_printf(m, "fanotify sdev:%x mflags:%x mask:%x ignored_mask:%x\n",
12731a371e4SAmir Goldstein 			   sb->s_dev, mflags, mark->mask, mark->ignore_mask);
128be77196bSCyrill Gorcunov 	}
129be77196bSCyrill Gorcunov }
130be77196bSCyrill Gorcunov 
fanotify_show_fdinfo(struct seq_file * m,struct file * f)131a3816ab0SJoe Perches void fanotify_show_fdinfo(struct seq_file *m, struct file *f)
132be77196bSCyrill Gorcunov {
133be77196bSCyrill Gorcunov 	struct fsnotify_group *group = f->private_data;
134de8cd83eSSteve Grubb 
135be77196bSCyrill Gorcunov 	seq_printf(m, "fanotify flags:%x event-flags:%x\n",
136a8b98c80SAmir Goldstein 		   group->fanotify_data.flags & FANOTIFY_INIT_FLAGS,
1377cea2a3cSAmir Goldstein 		   group->fanotify_data.f_flags);
138be77196bSCyrill Gorcunov 
139a3816ab0SJoe Perches 	show_fdinfo(m, f, fanotify_fdinfo);
140be77196bSCyrill Gorcunov }
141be77196bSCyrill Gorcunov 
142be77196bSCyrill Gorcunov #endif /* CONFIG_FANOTIFY */
143be77196bSCyrill Gorcunov 
144be77196bSCyrill Gorcunov #endif /* CONFIG_INOTIFY_USER || CONFIG_FANOTIFY */
145be77196bSCyrill Gorcunov 
146be77196bSCyrill Gorcunov #endif /* CONFIG_PROC_FS */
147