Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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 /* CONFIG_INOTIFY_USER */
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 /* CONFIG_FANOTIFY */
0145 
0146 #endif /* CONFIG_INOTIFY_USER || CONFIG_FANOTIFY */
0147 
0148 #endif /* CONFIG_PROC_FS */