0001
0002 #include <linux/file.h>
0003 #include <linux/fs.h>
0004 #include <linux/fsnotify_backend.h>
0005 #include <linux/idr.h>
0006 #include <linux/init.h>
0007 #include <linux/inotify.h>
0008 #include <linux/fanotify.h>
0009 #include <linux/kernel.h>
0010 #include <linux/namei.h>
0011 #include <linux/sched.h>
0012 #include <linux/types.h>
0013 #include <linux/seq_file.h>
0014 #include <linux/exportfs.h>
0015
0016 #include "inotify/inotify.h"
0017 #include "fanotify/fanotify.h"
0018 #include "fdinfo.h"
0019 #include "fsnotify.h"
0020
0021 #if defined(CONFIG_PROC_FS)
0022
0023 #if defined(CONFIG_INOTIFY_USER) || defined(CONFIG_FANOTIFY)
0024
0025 static void show_fdinfo(struct seq_file *m, struct file *f,
0026 void (*show)(struct seq_file *m,
0027 struct fsnotify_mark *mark))
0028 {
0029 struct fsnotify_group *group = f->private_data;
0030 struct fsnotify_mark *mark;
0031
0032 fsnotify_group_lock(group);
0033 list_for_each_entry(mark, &group->marks_list, g_list) {
0034 show(m, mark);
0035 if (seq_has_overflowed(m))
0036 break;
0037 }
0038 fsnotify_group_unlock(group);
0039 }
0040
0041 #if defined(CONFIG_EXPORTFS)
0042 static void show_mark_fhandle(struct seq_file *m, struct inode *inode)
0043 {
0044 struct {
0045 struct file_handle handle;
0046 u8 pad[MAX_HANDLE_SZ];
0047 } f;
0048 int size, ret, i;
0049
0050 f.handle.handle_bytes = sizeof(f.pad);
0051 size = f.handle.handle_bytes >> 2;
0052
0053 ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, NULL);
0054 if ((ret == FILEID_INVALID) || (ret < 0)) {
0055 WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret);
0056 return;
0057 }
0058
0059 f.handle.handle_type = ret;
0060 f.handle.handle_bytes = size * sizeof(u32);
0061
0062 seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:",
0063 f.handle.handle_bytes, f.handle.handle_type);
0064
0065 for (i = 0; i < f.handle.handle_bytes; i++)
0066 seq_printf(m, "%02x", (int)f.handle.f_handle[i]);
0067 }
0068 #else
0069 static void show_mark_fhandle(struct seq_file *m, struct inode *inode)
0070 {
0071 }
0072 #endif
0073
0074 #ifdef CONFIG_INOTIFY_USER
0075
0076 static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
0077 {
0078 struct inotify_inode_mark *inode_mark;
0079 struct inode *inode;
0080
0081 if (mark->connector->type != FSNOTIFY_OBJ_TYPE_INODE)
0082 return;
0083
0084 inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
0085 inode = igrab(fsnotify_conn_inode(mark->connector));
0086 if (inode) {
0087 seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:0 ",
0088 inode_mark->wd, inode->i_ino, inode->i_sb->s_dev,
0089 inotify_mark_user_mask(mark));
0090 show_mark_fhandle(m, inode);
0091 seq_putc(m, '\n');
0092 iput(inode);
0093 }
0094 }
0095
0096 void inotify_show_fdinfo(struct seq_file *m, struct file *f)
0097 {
0098 show_fdinfo(m, f, inotify_fdinfo);
0099 }
0100
0101 #endif
0102
0103 #ifdef CONFIG_FANOTIFY
0104
0105 static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
0106 {
0107 unsigned int mflags = fanotify_mark_user_flags(mark);
0108 struct inode *inode;
0109
0110 if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
0111 inode = igrab(fsnotify_conn_inode(mark->connector));
0112 if (!inode)
0113 return;
0114 seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ",
0115 inode->i_ino, inode->i_sb->s_dev,
0116 mflags, mark->mask, mark->ignore_mask);
0117 show_mark_fhandle(m, inode);
0118 seq_putc(m, '\n');
0119 iput(inode);
0120 } else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
0121 struct mount *mnt = fsnotify_conn_mount(mark->connector);
0122
0123 seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
0124 mnt->mnt_id, mflags, mark->mask, mark->ignore_mask);
0125 } else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_SB) {
0126 struct super_block *sb = fsnotify_conn_sb(mark->connector);
0127
0128 seq_printf(m, "fanotify sdev:%x mflags:%x mask:%x ignored_mask:%x\n",
0129 sb->s_dev, mflags, mark->mask, mark->ignore_mask);
0130 }
0131 }
0132
0133 void fanotify_show_fdinfo(struct seq_file *m, struct file *f)
0134 {
0135 struct fsnotify_group *group = f->private_data;
0136
0137 seq_printf(m, "fanotify flags:%x event-flags:%x\n",
0138 group->fanotify_data.flags & FANOTIFY_INIT_FLAGS,
0139 group->fanotify_data.f_flags);
0140
0141 show_fdinfo(m, f, fanotify_fdinfo);
0142 }
0143
0144 #endif
0145
0146 #endif
0147
0148 #endif