procfs fdinfo providers updated
Subsystems (6)
cover procfs fdinfo providers updated
Hi guys,
in this series I tried to address concerns on code duplication at seq_fdinfo_open and proc_fd_link, thus fdinfo_open_helper() is used in both routines. Also series updated to be appliable on top of v3.6-rc1.
Please review, comments are highly appreciated.
Cyrill
PATCH 1/8 procfs: Move /proc/pid/fd[info] handling code to fd.[ch]
This patch prepares the ground for further extension of /proc/pid/fd[info] handling code by moving fdinfo handling code into fs/proc/fd.c.
I think such move makes both fs/proc/base.c and fs/proc/fd.c easier to read.
--- fs/proc/Makefile | 2 fs/proc/base.c | 388 ----------------------------------------------------- fs/proc/fd.c | 351 +++++++++++++++++++++++++++++++++++++++++++++++ fs/proc/fd.h | 14 + fs/proc/internal.h | 48 ++++++ 5 files changed, 416 insertions(+), 387 deletions(-)
fs/proc/Makefile +1 -1
@@ -8,7 +8,7 @@ proc-y := nommu.o task_nommu.o proc-$(CONFIG_MMU) := mmu.o task_mmu.o proc-y += inode.o root.o base.o generic.o array.o \ - proc_tty.o + proc_tty.o fd.o proc-y += cmdline.o proc-y += consoles.o proc-y += cpuinfo.o
fs/proc/base.c +2 -386
430 lines not on this page · raw message
fs/proc/fd.c new file +351 -0
351 lines not on this page · raw message
fs/proc/fd.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef __PROCFS_FD_H__ +#define __PROCFS_FD_H__ + +#include <linux/fs.h> + +extern const struct file_operations proc_fd_operations; +extern const struct inode_operations proc_fd_inode_operations; + +extern const struct file_operations proc_fdinfo_operations; +extern const struct inode_operations proc_fdinfo_inode_operations; + +extern int proc_fd_permission (struct inode *inode,int mask); + +#endif /* __PROCFS_FD_H__ */
fs/proc/internal.h +48 -0
66 lines not on this page · raw message
Re: [patch 1/8] procfs: Move /proc/pid/fd[info] handling code to fd.[ch]
Quoted 7 lines · Cyrill Gorcunov
This patch prepares the ground for further extension of /proc/pid/fd[info] handling code by moving fdinfo handling code into
fs/proc/fd.c.I think such move makes both
fs/proc/base.candfs/proc/fd.ceasier to read.
Quoted 6 lines
Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>
PATCH 2/8 procfs: Convert /proc/pid/fdinfo/ handling routines to seq-file
In reply to Cyrill GorcunovThis patch converts /proc/pid/fdinfo/ handling routines to seq-file which is needed to extend seq operations and plug in auxiliary fdinfo provides from subsystems like eventfd/eventpoll/fsnotify.
Note the proc_fd_link no longer call for proc_fd_info, simply because proc_fd_info is converted to seq_fdinfo_open (which is seq-file open() prototype), moreover in further patches I need to provide two seq_fdinfo_open variants -- one with CONFIG_CHECKPOINT_RESTORE and one without this symbol. All in one -- this will look more messy then.
Also, to eliminate code duplication (and Pavel's concerns) the fdinfo_open_helper function introduced which is used in both seq_fdinfo_open and proc_fd_link.
--- fs/proc/fd.c | 123 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 48 deletions(-)
fs/proc/fd.c +75 -48
@@ -6,61 +6,104 @@#include <linux/namei.h> #include <linux/pid.h> #include <linux/security.h> +#include <linux/file.h> +#include <linux/seq_file.h> #include <linux/proc_fs.h> #include "internal.h" #include "fd.h" -#define PROC_FDINFO_MAX 64 +struct proc_fdinfo { +loff_t f_pos; +int f_flags; +}; -static int proc_fd_info (struct inode *inode,struct path *path,char *info) +static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct path *path) { -struct task_struct *task =get_proc_task (inode);struct files_struct *files =NULL ; -int fd =proc_fd (inode); -struct file *file; +struct task_struct *task; +int ret = -ENOENT ; + task =get_proc_task (inode);if (task) { files =get_files_struct (task);put_task_struct (task); } +if (files) { -/* -* We are not taking a ref to the file structure, so we must -* hold ->file_lock. -*/ -spin_lock (&files->file_lock); - file =fcheck_files (files, fd); -if (file) { -unsigned int f_flags; -struct fdtable *fdt; - - fdt =files_fdtable (files); - f_flags = file->f_flags & ~O_CLOEXEC ; -if (close_on_exec (fd, fdt)) - f_flags |=O_CLOEXEC ; +int fd =proc_fd (inode); +struct file *fd_file; +spin_lock (&files->file_lock); + fd_file =fcheck_files (files, fd); +if (fd_file) { +if (f_flags) { +struct fdtable *fdt =files_fdtable (files); + + *f_flags = fd_file->f_flags & ~O_CLOEXEC ; +if (close_on_exec (fd, fdt)) + *f_flags |=O_CLOEXEC ; + }if (path) { - *path = file->f_path; -path_get (&file->f_path); + *path = fd_file->f_path; +path_get (&fd_file->f_path); } -if (info) -snprintf (info,PROC_FDINFO_MAX , -"pos:\t%lli\n" -"flags:\t0%o\n" , - (long long ) file->f_pos, - f_flags); -spin_unlock (&files->file_lock); -put_files_struct (files); -return 0 ; + ret =0 ; }spin_unlock (&files->file_lock);put_files_struct (files); } -return -ENOENT ; + +return ret; } +static int seq_show (struct seq_file *m,void *v) +{ +struct proc_fdinfo *fdinfo = m->private; +seq_printf (m,"pos:\t%lli\nflags:\t0%o\n" , + (long long )fdinfo->f_pos, + fdinfo->f_flags); +return 0 ; +} + +static int seq_fdinfo_open (struct inode *inode,struct file *file) +{ +struct proc_fdinfo *fdinfo =NULL ; +int ret = -ENOENT ; + + fdinfo =kzalloc (sizeof (*fdinfo),GFP_KERNEL ); +if (!fdinfo) +return -ENOMEM ; + + ret =fdinfo_open_helper (inode, &fdinfo->f_flags,NULL ); +if (!ret) { + ret =single_open (file, seq_show, fdinfo); +if (!ret) + fdinfo =NULL ; + } + +kfree (fdinfo); +return ret; +} + +static int seq_fdinfo_release (struct inode *inode,struct file *file) +{ +struct seq_file *m = file->private_data; +struct proc_fdinfo *fdinfo = m->private; + +kfree (fdinfo); + +return single_release (inode, file); +} + +static const struct file_operations proc_fdinfo_file_operations = { + .open = seq_fdinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_fdinfo_release, +}; +static int tid_fd_revalidate (struct dentry *dentry,unsigned int flags) {struct files_struct *files;
@@ -130,7 +173,7 @@ static const struct dentry_operations tistatic int proc_fd_link (struct dentry *dentry,struct path *path) { -return proc_fd_info (dentry->d_inode, path,NULL ); +return fdinfo_open_helper (dentry->d_inode,NULL , path); } static struct dentry *
@@ -245,22 +288,6 @@ out_no_task:return retval; } -static ssize_t proc_fdinfo_read (struct file *file,char __user *buf, -size_t len,loff_t *ppos) -{ -char tmp[PROC_FDINFO_MAX ]; -int err =proc_fd_info (file->f_path.dentry->d_inode,NULL , tmp); -if (!err) - err =simple_read_from_buffer (buf, len, ppos, tmp,strlen (tmp)); -return err; -} - -static const struct file_operations proc_fdinfo_file_operations = { - .open = nonseekable_open, - .read = proc_fdinfo_read, - .llseek = no_llseek, -}; -static int proc_readfd (struct file *filp,void *dirent,filldir_t filldir) {return proc_readfd_common (filp, dirent, filldir, proc_fd_instantiate);
Re: [patch 2/8] procfs: Convert /proc/pid/fdinfo/ handling routines to seq-file
Quoted 13 lines · Cyrill Gorcunov
This patch converts
/proc/pid/fdinfo/handling routines to seq-file which is needed to extend seq operations and plug in auxiliary fdinfo provides from subsystems like eventfd/eventpoll/fsnotify.Note the
proc_fd_linkno longer call forproc_fd_info, simply becauseproc_fd_infois converted toseq_fdinfo_open(which is seq-fileopen()prototype), moreover in further patches I need to provide twoseq_fdinfo_openvariants -- one withCONFIG_CHECKPOINT_RESTOREand one without this symbol. All in one -- this will look more messy then.Also, to eliminate code duplication (and Pavel's concerns) the
fdinfo_open_helperfunction introduced which is used in bothseq_fdinfo_openandproc_fd_link.
Quoted 6 lines
Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>
PATCH 3/8 procfs: Add ability to plug in auxiliary fdinfo providers
In reply to Cyrill GorcunovThis patch brings ability to plug in auxiliary fdinfo providers. For example in further patches eventfd, evenpoll and fsnotify will print out information associated with files.
This feature is CONFIG_CHECKPOINT_RESTORE guarded to eliminate overhead for those who don't need it at all (this unfortunately makes patch bigger than I wanted).
The basic usage rule is the following
- fdinfo provider should register own "show" method via proc_register_fdinfo_driver call, where "show" methods are rather well known seq-file operations
- once the kernel opens /proc/$pid/fdinfo/$fd file it calls for ->probe() method in registered fdinfo drivers, and if probe success, then seq-file "show" operations will be called to provide out additional infomation
Initially we considered to inject some "show" metod to file_operations but since there really a number of file_operations declared inside kernel (and in real the further patches cover onle eventfd/epoll/inotify) the waste of memory space will be inacceptable I think.
Pavel, I've left seq_next memthod as it was simply because we can't leave seq_next() after calling extra->driver->ops->start without increasing "pos", thus we need to call for "show" manually once.
--- fs/proc/fd.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/proc_fs.h | 26 ++++++ 2 files changed, 216 insertions(+), 8 deletions(-)
fs/proc/fd.c +190 -8
@@ -8,18 +8,14 @@#include <linux/security.h> #include <linux/file.h> #include <linux/seq_file.h> +#include <linux/spinlock.h> #include <linux/proc_fs.h> #include "internal.h" #include "fd.h" -struct proc_fdinfo { -loff_t f_pos; -int f_flags; -}; - -static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct path *path) +static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct file **f_file,struct path *path) {struct files_struct *files =NULL ;struct task_struct *task;
@@ -49,6 +45,10 @@ static int fdinfo_open_helper(struct ino *path = fd_file->f_path;path_get (&fd_file->f_path); } +if (f_file) { + *f_file = fd_file; +get_file (fd_file); + } ret =0 ; }spin_unlock (&files->file_lock);
@@ -58,6 +58,186 @@ static int fdinfo_open_helper(struct inoreturn ret; } +#ifdef CONFIG_CHECKPOINT_RESTORE + +static LIST_HEAD (fdinfo_drivers); +static DECLARE_RWSEM (fdinfo_drivers_sem); + +int proc_register_fdinfo_driver (struct proc_fdinfo_driver *s) +{ +struct proc_fdinfo_driver *i; +int ret =0 ; + +if (!s->ops || !s->probe) +return -EINVAL ; + +down_write (&fdinfo_drivers_sem); +list_for_each_entry (i, &fdinfo_drivers, list) { +if (i == s) { +WARN_ONCE ("Trying reassign fdinfo driver `%s'\n" , + i->name); + ret = -EINVAL ; +break ; + } + } +if (!ret) +list_add (&s->list, &fdinfo_drivers); +up_write (&fdinfo_drivers_sem); + +return ret; +} + +void proc_unregister_fdinfo_driver (struct proc_fdinfo_driver *s) +{ +struct proc_fdinfo_driver *i, *tmp; + +down_write (&fdinfo_drivers_sem); +list_for_each_entry_safe (i, tmp, &fdinfo_drivers, list) { +if (i == s) { +list_del (&i->list); +break ; + } + } +up_write (&fdinfo_drivers_sem); +} + +static int prep_fdinfo_driver (struct proc_fdinfo_extra *extra) +{ +struct proc_fdinfo_driver *s; + +down_read (&fdinfo_drivers_sem); +list_for_each_entry (s, &fdinfo_drivers, list) { +if (s->probe (extra->f_file)) { + extra->driver = s; +break ; + } + } +up_read (&fdinfo_drivers_sem); + +return 0 ; +} + +static void *seq_start (struct seq_file *m,loff_t *pos) +{ +struct proc_fdinfo_extra *extra = m->private; + +down_read (&fdinfo_drivers_sem); + extra->pos = *pos; + +return *pos ==0 ? extra : + (extra->driver ? extra->driver->ops->start (m, pos) :NULL ); +} + +static void seq_stop (struct seq_file *m,void *v) +{ +struct proc_fdinfo_extra *extra = m->private; + +if (extra->driver && extra->pos >0 ) + extra->driver->ops->stop (m, v); +up_read (&fdinfo_drivers_sem); +} + +static void *seq_next (struct seq_file *m,void *p,loff_t *pos) +{ +struct proc_fdinfo_extra *extra = m->private; +void *v =NULL ; + +if (extra->driver) { +int ret =0 ; + +if (*pos ==0 ) { + v = extra->driver->ops->start (m, pos); +if (v) { + ret = extra->driver->ops->show (m, v); + p = v; + }else + ret =-1 ; + } + +if (!ret) + v = extra->driver->ops->next (m, p, pos); + }else + ++*pos; + + extra->pos = *pos; +return v; +} + +static int seq_show (struct seq_file *m,void *v) +{ +struct proc_fdinfo_extra *extra = m->private; + +if (extra->driver && extra->pos >0 ) +return extra->driver->ops->show (m, v); + +seq_printf (m,"pos:\t%lli\nflags:\t0%o\n" , + (long long )extra->f_file->f_pos, + extra->f_flags); +return 0 ; +} + +static const struct seq_operations fdinfo_seq_ops = { + .start = seq_start, + .next = seq_next, + .stop = seq_stop, + .show = seq_show, +}; + +static int seq_fdinfo_open (struct inode *inode,struct file *file) +{ +struct proc_fdinfo_extra *extra; +struct seq_file *m; +int ret; + + extra =kzalloc (sizeof (*extra),GFP_KERNEL ); +if (!extra) +return -ENOMEM ; + + ret =seq_open (file, &fdinfo_seq_ops); +if (!ret) { + ret = -ENOENT ; + m = file->private_data; + m->private = extra; + + ret =fdinfo_open_helper (inode, &extra->f_flags, + &extra->f_file,NULL ); +if (!ret) + ret =prep_fdinfo_driver (extra); + } + +if (ret) { +if (extra->f_file) +put_filp (extra->f_file); +kfree (extra); + } +return ret; +} + +static int seq_fdinfo_release (struct inode *inode,struct file *file) +{ +struct seq_file *m = file->private_data; +struct proc_fdinfo_extra *extra = m->private; + +put_filp (extra->f_file); +kfree (m->private); + +return seq_release (inode, file); +} + +static const struct file_operations proc_fdinfo_file_operations = { + .open = seq_fdinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_fdinfo_release, +}; + +#else /* CONFIG_CHECKPOINT_RESTORE */ + +struct proc_fdinfo { +loff_t f_pos; +int f_flags; +}; +static int seq_show (struct seq_file *m,void *v) {struct proc_fdinfo *fdinfo = m->private;
@@ -76,7 +256,7 @@ static int seq_fdinfo_open(struct inodeif (!fdinfo)return -ENOMEM ; - ret =fdinfo_open_helper (inode, &fdinfo->f_flags,NULL ); + ret =fdinfo_open_helper (inode, &fdinfo->f_flags,NULL ,NULL );if (!ret) { ret =single_open (file, seq_show, fdinfo);if (!ret)
@@ -104,6 +284,8 @@ static const struct file_operations proc .release = seq_fdinfo_release, }; +#endif /* CONFIG_CHECKPOINT_RESTORE */ +static int tid_fd_revalidate (struct dentry *dentry,unsigned int flags) {struct files_struct *files;
@@ -173,7 +355,7 @@ static const struct dentry_operations tistatic int proc_fd_link (struct dentry *dentry,struct path *path) { -return fdinfo_open_helper (dentry->d_inode,NULL , path); +return fdinfo_open_helper (dentry->d_inode,NULL ,NULL , path); } static struct dentry *
include/linux/proc_fs.h +26 -0
@@ -100,6 +100,24 @@ struct vmcore {loff_t offset; }; +struct seq_operations ; + +/* fdinfo auxiliary information drivers */ +struct proc_fdinfo_driver { +struct list_head list; +const char *name; +const struct seq_operations *ops; +int (*probe)(struct file *file); +}; + +/* auxiliary data allocated per fdinfo reader */ +struct proc_fdinfo_extra { +struct proc_fdinfo_driver *driver; +loff_t pos; +struct file *f_file; +unsigned int f_flags; +}; +#ifdef CONFIG_PROC_FS extern void proc_root_init (void );
@@ -175,6 +193,11 @@ extern struct proc_dir_entry *proc_net_mextern struct file *proc_ns_fget (int fd); +#ifdef CONFIG_CHECKPOINT_RESTORE +extern int proc_register_fdinfo_driver (struct proc_fdinfo_driver *s); +extern void proc_unregister_fdinfo_driver (struct proc_fdinfo_driver *s); +#endif /* CONFIG_CHECKPOINT_RESTORE */ +#else #define proc_net_fops_create (net, name, mode, fops) ({ (void)(mode), NULL; })
@@ -229,6 +252,9 @@ static inline struct file *proc_ns_fget( return ERR_PTR(-EINVAL); } +static inline int proc_register_fdinfo_driver (struct proc_fdinfo_driver *s) {return -EINVAL ; } +static inline void proc_unregister_fdinfo_driver (struct proc_fdinfo_driver *s) { } +#endif /* CONFIG_PROC_FS */ #if !defined(CONFIG_PROC_KCORE )
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 31 lines · Cyrill Gorcunov
This patch brings ability to plug in auxiliary fdinfo providers. For example in further patches eventfd, evenpoll and fsnotify will print out information associated with files.
This feature is
CONFIG_CHECKPOINT_RESTOREguarded to eliminate overhead for those who don't need it at all (this unfortunately makes patch bigger than I wanted).The basic usage rule is the following
- fdinfo provider should register own "show" method via
proc_register_fdinfo_drivercall, where "show" methods are rather well known seq-file operations- once the kernel opens
/proc/$pid/fdinfo/$fdfile it calls for ->probe() method in registered fdinfo drivers, and if probe success, then seq-file "show" operations will be called to provide out additional infomationInitially we considered to inject some "show" metod to
file_operationsbut since there really a number offile_operationsdeclared inside kernel (and in real the further patches cover onle eventfd/epoll/inotify) the waste of memory space will be inacceptable I think.Pavel, I've left
seq_nextmemthod as it was simply because we can't leaveseq_next()after callingextra->driver->ops->startwithout increasing "pos", thus we need to call for "show" manually once.
Quoted 6 lines
Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>
Al Viro
maintainerRe: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
In reply to Cyrill GorcunovQuoted 20 lines · Cyrill Gorcunov
This patch brings ability to plug in auxiliary fdinfo providers. For example in further patches eventfd, evenpoll and fsnotify will print out information associated with files.
This feature is
CONFIG_CHECKPOINT_RESTOREguarded to eliminate overhead for those who don't need it at all (this unfortunately makes patch bigger than I wanted).The basic usage rule is the following
- fdinfo provider should register own "show" method via
proc_register_fdinfo_drivercall, where "show" methods are rather well known seq-file operations- once the kernel opens
/proc/$pid/fdinfo/$fdfile it calls for ->probe() method in registered fdinfo drivers, and if probe success, then seq-file "show" operations will be called to provide out additional infomation
Quoted 5 lines
Initially we considered to inject some "show" metod to
file_operationsbut since there really a number offile_operationsdeclared inside kernel (and in real the further patches cover onle eventfd/epoll/inotify) the waste of memory space will be inacceptable I think.
NAK. This is too ugly to live. Put it into file_operations, with NULL meaning default output, or don't do it at all.
And no, "it's only if you enable CONFIG_SOME_SHIT" gambit won't fly - we have all seen it played too many times. All it takes is one politically-inclined induhvidual adding a dependency to some "vertically integrated" turd (*cough* systemd *spit* udev *cough*) and we are stuck with the damn thing. CGROUP shite is already there, DEVTMPFS is well on its way, etc.
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 9 lines · Al Viro
Quoted 5 lines
Initially we considered to inject some "show" metod to
file_operationsbut since there really a number offile_operationsdeclared inside kernel (and in real the further patches cover onle eventfd/epoll/inotify) the waste of memory space will be inacceptable I think.NAK. This is too ugly to live. Put it into
file_operations, with NULL meaning default output, or don't do it at all.
Quoted 6 lines
And no, "it's only if you enable
CONFIG_SOME_SHIT" gambit won't fly - we have all seen it played too many times. All it takes is one politically-inclined induhvidual adding a dependency to some "vertically integrated" turd (*cough* systemd *spit* udev *cough*) and we are stuck with the damn thing. CGROUP shite is already there, DEVTMPFS is well on its way, etc.
OK, I'll put it into file_operations then (actually Pavel was proposing the same but I've been scared by amount of file_operations declared). Thanks!
Cyrill
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 17 lines · Cyrill Gorcunov
Quoted 9 lines · Al Viro
Quoted 5 lines
Initially we considered to inject some "show" metod to
file_operationsbut since there really a number offile_operationsdeclared inside kernel (and in real the further patches cover onle eventfd/epoll/inotify) the waste of memory space will be inacceptable I think.NAK. This is too ugly to live. Put it into
file_operations, with NULL meaning default output, or don't do it at all.Quoted 6 lines
And no, "it's only if you enable
CONFIG_SOME_SHIT" gambit won't fly - we have all seen it played too many times. All it takes is one politically-inclined induhvidual adding a dependency to some "vertically integrated" turd (*cough* systemd *spit* udev *cough*) and we are stuck with the damn thing. CGROUP shite is already there, DEVTMPFS is well on its way, etc.
Quoted 3 lines
OK, I'll put it into
file_operationsthen (actually Pavel was proposing the same but I've been scared by amount offile_operationsdeclared). Thanks!
Al, does the patch below looks better? If so I'll fix up the rest.
--- fs/proc/fd.c | 109 ++++++++++++++++++++++++++++++++++++++---------- include/linux/fs.h | 3 + include/linux/proc_fs.h | 8 +++ 3 files changed, 99 insertions(+), 21 deletions(-)
fs/proc/fd.c +88 -21
@@ -8,18 +8,14 @@#include <linux/security.h> #include <linux/file.h> #include <linux/seq_file.h> +#include <linux/spinlock.h> #include <linux/proc_fs.h> #include "internal.h" #include "fd.h" -struct proc_fdinfo { -loff_t f_pos; -int f_flags; -}; - -static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct path *path) +static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct file **f_file,struct path *path) {struct files_struct *files =NULL ;struct task_struct *task;
@@ -49,6 +45,10 @@ static int fdinfo_open_helper(struct ino *path = fd_file->f_path;path_get (&fd_file->f_path); } +if (f_file) { + *f_file = fd_file; +get_file (fd_file); + } ret =0 ; }spin_unlock (&files->file_lock);
@@ -58,43 +58,110 @@ static int fdinfo_open_helper(struct inoreturn ret; } +static void *seq_start (struct seq_file *m,loff_t *pos) +{ +struct proc_fdinfo_extra *extra = m->private; + + extra->pos = *pos; + +return *pos ==0 ? extra : + (extra->fdinfo_ops ? + extra->fdinfo_ops->start (m, pos) :NULL ); +} + +static void seq_stop (struct seq_file *m,void *v) +{ +struct proc_fdinfo_extra *extra = m->private; + +if (extra->fdinfo_ops && extra->pos >0 ) + extra->fdinfo_ops->stop (m, v); +} + +static void *seq_next (struct seq_file *m,void *p,loff_t *pos) +{ +struct proc_fdinfo_extra *extra = m->private; +void *v =NULL ; + +if (extra->fdinfo_ops) { +int ret =0 ; + +if (*pos ==0 ) { + v = extra->fdinfo_ops->start (m, pos); +if (v) { + ret = extra->fdinfo_ops->show (m, v); + p = v; + }else + ret =-1 ; + } + +if (!ret) + v = extra->fdinfo_ops->next (m, p, pos); + }else + ++*pos; + + extra->pos = *pos; +return v; +} +static int seq_show (struct seq_file *m,void *v) { -struct proc_fdinfo *fdinfo = m->private; +struct proc_fdinfo_extra *extra = m->private; + +if (extra->fdinfo_ops && extra->pos >0 ) +return extra->fdinfo_ops->show (m, v); +seq_printf (m,"pos:\t%lli\nflags:\t0%o\n" , - (long long )fdinfo->f_pos, - fdinfo->f_flags); + (long long )extra->f_file->f_pos, + extra->f_flags);return 0 ; } +static const struct seq_operations fdinfo_seq_ops = { + .start = seq_start, + .next = seq_next, + .stop = seq_stop, + .show = seq_show, +}; +static int seq_fdinfo_open (struct inode *inode,struct file *file) { -struct proc_fdinfo *fdinfo =NULL ; -int ret = -ENOENT ; +struct proc_fdinfo_extra *extra; +struct seq_file *m; +int ret; - fdinfo =kzalloc (sizeof (*fdinfo),GFP_KERNEL ); -if (!fdinfo) + extra =kzalloc (sizeof (*extra),GFP_KERNEL ); +if (!extra)return -ENOMEM ; - ret =fdinfo_open_helper (inode, &fdinfo->f_flags,NULL ); + ret =seq_open (file, &fdinfo_seq_ops);if (!ret) { - ret =single_open (file, seq_show, fdinfo); + ret = -ENOENT ; + m = file->private_data; + m->private = extra; + + ret =fdinfo_open_helper (inode, &extra->f_flags, + &extra->f_file,NULL );if (!ret) - fdinfo =NULL ; + extra->fdinfo_ops = extra->f_file->f_op->fdinfo_ops; } -kfree (fdinfo); +if (ret) { +if (extra->f_file) +put_filp (extra->f_file); +kfree (extra); + }return ret; }static int seq_fdinfo_release (struct inode *inode,struct file *file) {struct seq_file *m = file->private_data; -struct proc_fdinfo *fdinfo = m->private; +struct proc_fdinfo_extra *extra = m->private; -kfree (fdinfo); +put_filp (extra->f_file); +kfree (m->private); -return single_release (inode, file); +return seq_release (inode, file); }static const struct file_operations proc_fdinfo_file_operations = {
@@ -173,7 +240,7 @@ static const struct dentry_operations tistatic int proc_fd_link (struct dentry *dentry,struct path *path) { -return fdinfo_open_helper (dentry->d_inode,NULL , path); +return fdinfo_open_helper (dentry->d_inode,NULL ,NULL , path); } static struct dentry *
include/linux/fs.h +3 -0
@@ -1775,8 +1775,11 @@ struct block_device_operations;#define HAVE_COMPAT_IOCTL 1#define HAVE_UNLOCKED_IOCTL 1 +struct seq_operations ; +struct file_operations {struct module *owner; +struct seq_operations *fdinfo_ops;loff_t (*llseek) (struct file *,loff_t ,int );ssize_t (*read) (struct file *,char __user *,size_t ,loff_t *);ssize_t (*write) (struct file *,const char __user *,size_t ,loff_t *);
include/linux/proc_fs.h +8 -0
@@ -100,6 +100,14 @@ struct vmcore {loff_t offset; }; +/* auxiliary data allocated per fdinfo reader */ +struct proc_fdinfo_extra { +loff_t pos; +struct file *f_file; +struct seq_operations *fdinfo_ops; +unsigned int f_flags; +}; +#ifdef CONFIG_PROC_FS extern void proc_root_init (void );
Al Viro
maintainerRe: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
include/linux/fs.h struct block_device_operations; · line 1782
Quoted 5 lines · Cyrill Gorcunov
Al, does the patch below looks better? If so I'll fix up the rest.
struct
file_operations{include/linux/fs.h +1
-0struct module *owner; +struct seq_operations *fdinfo_ops;
IDGI. Why on the earth do you need the whole iterator? All it takes is show_fdinfo(struct seq_file *m, struct file *f); have ->show() in your iterator (one going through the files) call that sucker for the file we are trying to show.
I think you are severely overdesigning that thing...
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 12 lines · Al Viro
include/linux/fs.h struct block_device_operations; · line 1782
Quoted 5 lines · Cyrill Gorcunov
Al, does the patch below looks better? If so I'll fix up the rest.
struct
file_operations{include/linux/fs.h +1
-0struct module *owner; +struct seq_operations *fdinfo_ops;IDGI. Why on the earth do you need the whole iterator? All it takes is
show_fdinfo(struct seq_file *m, struct file *f); have ->show() in your iterator (one going through the files) call that sucker for the file we are trying to show.
Quoted 1 line
I think you are severely overdesigning that thing...
Hmm, in very first versions I've been using one ->show method, but then I thought that this is not very correlate with seq-files idea where for each record show/next sequence is called. I'll update (this for sure will make code simplier, and I'll have to check for seq-file overflow after seq_printf call to not continue printing data for too long if buffer already out of space).
Cyrill
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 9 lines · Cyrill Gorcunov
Quoted 9 lines
include/linux/fs.h struct block_device_operations; · line 1782
Quoted 3 lines
struct
file_operations{include/linux/fs.h +1
-0struct module *owner; +struct seq_operations *fdinfo_ops;IDGI. Why on the earth do you need the whole iterator? All it takes is
show_fdinfo(struct seq_file *m, struct file *f); have ->show() in your iterator (one going through the files) call that sucker for the file we are trying to show.
Quoted 8 lines
Quoted 1 line
I think you are severely overdesigning that thing...
Hmm, in very first versions I've been using one ->show method, but then I thought that this is not very correlate with seq-files idea where for each record show/next sequence is called. I'll update (this for sure will make code simplier, and I'll have to check for seq-file overflow after
seq_printfcall to not continue printing data for too long if buffer already out of space).
Al, I'll cook the whole series tomorrow and resend it for review, also I guess the new show_fdinfo() member in file-operations should be guarded with CONFIG_PROC_FS, right?
Al Viro
maintainerRe: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 10 lines · Cyrill Gorcunov
Quoted 6 lines
Hmm, in very first versions I've been using one ->show method, but then I thought that this is not very correlate with seq-files idea where for each record show/next sequence is called. I'll update (this for sure will make code simplier, and I'll have to check for seq-file overflow after
seq_printfcall to not continue printing data for too long if buffer already out of space).Al, I'll cook the whole series tomorrow and resend it for review, also I guess the new
show_fdinfo()member in file-operations should be guarded withCONFIG_PROC_FS, right?
I seriously doubt that it's worth bothering. If somebody cares, they can add making it conditional later.
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 8 lines · Al Viro
Quoted 7 lines · Cyrill Gorcunov
Quoted 6 lines
Hmm, in very first versions I've been using one ->show method, but then I thought that this is not very correlate with seq-files idea where for each record show/next sequence is called. I'll update (this for sure will make code simplier, and I'll have to check for seq-file overflow after
seq_printfcall to not continue printing data for too long if buffer already out of space).
Quoted 6 lines
Quoted 3 lines
Al, I'll cook the whole series tomorrow and resend it for review, also I guess the new
show_fdinfo()member in file-operations should be guarded withCONFIG_PROC_FS, right?I seriously doubt that it's worth bothering. If somebody cares, they can add making it conditional later.
That's what I've beed testing, does it looks good for you?
---
From: Cyrill Gorcunov <[email protected]>
Subject: procfs: Add ability to plug in auxiliary fdinfo providers
This patch brings ability to print out auxiliary data associated with file in procfs interface /proc/pid/fdinfo/fd.
Inparticular further patches make eventfd, evenpoll, signalfd and fsnotify to print additional information complete enough to restore these objects after checkpoint.
To simplify the code we add show_fdinfo callback into struct file_operations (as Al proposed).
--- fs/proc/fd.c | 51 ++++++++++++++++++++++++++++++++++++--------------- include/linux/fs.h | 3 +++ 2 files changed, 39 insertions(+), 15 deletions(-)
fs/proc/fd.c +36 -15
@@ -15,11 +15,11 @@#include "fd.h" struct proc_fdinfo { -loff_t f_pos; -int f_flags; +struct file *f_file; +int f_flags; }; -static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct path *path) +static int fdinfo_open_helper (struct inode *inode,int *f_flags,struct file **f_file,struct path *path) {struct files_struct *files =NULL ;struct task_struct *task;
@@ -49,6 +49,10 @@ static int fdinfo_open_helper(struct ino *path = fd_file->f_path;path_get (&fd_file->f_path); } +if (f_file) { + *f_file = fd_file; +get_file (fd_file); + } ret =0 ; }spin_unlock (&files->file_lock);
@@ -61,28 +65,44 @@ static int fdinfo_open_helper(struct inostatic int seq_show (struct seq_file *m,void *v) {struct proc_fdinfo *fdinfo = m->private; -seq_printf (m,"pos:\t%lli\nflags:\t0%o\n" , - (long long )fdinfo->f_pos, - fdinfo->f_flags); -return 0 ; +int ret; + + ret =seq_printf (m,"pos:\t%lli\nflags:\t0%o\n" , + (long long )fdinfo->f_file->f_pos, + fdinfo->f_flags); + +if (!ret && fdinfo->f_file->f_op->show_fdinfo) + ret = fdinfo->f_file->f_op->show_fdinfo (m, fdinfo->f_file); + +return ret; }static int seq_fdinfo_open (struct inode *inode,struct file *file) { -struct proc_fdinfo *fdinfo =NULL ; -int ret = -ENOENT ; +struct proc_fdinfo *fdinfo; +struct seq_file *m; +int ret; fdinfo =kzalloc (sizeof (*fdinfo),GFP_KERNEL );if (!fdinfo)return -ENOMEM ; - ret =fdinfo_open_helper (inode, &fdinfo->f_flags,NULL ); -if (!ret) { - ret =single_open (file, seq_show, fdinfo); -if (!ret) - fdinfo =NULL ; + ret =fdinfo_open_helper (inode, &fdinfo->f_flags, &fdinfo->f_file,NULL ); +if (ret) + goto err_free; + + ret =single_open (file, seq_show, fdinfo); +if (ret) { +put_filp (fdinfo->f_file); + goto err_free; } + m = file->private_data; + m->private = fdinfo; + +return ret; + +err_free:kfree (fdinfo);return ret; }
@@ -92,6 +112,7 @@ static int seq_fdinfo_release(struct inostruct seq_file *m = file->private_data;struct proc_fdinfo *fdinfo = m->private; +put_filp (fdinfo->f_file);kfree (fdinfo);return single_release (inode, file);
@@ -173,7 +194,7 @@ static const struct dentry_operations tistatic int proc_fd_link (struct dentry *dentry,struct path *path) { -return fdinfo_open_helper (dentry->d_inode,NULL , path); +return fdinfo_open_helper (dentry->d_inode,NULL ,NULL , path); } static struct dentry *
include/linux/fs.h +3 -0
@@ -1775,6 +1775,8 @@ struct block_device_operations;#define HAVE_COMPAT_IOCTL 1#define HAVE_UNLOCKED_IOCTL 1 +struct seq_file ; +struct file_operations {struct module *owner;loff_t (*llseek) (struct file *,loff_t ,int );
@@ -1803,6 +1805,7 @@ struct file_operations {int (*setlease)(struct file *,long ,struct file_lock **);long (*fallocate)(struct file *file,int mode,loff_t offset,loff_t len); +int (*show_fdinfo)(struct seq_file *m,struct file *f); };struct inode_operations {
PATCH 4/8 fs, eventfd: Add procfs fdinfo helper
In reply to Cyrill GorcunovThis allow us to print out raw counter value. The /proc/pid/fdinfo/fd output is
| pos: 0 | flags: 04002 | eventfd-count: 5a
This feature is CONFIG_CHECKPOINT_RESTORE only.
--- fs/eventfd.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
fs/eventfd.c +55 -0
@@ -19,6 +19,8 @@#include <linux/export.h> #include <linux/kref.h> #include <linux/eventfd.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> struct eventfd_ctx {struct kref kref;
@@ -433,3 +435,56 @@ SYSCALL_DEFINE1(eventfd, unsigned int, creturn sys_eventfd2 (count,0 ); } +#if defined(CONFIG_PROC_FS ) && defined(CONFIG_CHECKPOINT_RESTORE ) + +static void *seq_start (struct seq_file *m,loff_t *pos) +{ +struct proc_fdinfo_extra *extra = m->private; +return *pos ==0 ? extra->f_file :NULL ; +} + +static void *seq_next (struct seq_file *m,void *p,loff_t *pos) +{ + ++*pos; +return NULL ; +} + +static int seq_show (struct seq_file *m,void *v) +{ +struct eventfd_ctx *ctx = ((struct file *)v)->private_data; + +spin_lock_irq (&ctx->wqh.lock); +seq_printf (m,"eventfd-count: %16llx\n" , + (unsigned long long )ctx->count); +spin_unlock_irq (&ctx->wqh.lock); + +return 0 ; +} + +static void seq_stop (struct seq_file *p,void *v) { } + +static const struct seq_operations eventfd_fdinfo_ops = { + .start = seq_start, + .next = seq_next, + .stop = seq_stop, + .show = seq_show, +}; + +static int is_eventfd_file (struct file *file) +{ +return file->f_op == &eventfd_fops; +} + +static struct proc_fdinfo_driver eventfd_fdinfo = { + .name ="eventfd" , + .ops = &eventfd_fdinfo_ops, + .probe = is_eventfd_file, +}; + +static int __init eventfd_init (void ) +{ +return proc_register_fdinfo_driver (&eventfd_fdinfo); +} +fs_initcall (eventfd_init); + +#endif /* CONFIG_PROC_FS && CONFIG_CHECKPOINT_RESTORE */
Re: [patch 4/8] fs, eventfd: Add procfs fdinfo helper
Quoted 7 lines · Cyrill Gorcunov
This allow us to print out raw counter value. The
/proc/pid/fdinfo/fdoutput is| pos: 0 | flags: 04002 | eventfd-count: 5a
Quoted 8 lines
This feature is
CONFIG_CHECKPOINT_RESTOREonly.Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>
PATCH 5/8 fs, epoll: Add procfs fdinfo helper v2
In reply to Cyrill GorcunovThis allow us to print out eventpoll target file descriptor, events and data, the /proc/pid/fdinfo/fd consists of
| pos: 0 | flags: 02 | tfd: 5 events: 1d data: ffffffffffffffff
This feature is CONFIG_CHECKPOINT_RESTORE only.
v2:
- don't walk over all rb nodes on seq-next,
try to continue from pervious position
--- fs/eventpoll.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
fs/eventpoll.c +67 -0
@@ -38,6 +38,8 @@#include <asm/io.h> #include <asm/mman.h> #include <linux/atomic.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> /* * LOCKING:
@@ -1897,6 +1899,69 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd,return error; } +#if defined(CONFIG_PROC_FS ) && defined(CONFIG_CHECKPOINT_RESTORE ) + +static void *seq_start (struct seq_file *m,loff_t *pos) +{ +struct proc_fdinfo_extra *extra = m->private; +struct eventpoll *ep = extra->f_file->private_data; +struct rb_node *rbp; +loff_t num = *pos; + +mutex_lock (&ep->mtx); +for (rbp =rb_first (&ep->rbr); rbp; rbp =rb_next (rbp)) { +if (num-- ==0 ) +return rbp; + } + +return NULL ; +} + +static void seq_stop (struct seq_file *m,void *v) +{ +struct proc_fdinfo_extra *extra = m->private; +struct eventpoll *ep = extra->f_file->private_data; +mutex_unlock (&ep->mtx); +} + +static void *seq_next (struct seq_file *m,void *p,loff_t *pos) +{ +struct rb_node *rbp = p; + ++*pos; +return (void *)rb_next (rbp); +} + +static int seq_show (struct seq_file *m,void *v) +{ +struct rb_node *rbp = v; + struct epitem *epi = rb_entry(rbp, struct epitem, rbn); + +return seq_printf (m,"tfd: %8d events: %8x data: %16llx\n" , + epi->ffd.fd, epi->event.events, + (long long )epi->event.data); +} + +static const struct seq_operations ep_fdinfo_ops = { + .start = seq_start, + .next = seq_next, + .stop = seq_stop, + .show = seq_show, +}; + +static struct proc_fdinfo_driver ep_fdinfo = { + .name ="eventpoll" , + .ops = &ep_fdinfo_ops, + .probe = is_file_epoll, +}; + +static int __init ep_register_fdinfo_driver (void ) +{ +return proc_register_fdinfo_driver (&ep_fdinfo); +} +#else +static void ep_register_fdinfo_driver (void ) { } +#endif /* CONFIG_PROC_FS && CONFIG_CHECKPOINT_RESTORE */ +static int __init eventpoll_init (void ) {struct sysinfo si;
@@ -1929,6 +1994,8 @@ static int __init eventpoll_init(void) pwq_cache =kmem_cache_create ("eventpoll_pwq" ,sizeof (struct eppoll_entry ),0 ,SLAB_PANIC ,NULL ); +ep_register_fdinfo_driver (); +return 0 ; }fs_initcall (eventpoll_init);
Re: [patch 5/8] fs, epoll: Add procfs fdinfo helper v2
Quoted 13 lines · Cyrill Gorcunov
This allow us to print out eventpoll target file descriptor, events and data, the
/proc/pid/fdinfo/fdconsists of| pos: 0 | flags: 02 | tfd: 5 events: 1d data: ffffffffffffffffThis feature is
CONFIG_CHECKPOINT_RESTOREonly.v2:
- don't walk over all rb nodes on seq-next,
try to continue from pervious position
Quoted 7 lines
Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>CC Matthew Helsley <[email protected]>
PATCH 6/8 fs, exportfs: Add export_encode_inode_fh helper
In reply to Cyrill GorcunovTo provide fsnotify object inodes being watched without binding to alphabetical path we need to encode them with exportfs help. This patch adds a helper which operates with plain inodes directly.
This feature is CONFIG_CHECKPOINT_RESTORE only.
--- fs/exportfs/expfs.c | 21 +++++++++++++++++++++ include/linux/exportfs.h | 4 ++++ 2 files changed, 25 insertions(+)
fs/exportfs/expfs.c +21 -0
@@ -302,6 +302,27 @@ out:return error; } +#ifdef CONFIG_CHECKPOINT_RESTORE +int export_encode_inode_fh (struct inode *inode,struct fid *fid,int *max_len) +{ +int len = *max_len; +int type =FILEID_INO32_GEN ; + +if (len <2 ) { + *max_len =2 ; +return 255 ; + } + + len =2 ; + fid->i32.ino = inode->i_ino; + fid->i32.gen = inode->i_generation; + *max_len = len; + +return type; +} +EXPORT_SYMBOL_GPL (export_encode_inode_fh); +#endif +/** * export_encode_fh - default export_operations->encode_fh function * @inode: the object to encode
include/linux/exportfs.h +4 -0
@@ -177,6 +177,10 @@ struct export_operations {int (*commit_metadata)(struct inode *inode); }; +#ifdef CONFIG_CHECKPOINT_RESTORE +extern int export_encode_inode_fh (struct inode *inode,struct fid *fid,int *max_len); +#endif +extern int exportfs_encode_fh (struct dentry *dentry,struct fid *fid,int *max_len,int connectable); extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
Re: [patch 6/8] fs, exportfs: Add export_encode_inode_fh helper
Quoted 5 lines · Cyrill Gorcunov
To provide fsnotify object inodes being watched without binding to alphabetical path we need to encode them with exportfs help. This patch adds a helper which operates with plain inodes directly.
Quoted 8 lines
This feature is
CONFIG_CHECKPOINT_RESTOREonly.Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>
PATCH 7/8 fs, notify: Add procfs fdinfo helper v3
In reply to Cyrill GorcunovThis allow us to print out fsnotify details such as watchee inode, device, mask and file handle.
For example for inotify objects the output is
| pos: 0 | flags: 02000000 | inotify wd: 3 ino: 9e7e sdev: 800013 mask: 800afce ignored_mask: 0 fhandle-bytes: 8 fhandle-type: 1 f_handle: 7e9e0000640d1b6d | inotify wd: 2 ino: a111 sdev: 800013 mask: 800afce ignored_mask: 0 fhandle-bytes: 8 fhandle-type: 1 f_handle: 11a1000020542153 | inotify wd: 1 ino: 6b149 sdev: 800013 mask: 800afce ignored_mask: 0 fhandle-bytes: 8 fhandle-type: 1 f_handle: 49b1060023552153
For fanotify it is like
| pos: 0 | flags: 02 | fanotify ino: 68f71 sdev: 800013 mask: 1 ignored_mask: 40000000 fhandle-bytes: 8 fhandle-type: 1 f_handle: 718f0600b9f42053 | fanotify mnt_id: 13 mask: 1 ignored_mask: 40000000
This feature is CONFIG_CHECKPOINT_RESTORE only. To minimize impact on general fsnotify code the new functionality is gathered in fs/notify/fdinfo.c file mostly.
v2:
- append missing colons to terms
v3:
- continue from pervious position in list on ->next
--- fs/notify/Makefile | 2 fs/notify/fanotify/fanotify_user.c | 17 ++ fs/notify/fdinfo.c | 216 +++++++++++++++++++++++++++++++++++++ fs/notify/fdinfo.h | 19 +++ fs/notify/inotify/inotify_user.c | 32 +++++ 5 files changed, 284 insertions(+), 2 deletions(-)
fs/notify/Makefile +1 -1
@@ -1,5 +1,5 @@ obj-$(CONFIG_FSNOTIFY) += fsnotify.o notification.o group.o inode_mark.o \ - mark.o vfsmount_mark.o + mark.o vfsmount_mark.o fdinfo.o obj-y += dnotify/ obj-y += inotify/
fs/notify/fanotify/fanotify_user.c +16 -1
@@ -17,6 +17,7 @@#include <asm/ioctls.h> #include "../../mount.h" +#include "../fdinfo.h" #define FANOTIFY_DEFAULT_MAX_EVENTS 16384#define FANOTIFY_DEFAULT_MAX_MARKS 8192
@@ -873,6 +874,20 @@ asmlinkage long SyS_fanotify_mark(long fSYSCALL_ALIAS (sys_fanotify_mark, SyS_fanotify_mark);#endif +#if defined(CONFIG_PROC_FS ) && defined(CONFIG_CHECKPOINT_RESTORE ) +int is_file_fanotify (struct file *file) +{ +return file->f_op == &fanotify_fops; +} + +static int __init fanotify_register_fdinfo_driver (void ) +{ +return proc_register_fdinfo_driver (&fanotify_fdinfo); +} +#else +void fanotify_register_fdinfo_driver (void ) { } +#endif /* CONFIG_PROC_FS && CONFIG_CHECKPOINT_RESTORE */ +/* * fanotify_user_setup - Our initialization function. Note that we cannot return * error because we have compiled-in VFS hooks. So an (unlikely) failure here
@@ -883,7 +898,7 @@ static int __init fanotify_user_setup(vo fanotify_mark_cache =KMEM_CACHE (fsnotify_mark,SLAB_PANIC ); fanotify_response_event_cache =KMEM_CACHE (fanotify_response_event,SLAB_PANIC ); - +fanotify_register_fdinfo_driver ();return 0 ; }device_initcall (fanotify_user_setup);
fs/notify/fdinfo.c new file +216 -0
216 lines not on this page · raw message
fs/notify/fdinfo.h new file +19 -0
@@ -0,0 +1,19 @@ +#ifndef __FSNOTIFY_FDINFO_H__ +#define __FSNOTIFY_FDINFO_H__ + +#include <linux/errno.h> +#include <linux/proc_fs.h> + +#if defined(CONFIG_PROC_FS ) && defined(CONFIG_CHECKPOINT_RESTORE ) + +#ifdef CONFIG_INOTIFY_USER +extern struct proc_fdinfo_driver inotify_fdinfo; +#endif + +#ifdef CONFIG_FANOTIFY +extern struct proc_fdinfo_driver fanotify_fdinfo; +#endif + +#endif + +#endif /* __FSNOTIFY_FDINFO_H__ */
fs/notify/inotify/inotify_user.c +32 -0
@@ -38,8 +38,12 @@#include <linux/uaccess.h> #include <linux/poll.h> #include <linux/wait.h> +#include <linux/seq_file.h> +#include <linux/exportfs.h> +#include <linux/proc_fs.h> #include "inotify.h" +#include "../fdinfo.h" #include <asm/ioctls.h>
@@ -827,6 +831,26 @@ out:return ret; } +#if defined(CONFIG_PROC_FS ) && defined(CONFIG_CHECKPOINT_RESTORE ) +int is_file_inotify (struct file *file) +{ +return file->f_op == &inotify_fops; +} + +static int __init inotify_register_fdinfo_driver (void ) +{ +return proc_register_fdinfo_driver (&inotify_fdinfo); +} + +static void __exit inotify_unregister_fdinfo_driver(void) +{ +proc_unregister_fdinfo_driver (&inotify_fdinfo); +} +#else +static int __init inotify_register_fdinfo_driver (void ) {return 0 ; } +static void __exit inotify_unregister_fdinfo_driver(void) { } +#endif /* CONFIG_PROC_FS && CONFIG_CHECKPOINT_RESTORE */ +/* * inotify_user_setup - Our initialization function. Note that we cannot return * error because we have compiled-in VFS hooks. So an (unlikely) failure here
@@ -862,6 +886,14 @@ static int __init inotify_user_setup(voi inotify_max_user_instances =128 ; inotify_max_user_watches =8192 ; +inotify_register_fdinfo_driver (); +return 0 ; }module_init (inotify_user_setup); + +static void __exit inotify_user_exit(void) +{ +inotify_unregister_fdinfo_driver (); +} +module_exit (inotify_user_exit);
Re: [patch 7/8] fs, notify: Add procfs fdinfo helper v3
Quoted 27 lines · Cyrill Gorcunov
This allow us to print out fsnotify details such as watchee inode, device, mask and file handle.
For example for inotify objects the output is
| pos: 0 | flags: 02000000 | inotify wd: 3 ino: 9e7e sdev: 800013 mask: 800afce ignored_mask: 0 fhandle-bytes: 8 fhandle-type: 1 f_handle: 7e9e0000640d1b6d | inotify wd: 2 ino: a111 sdev: 800013 mask: 800afce ignored_mask: 0 fhandle-bytes: 8 fhandle-type: 1 f_handle: 11a1000020542153 | inotify wd: 1 ino: 6b149 sdev: 800013 mask: 800afce ignored_mask: 0 fhandle-bytes: 8 fhandle-type: 1 f_handle: 49b1060023552153For fanotify it is like
| pos: 0 | flags: 02 | fanotify ino: 68f71 sdev: 800013 mask: 1 ignored_mask: 40000000 fhandle-bytes: 8 fhandle-type: 1 f_handle: 718f0600b9f42053 | fanotify mnt_id: 13 mask: 1 ignored_mask: 40000000This feature is
CONFIG_CHECKPOINT_RESTOREonly. To minimize impact on general fsnotify code the new functionality is gathered infs/notify/fdinfo.cfile mostly.v2:
- append missing colons to terms
v3:
- continue from pervious position in list on ->next
Quoted 6 lines
Signed-off-by Cyrill Gorcunov <[email protected]>CC Al Viro <[email protected]>CC Alexey Dobriyan <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[email protected]>CC James Bottomley <[email protected]>
PATCH 8/8 fdinfo: Show sigmask for signalfd fd
In reply to Cyrill Gorcunov--- fs/proc/array.c | 2 - fs/signalfd.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/proc_fs.h | 3 ++ 3 files changed, 67 insertions(+), 1 deletion(-)
fs/proc/array.c +1 -1
@@ -220,7 +220,7 @@ static inline void task_state(struct seqseq_putc (m,'\n' ); } -static void render_sigset_t (struct seq_file *m,const char *header, +void render_sigset_t (struct seq_file *m,const char *header,sigset_t *set) {int i;
fs/signalfd.c +63 -0
91 lines not on this page · raw message
include/linux/proc_fs.h +3 -0
@@ -316,4 +316,7 @@ static inline struct net *PDE_NET(struct return pde->parent->data; } +#include <asm/signal.h> + +void render_sigset_t (struct seq_file *m,const char *header,sigset_t *set);#endif /* _LINUX_PROC_FS_H */