auxiliary fdinfo, new round
Subsystems (6)
cover auxiliary fdinfo, new round
Hi Al, could you please share your opinion on this series? Is there something I should fix or redesign?
Cyrill
PATCH 1/7 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.
In particular 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 inside struct file_operations (as Al and Pavel are proposing).
--- fs/proc/fd.c | 2 ++ include/linux/fs.h | 3 +++ 2 files changed, 5 insertions(+)
fs/proc/fd.c +2 -0
@@ -50,6 +50,8 @@ static int seq_show(struct seq_file *m,if (!ret) {seq_printf (m,"pos:\t%lli\nflags:\t0%o\n" , (long long )file->f_pos, f_flags); +if (file->f_op->show_fdinfo) + ret = file->f_op->show_fdinfo (m, file);fput (file); }
include/linux/fs.h +3 -0
@@ -1774,6 +1774,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 );
@@ -1802,6 +1804,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 {
Re: [patch 1/7] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 10 lines · Cyrill Gorcunov
This patch brings ability to print out auxiliary data associated with file in procfs interface
/proc/pid/fdinfo/fd.In particular 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_fdinfocallback inside structfile_operations(as Al and Pavel are proposing).
Hi, sorry for bothering but is there some opinions on this series?
(I've found that epoll change log has not been well refreshed and
says that this fdinfo feature is config-checkpoint-restore dependant, but in real this config entry was ripped off during conversation).
So, at moment I somehow confused since it's a bit unclear where to move, either this series is more-less acceptible or not. I could bring back all config-checkpoint-restore dependency (since I still believe this feature better to be enabled not by default but iif user has asked fo it).
Re: [patch 1/7] procfs: Add ability to plug in auxiliary fdinfo providers
Quoted 8 lines · Cyrill Gorcunov
Quoted 7 lines · Cyrill Gorcunov
This patch brings ability to print out auxiliary data associated with file in procfs interface
/proc/pid/fdinfo/fd.In particular further patches make eventfd, evenpoll, signalfd and fsnotify to print additional information complete enough to restore these objects after checkpoint.
Quoted 5 lines
Quoted 3 lines
To simplify the code we add
show_fdinfocallback inside structfile_operations(as Al and Pavel are proposing).Hi, sorry for bothering but is there some opinions on this series?
Al, we'd appreciate if you share your plans about this series. Please.
Quoted 11 lines
(I've found that epoll change log has not been well refreshed and
says that this fdinfo feature is config-checkpoint-restore dependant, but in real this config entry was ripped off during conversation).So, at moment I somehow confused since it's a bit unclear where to move, either this series is more-less acceptible or not. I could bring back all config-checkpoint-restore dependency (since I still believe this feature better to be enabled not by default but iif user has asked fo it).
.
Thanks,
Pavel
PATCH 2/7 fs, exportfs: Escape nil dereference if no s_export_op present
In reply to Cyrill GorcunovThis routine will be used to generate a file handle in fdinfo output for inotify subsystem, where if no s_export_op present the general export_encode_fh should be used. Thus add a test if s_export_op present inside exportfs_encode_fh itself.
--- fs/exportfs/expfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/exportfs/expfs.c +1 -1
@@ -357,7 +357,7 @@ int exportfs_encode_fh(struct dentry *de*/ parent = p->d_inode; } -if (nop->encode_fh) +if (nop && nop->encode_fh) error = nop->encode_fh (inode, fid->raw, max_len, parent);else error =export_encode_fh (inode, fid, max_len, parent);
PATCH 3/7 fs, notify: Add file handle entry into inotify_inode_mark
In reply to Cyrill GorcunovThis file handle will be used in /proc/pid/fdinfo/fd output, which in turn will allow to restore a watch target after checkpoint.
--- fs/notify/inotify/inotify.h | 8 +++++++ fs/notify/inotify/inotify_user.c | 42 ++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 5 deletions(-)
fs/notify/inotify/inotify.h +8 -0
@@ -1,6 +1,7 @@#include <linux/fsnotify_backend.h> #include <linux/inotify.h> #include <linux/slab.h> /* struct kmem_cache */ +#include <linux/exportfs.h> extern struct kmem_cache *event_priv_cachep;
@@ -9,9 +10,16 @@ struct inotify_event_private_data {int wd; }; +#if defined(CONFIG_PROC_FS ) && defined(CONFIG_EXPORTFS ) && defined(CONFIG_CHECKPOINT_RESTORE ) +# define INOTIFY_USE_FHANDLE +#endif +struct inotify_inode_mark {struct fsnotify_mark fsn_mark;int wd; +#ifdef INOTIFY_USE_FHANDLE +__u8 fhandle[sizeof (struct file_handle ) +MAX_HANDLE_SZ ]; +#endif }; extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
fs/notify/inotify/inotify_user.c +37 -5
82 lines not on this page · raw message
PATCH 4/7 fs, notify: Add procfs fdinfo helper v4
In reply to Cyrill GorcunovThis allow us to print out fsnotify details such as watchee inode, device, mask and optionally a file handle.
For inotify objects if kernel compiled with exportfs support the output will be
| 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
If kernel compiled without exportfs support, the file handle won't be provided but inode and device only.
| pos: 0 | flags: 02000000 | inotify wd: 3 ino: 9e7e sdev: 800013 mask: 800afce ignored_mask: 0 | inotify wd: 2 ino: a111 sdev: 800013 mask: 800afce ignored_mask: 0 | inotify wd: 1 ino: 6b149 sdev: 800013 mask: 800afce ignored_mask: 0
For fanotify the output is like
| pos: 0 | flags: 02 | fanotify ino: 68f71 sdev: 800013 mask: 1 ignored_mask: 40000000 | fanotify mnt_id: 13 mask: 1 ignored_mask: 40000000
To minimize impact on general fsnotify code the new functionality is gathered in fs/notify/fdinfo.c file.
--- fs/notify/Makefile | 2 fs/notify/fanotify/fanotify_user.c | 4 + fs/notify/fdinfo.c | 124 +++++++++++++++++++++++++++++++++++++ fs/notify/fdinfo.h | 22 ++++++ fs/notify/inotify/inotify_user.c | 4 + 5 files changed, 155 insertions(+), 1 deletion(-)
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 +4 -0
@@ -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
@@ -446,6 +447,9 @@ static long fanotify_ioctl(struct file * }static const struct file_operations fanotify_fops = { +#ifdef CONFIG_PROC_FS + .show_fdinfo = fanotify_show_fdinfo, +#endif .poll = fanotify_poll, .read = fanotify_read, .write = fanotify_write,
fs/notify/fdinfo.c new file +124 -0
124 lines not on this page · raw message
fs/notify/fdinfo.h new file +22 -0
@@ -0,0 +1,22 @@ +#ifndef __FSNOTIFY_FDINFO_H__ +#define __FSNOTIFY_FDINFO_H__ + +#include <linux/errno.h> +#include <linux/proc_fs.h> + +struct seq_file ; +struct file ; + +#ifdef CONFIG_PROC_FS + +#ifdef CONFIG_INOTIFY_USER +extern int inotify_show_fdinfo (struct seq_file *m,struct file *f); +#endif + +#ifdef CONFIG_FANOTIFY +extern int fanotify_show_fdinfo (struct seq_file *m,struct file *f); +#endif + +#endif /* CONFIG_PROC_FS */ + +#endif /* __FSNOTIFY_FDINFO_H__ */
fs/notify/inotify/inotify_user.c +4 -0
@@ -40,6 +40,7 @@#include <linux/wait.h> #include "inotify.h" +#include "../fdinfo.h" #include <asm/ioctls.h>
@@ -335,6 +336,9 @@ static long inotify_ioctl(struct file *f }static const struct file_operations inotify_fops = { +#ifdef CONFIG_PROC_FS + .show_fdinfo = inotify_show_fdinfo, +#endif .poll = inotify_poll, .read = inotify_read, .fasync = inotify_fasync,
PATCH 5/7 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
--- fs/eventfd.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
fs/eventfd.c +20 -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;
@@ -284,7 +286,25 @@ static ssize_t eventfd_write(struct filereturn res; } +#ifdef CONFIG_PROC_FS +static int eventfd_show_fdinfo (struct seq_file *m,struct file *f) +{ +struct eventfd_ctx *ctx = f->private_data; +int ret; + +spin_lock_irq (&ctx->wqh.lock); + ret =seq_printf (m,"eventfd-count: %16llx\n" , + (unsigned long long )ctx->count); +spin_unlock_irq (&ctx->wqh.lock); + +return ret; +} +#endif +static const struct file_operations eventfd_fops = { +#ifdef CONFIG_PROC_FS + .show_fdinfo = eventfd_show_fdinfo, +#endif .release = eventfd_release, .poll = eventfd_poll, .read = eventfd_read,
PATCH 6/7 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.
[avagin@: fix for unitialized ret variable]
--- fs/eventpoll.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
fs/eventpoll.c +28 -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:
@@ -783,8 +785,34 @@ static unsigned int ep_eventpoll_poll(streturn pollflags !=-1 ? pollflags :0 ; } +#ifdef CONFIG_PROC_FS +static int ep_show_fdinfo (struct seq_file *m,struct file *f) +{ +struct eventpoll *ep = f->private_data; +struct rb_node *rbp; +int ret =0 ; + +mutex_lock (&ep->mtx); +for (rbp =rb_first (&ep->rbr); rbp; rbp =rb_next (rbp)) { + struct epitem *epi = rb_entry(rbp, struct epitem, rbn); + + ret =seq_printf (m,"tfd: %8d events: %8x data: %16llx\n" , + epi->ffd.fd, epi->event.events, + (long long )epi->event.data); +if (ret) +break ; + } +mutex_unlock (&ep->mtx); + +return ret; +} +#endif +/* File callbacks that implement the eventpoll file behaviour */ static const struct file_operations eventpoll_fops = { +#ifdef CONFIG_PROC_FS + .show_fdinfo = ep_show_fdinfo, +#endif .release = ep_eventpoll_release, .poll = ep_eventpoll_poll, .llseek = noop_llseek,
PATCH 7/7 fdinfo: Show sigmask for signalfd fd v2
In reply to Cyrill Gorcunov--- fs/proc/array.c | 2 +- fs/signalfd.c | 26 ++++++++++++++++++++++++++ include/linux/proc_fs.h | 3 +++ 3 files changed, 30 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 +26 -0
@@ -29,6 +29,7 @@#include <linux/anon_inodes.h> #include <linux/signalfd.h> #include <linux/syscalls.h> +#include <linux/proc_fs.h> void signalfd_cleanup (struct sighand_struct *sighand) {
@@ -46,6 +47,7 @@ void signalfd_cleanup(struct sighand_str }struct signalfd_ctx { +seqcount_t cnt;sigset_t sigmask; };
@@ -227,7 +229,28 @@ static ssize_t signalfd_read(struct filereturn total ? total: ret; } +#ifdef CONFIG_PROC_FS +static int signalfd_show_fdinfo (struct seq_file *m,struct file *f) +{ +struct signalfd_ctx *ctx = f->private_data; +sigset_t sigmask; +unsigned seq; + +do { + seq =read_seqcount_begin (&ctx->cnt); + sigmask = ctx->sigmask; + }while (read_seqcount_retry (&ctx->cnt, seq)); + +signotset (&sigmask); +render_sigset_t (m,"sigmask:\t" , &sigmask); +return 0 ; +} +#endif +static const struct file_operations signalfd_fops = { +#ifdef CONFIG_PROC_FS + .show_fdinfo = signalfd_show_fdinfo, +#endif .release = signalfd_release, .poll = signalfd_poll, .read = signalfd_read,
@@ -259,6 +282,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigreturn -ENOMEM ; ctx->sigmask = sigmask; +seqcount_init (&ctx->cnt);/* * When we call this, the initialization must be complete, since
@@ -279,7 +303,9 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigreturn -EINVAL ; }spin_lock_irq (¤t->sighand->siglock); +write_seqcount_begin (&ctx->cnt); ctx->sigmask = sigmask; +write_seqcount_end (&ctx->cnt);spin_unlock_irq (¤t->sighand->siglock);wake_up (¤t->sighand->signalfd_wqh);
include/linux/proc_fs.h +3 -0
@@ -290,4 +290,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 */