Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 10:29:27PM +0100, Al Viro wrote: > This, BTW, is too convoluted for its own good. What you need is > something like > struct whatever { > struct seq_file *m; > struct file *f; > int flags; > }; > with single allocation of that sucker in your ->open(). Set > file->private_data to address of seq_file field in your object *before* > calling seq_open() and don't bother with m->private at all - just use > container_of(m, struct whatever, m) in your ->show() to get to that > structure... Al, does the version below looks better? (Since it's harder to review diff, here is the code after the patch applied). --- struct proc_fdinfo { struct seq_file m; struct file *fd_file; int f_flags; }; static int seq_show(struct seq_file *m, void *v) { struct proc_fdinfo *fdinfo = container_of(m, struct proc_fdinfo, m); seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", (long long)fdinfo->fd_file->f_pos, fdinfo->f_flags); return 0; } static int seq_fdinfo_open(struct inode *inode, struct file *file) { struct proc_fdinfo *fdinfo = NULL; struct files_struct *files = NULL; struct task_struct *task; struct file *fd_file; int f_flags, ret; ret = -ENOENT; task = get_proc_task(inode); if (task) { files = get_files_struct(task); put_task_struct(task); } if (files) { int fd = proc_fd(inode); spin_lock(>file_lock); fd_file = fcheck_files(files, fd); if (fd_file) { struct fdtable *fdt = files_fdtable(files); f_flags = fd_file->f_flags & ~O_CLOEXEC; if (close_on_exec(fd, fdt)) f_flags |= O_CLOEXEC; get_file(fd_file); ret = 0; } spin_unlock(>file_lock); put_files_struct(files); } if (ret) return ret; ret = -ENOMEM; fdinfo = kmalloc(sizeof(*fdinfo), GFP_KERNEL); if (!fdinfo) goto err_put; fdinfo->fd_file = fd_file; fdinfo->f_flags = f_flags; file->private_data = >m; ret = single_open(file, seq_show, NULL); if (ret) goto err_free; return 0; err_free: kfree(fdinfo); err_put: fput(fd_file); return ret; } static int seq_fdinfo_release(struct inode *inode, struct file *file) { struct proc_fdinfo *fdinfo = container_of((struct seq_file *)file->private_data, struct proc_fdinfo, m); fput(fdinfo->fd_file); 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, }; --- From: Cyrill Gorcunov Subject: procfs: Convert /proc/pid/fdinfo/ handling routines to seq-file v2 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_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). v2 (by Al Viro): - Don't use helper function with optional arguments, thus proc_fd_info get deprecated - Use proc_fdinfo structure with seq_file embedded, thus we can use container_of helper - Use fput to free reference to the file we've grabbed Signed-off-by: Cyrill Gorcunov CC: Pavel Emelyanov CC: Al Viro CC: Alexey Dobriyan CC: Andrew Morton CC: James Bottomley --- fs/proc/fd.c | 145 --- 1 file changed, 99 insertions(+), 46 deletions(-) Index: linux-2.6.git/fs/proc/fd.c === --- linux-2.6.git.orig/fs/proc/fd.c +++ linux-2.6.git/fs/proc/fd.c @@ -6,61 +6,105 @@ #include #include #include +#include +#include #include #include "internal.h" #include "fd.h" -#define PROC_FDINFO_MAX 64 +struct proc_fdinfo { + struct seq_file m; + struct file *fd_file; + int f_flags; +}; + +static int seq_show(struct seq_file *m, void *v) +{ + struct proc_fdinfo *fdinfo = container_of(m, struct proc_fdinfo, m); + seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", + (long long)fdinfo->fd_file->f_pos, fdinfo->f_flags); + return 0; +} -static int proc_fd_info(struct inode *inode, struct path *path, char *info) +static int seq_fdinfo_open(struct inode *inode, struct file
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 10:29:27PM +0100, Al Viro wrote: This, BTW, is too convoluted for its own good. What you need is something like struct whatever { struct seq_file *m; struct file *f; int flags; }; with single allocation of that sucker in your -open(). Set file-private_data to address of seq_file field in your object *before* calling seq_open() and don't bother with m-private at all - just use container_of(m, struct whatever, m) in your -show() to get to that structure... Al, does the version below looks better? (Since it's harder to review diff, here is the code after the patch applied). --- struct proc_fdinfo { struct seq_file m; struct file *fd_file; int f_flags; }; static int seq_show(struct seq_file *m, void *v) { struct proc_fdinfo *fdinfo = container_of(m, struct proc_fdinfo, m); seq_printf(m, pos:\t%lli\nflags:\t0%o\n, (long long)fdinfo-fd_file-f_pos, fdinfo-f_flags); return 0; } static int seq_fdinfo_open(struct inode *inode, struct file *file) { struct proc_fdinfo *fdinfo = NULL; struct files_struct *files = NULL; struct task_struct *task; struct file *fd_file; int f_flags, ret; ret = -ENOENT; task = get_proc_task(inode); if (task) { files = get_files_struct(task); put_task_struct(task); } if (files) { int fd = proc_fd(inode); spin_lock(files-file_lock); fd_file = fcheck_files(files, fd); if (fd_file) { struct fdtable *fdt = files_fdtable(files); f_flags = fd_file-f_flags ~O_CLOEXEC; if (close_on_exec(fd, fdt)) f_flags |= O_CLOEXEC; get_file(fd_file); ret = 0; } spin_unlock(files-file_lock); put_files_struct(files); } if (ret) return ret; ret = -ENOMEM; fdinfo = kmalloc(sizeof(*fdinfo), GFP_KERNEL); if (!fdinfo) goto err_put; fdinfo-fd_file = fd_file; fdinfo-f_flags = f_flags; file-private_data = fdinfo-m; ret = single_open(file, seq_show, NULL); if (ret) goto err_free; return 0; err_free: kfree(fdinfo); err_put: fput(fd_file); return ret; } static int seq_fdinfo_release(struct inode *inode, struct file *file) { struct proc_fdinfo *fdinfo = container_of((struct seq_file *)file-private_data, struct proc_fdinfo, m); fput(fdinfo-fd_file); 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, }; --- From: Cyrill Gorcunov gorcu...@openvz.org Subject: procfs: Convert /proc/pid/fdinfo/ handling routines to seq-file v2 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_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). v2 (by Al Viro): - Don't use helper function with optional arguments, thus proc_fd_info get deprecated - Use proc_fdinfo structure with seq_file embedded, thus we can use container_of helper - Use fput to free reference to the file we've grabbed Signed-off-by: Cyrill Gorcunov gorcu...@openvz.org CC: Pavel Emelyanov xe...@parallels.com CC: Al Viro v...@zeniv.linux.org.uk CC: Alexey Dobriyan adobri...@gmail.com CC: Andrew Morton a...@linux-foundation.org CC: James Bottomley jbottom...@parallels.com --- fs/proc/fd.c | 145 --- 1 file changed, 99 insertions(+), 46 deletions(-) Index: linux-2.6.git/fs/proc/fd.c === --- linux-2.6.git.orig/fs/proc/fd.c +++ linux-2.6.git/fs/proc/fd.c @@ -6,61 +6,105 @@ #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 { + struct seq_file m; + struct file *fd_file; + int f_flags; +}; + +static int seq_show(struct seq_file *m, void *v) +{ + struct proc_fdinfo *fdinfo = container_of(m, struct proc_fdinfo, m); + seq_printf(m, pos:\t%lli\nflags:\t0%o\n, + (long
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 10:29:27PM +0100, Al Viro wrote: > > This, BTW, is too convoluted for its own good. What you need is > something like > struct whatever { > struct seq_file *m; > struct file *f; > int flags; > }; > with single allocation of that sucker in your ->open(). Set > file->private_data to address of seq_file field in your object *before* > calling seq_open() and don't bother with m->private at all - just use > container_of(m, struct whatever, m) in your ->show() to get to that > structure... I will try and post results, thanks! Cyrill -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 10:16:28PM +0100, Al Viro wrote: > On Wed, Aug 15, 2012 at 01:21:19PM +0400, Cyrill Gorcunov wrote: > > -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) > > Bloody bad taste, that... This kind of optional arguments is almost always > a bad sign - tends to happen when you have two barely related functions > crammed into one. And yes, proc_fd_info() suffers the same braindamage. > Trying to avoid code duplication is generally a good thing, but it's not > always worth doing - less obfuscated code wins. Sure I'll update. Thanks. > > 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; > > + int ret; > > + > > + ret = seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", > > +(long long)fdinfo->f_file->f_pos, > > +fdinfo->f_flags); > > Realistically, that one is not going to overflow; you are almost certainly > wasting more cycles on that check of !ret just below than you'll save on > not going into ->show_fdinfo() in case of full buffer. Yes, this is redundant, thanks. Will fix. > > > + if (!ret && fdinfo->f_file->f_op->show_fdinfo) > > + ret = fdinfo->f_file->f_op->show_fdinfo(m, fdinfo->f_file); > > + > > + return ret; > > } > > > + ret = single_open(file, seq_show, fdinfo); > > + if (ret) { > > + put_filp(fdinfo->f_file); > > Excuse me? We should *never* do put_filp() on anything that has already > been opened. Think what happens if you race with close(); close() would > rip the reference from descriptor table and do fput(), leaving you with > the last reference to that struct file. You really don't want to just > go and free it. IOW, that one should be fput(). > > > + put_filp(fdinfo->f_file); > Ditto. It seems I indeed missed this scenario, thanks Al, will update! Cyrill -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:21:19PM +0400, Cyrill Gorcunov wrote: > struct proc_fdinfo { > - loff_t f_pos; > - int f_flags; > + struct file *f_file; > + int f_flags; > }; > + struct proc_fdinfo *fdinfo; > + struct seq_file *m; > + int ret; > > fdinfo = kzalloc(sizeof(*fdinfo), GFP_KERNEL); > if (!fdinfo) > return -ENOMEM; > + ret = single_open(file, seq_show, fdinfo); > + if (ret) { > + put_filp(fdinfo->f_file); > + goto err_free; > } > > + m = file->private_data; > + m->private = fdinfo; This, BTW, is too convoluted for its own good. What you need is something like struct whatever { struct seq_file *m; struct file *f; int flags; }; with single allocation of that sucker in your ->open(). Set file->private_data to address of seq_file field in your object *before* calling seq_open() and don't bother with m->private at all - just use container_of(m, struct whatever, m) in your ->show() to get to that structure... -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:21:19PM +0400, Cyrill Gorcunov wrote: > -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) Bloody bad taste, that... This kind of optional arguments is almost always a bad sign - tends to happen when you have two barely related functions crammed into one. And yes, proc_fd_info() suffers the same braindamage. Trying to avoid code duplication is generally a good thing, but it's not always worth doing - less obfuscated code wins. > 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; > + int ret; > + > + ret = seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", > + (long long)fdinfo->f_file->f_pos, > + fdinfo->f_flags); Realistically, that one is not going to overflow; you are almost certainly wasting more cycles on that check of !ret just below than you'll save on not going into ->show_fdinfo() in case of full buffer. > + if (!ret && fdinfo->f_file->f_op->show_fdinfo) > + ret = fdinfo->f_file->f_op->show_fdinfo(m, fdinfo->f_file); > + > + return ret; > } > + ret = single_open(file, seq_show, fdinfo); > + if (ret) { > + put_filp(fdinfo->f_file); Excuse me? We should *never* do put_filp() on anything that has already been opened. Think what happens if you race with close(); close() would rip the reference from descriptor table and do fput(), leaving you with the last reference to that struct file. You really don't want to just go and free it. IOW, that one should be fput(). > + put_filp(fdinfo->f_file); Ditto. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:07:03AM +0100, Al Viro wrote: > On Wed, Aug 15, 2012 at 02:21:47AM +0400, Cyrill Gorcunov wrote: > > > 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). > > > > 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? > > 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 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). Signed-off-by: Cyrill Gorcunov CC: Pavel Emelyanov CC: Al Viro CC: Alexey Dobriyan CC: Andrew Morton CC: James Bottomley --- fs/proc/fd.c | 51 --- include/linux/fs.h |3 +++ 2 files changed, 39 insertions(+), 15 deletions(-) Index: linux-2.6.git/fs/proc/fd.c === --- linux-2.6.git.orig/fs/proc/fd.c +++ linux-2.6.git/fs/proc/fd.c @@ -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(_file->f_path); } + if (f_file) { + *f_file = fd_file; + get_file(fd_file); + } ret = 0; } spin_unlock(>file_lock); @@ -61,28 +65,44 @@ static int fdinfo_open_helper(struct ino 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; + 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, >f_flags, NULL); - if (!ret) { - ret = single_open(file, seq_show, fdinfo); - if (!ret) - fdinfo = NULL; + ret = fdinfo_open_helper(inode, >f_flags, >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 ino struct 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 ti static 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 * Index: linux-2.6.git/include/linux/fs.h
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:07:03AM +0100, Al Viro wrote: On Wed, Aug 15, 2012 at 02:21:47AM +0400, Cyrill Gorcunov wrote: 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). 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? 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 gorcu...@openvz.org 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). Signed-off-by: Cyrill Gorcunov gorcu...@openvz.org CC: Pavel Emelyanov xe...@parallels.com CC: Al Viro v...@zeniv.linux.org.uk CC: Alexey Dobriyan adobri...@gmail.com CC: Andrew Morton a...@linux-foundation.org CC: James Bottomley jbottom...@parallels.com --- fs/proc/fd.c | 51 --- include/linux/fs.h |3 +++ 2 files changed, 39 insertions(+), 15 deletions(-) Index: linux-2.6.git/fs/proc/fd.c === --- linux-2.6.git.orig/fs/proc/fd.c +++ linux-2.6.git/fs/proc/fd.c @@ -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 ino 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; + 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 ino struct 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 ti static 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);
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:21:19PM +0400, Cyrill Gorcunov wrote: -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) Bloody bad taste, that... This kind of optional arguments is almost always a bad sign - tends to happen when you have two barely related functions crammed into one. And yes, proc_fd_info() suffers the same braindamage. Trying to avoid code duplication is generally a good thing, but it's not always worth doing - less obfuscated code wins. 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; + int ret; + + ret = seq_printf(m, pos:\t%lli\nflags:\t0%o\n, + (long long)fdinfo-f_file-f_pos, + fdinfo-f_flags); Realistically, that one is not going to overflow; you are almost certainly wasting more cycles on that check of !ret just below than you'll save on not going into -show_fdinfo() in case of full buffer. + if (!ret fdinfo-f_file-f_op-show_fdinfo) + ret = fdinfo-f_file-f_op-show_fdinfo(m, fdinfo-f_file); + + return ret; } + ret = single_open(file, seq_show, fdinfo); + if (ret) { + put_filp(fdinfo-f_file); Excuse me? We should *never* do put_filp() on anything that has already been opened. Think what happens if you race with close(); close() would rip the reference from descriptor table and do fput(), leaving you with the last reference to that struct file. You really don't want to just go and free it. IOW, that one should be fput(). + put_filp(fdinfo-f_file); Ditto. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:21:19PM +0400, Cyrill Gorcunov wrote: struct proc_fdinfo { - loff_t f_pos; - int f_flags; + struct file *f_file; + int f_flags; }; + struct proc_fdinfo *fdinfo; + struct seq_file *m; + int ret; fdinfo = kzalloc(sizeof(*fdinfo), GFP_KERNEL); if (!fdinfo) return -ENOMEM; + ret = single_open(file, seq_show, fdinfo); + if (ret) { + put_filp(fdinfo-f_file); + goto err_free; } + m = file-private_data; + m-private = fdinfo; This, BTW, is too convoluted for its own good. What you need is something like struct whatever { struct seq_file *m; struct file *f; int flags; }; with single allocation of that sucker in your -open(). Set file-private_data to address of seq_file field in your object *before* calling seq_open() and don't bother with m-private at all - just use container_of(m, struct whatever, m) in your -show() to get to that structure... -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 10:16:28PM +0100, Al Viro wrote: On Wed, Aug 15, 2012 at 01:21:19PM +0400, Cyrill Gorcunov wrote: -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) Bloody bad taste, that... This kind of optional arguments is almost always a bad sign - tends to happen when you have two barely related functions crammed into one. And yes, proc_fd_info() suffers the same braindamage. Trying to avoid code duplication is generally a good thing, but it's not always worth doing - less obfuscated code wins. Sure I'll update. Thanks. 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; + int ret; + + ret = seq_printf(m, pos:\t%lli\nflags:\t0%o\n, +(long long)fdinfo-f_file-f_pos, +fdinfo-f_flags); Realistically, that one is not going to overflow; you are almost certainly wasting more cycles on that check of !ret just below than you'll save on not going into -show_fdinfo() in case of full buffer. Yes, this is redundant, thanks. Will fix. + if (!ret fdinfo-f_file-f_op-show_fdinfo) + ret = fdinfo-f_file-f_op-show_fdinfo(m, fdinfo-f_file); + + return ret; } + ret = single_open(file, seq_show, fdinfo); + if (ret) { + put_filp(fdinfo-f_file); Excuse me? We should *never* do put_filp() on anything that has already been opened. Think what happens if you race with close(); close() would rip the reference from descriptor table and do fput(), leaving you with the last reference to that struct file. You really don't want to just go and free it. IOW, that one should be fput(). + put_filp(fdinfo-f_file); Ditto. It seems I indeed missed this scenario, thanks Al, will update! Cyrill -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 10:29:27PM +0100, Al Viro wrote: This, BTW, is too convoluted for its own good. What you need is something like struct whatever { struct seq_file *m; struct file *f; int flags; }; with single allocation of that sucker in your -open(). Set file-private_data to address of seq_file field in your object *before* calling seq_open() and don't bother with m-private at all - just use container_of(m, struct whatever, m) in your -show() to get to that structure... I will try and post results, thanks! Cyrill -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 02:21:47AM +0400, Cyrill Gorcunov wrote: > > 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). > > 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? I seriously doubt that it's worth bothering. If somebody cares, they can add making it conditional later. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:56:16AM +0400, Cyrill Gorcunov wrote: > > > struct file_operations { > > > struct 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... > > 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). 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? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 10:27:21PM +0100, Al Viro wrote: > On Tue, Aug 14, 2012 at 11:56:49PM +0400, Cyrill Gorcunov wrote: > > Al, does the patch below looks better? If so I'll fix up the rest. > > > struct file_operations { > > struct 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... 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 11:56:49PM +0400, Cyrill Gorcunov wrote: > Al, does the patch below looks better? If so I'll fix up the rest. > struct file_operations { > struct 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... -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 10:35:58PM +0400, Cyrill Gorcunov wrote: > On Tue, Aug 14, 2012 at 07:31:42PM +0100, Al Viro wrote: > > > 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. > > > > 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. > > 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! 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(-) Index: linux-2.6.git/fs/proc/fd.c === --- linux-2.6.git.orig/fs/proc/fd.c +++ linux-2.6.git/fs/proc/fd.c @@ -8,18 +8,14 @@ #include #include #include +#include #include #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(_file->f_path); } + if (f_file) { + *f_file = fd_file; + get_file(fd_file); + } ret = 0; } spin_unlock(>file_lock); @@ -58,43 +58,110 @@ static int fdinfo_open_helper(struct ino return 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, >f_flags, NULL); + ret = seq_open(file, _seq_ops); if (!ret) { -
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 07:31:42PM +0100, Al Viro wrote: > > 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. > > 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. 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 06:03:45PM +0400, Cyrill Gorcunov wrote: > 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_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. 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. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On 08/14/2012 06:03 PM, Cyrill Gorcunov wrote: > 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_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. > > Signed-off-by: Cyrill Gorcunov > CC: Al Viro > CC: Alexey Dobriyan > CC: Andrew Morton > CC: Pavel Emelyanov > CC: James Bottomley Acked-by: Pavel Emelyanov -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On 08/14/2012 06:03 PM, Cyrill Gorcunov wrote: 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_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. Signed-off-by: Cyrill Gorcunov gorcu...@openvz.org CC: Al Viro v...@zeniv.linux.org.uk CC: Alexey Dobriyan adobri...@gmail.com CC: Andrew Morton a...@linux-foundation.org CC: Pavel Emelyanov xe...@parallels.com CC: James Bottomley jbottom...@parallels.com Acked-by: Pavel Emelyanov xe...@parallels.com -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 06:03:45PM +0400, Cyrill Gorcunov wrote: 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_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. 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. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 07:31:42PM +0100, Al Viro wrote: 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. 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. 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 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 10:35:58PM +0400, Cyrill Gorcunov wrote: On Tue, Aug 14, 2012 at 07:31:42PM +0100, Al Viro wrote: 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. 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. 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! 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(-) Index: linux-2.6.git/fs/proc/fd.c === --- linux-2.6.git.orig/fs/proc/fd.c +++ linux-2.6.git/fs/proc/fd.c @@ -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 ino return 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) { -
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 11:56:49PM +0400, Cyrill Gorcunov wrote: Al, does the patch below looks better? If so I'll fix up the rest. struct file_operations { struct 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... -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Tue, Aug 14, 2012 at 10:27:21PM +0100, Al Viro wrote: On Tue, Aug 14, 2012 at 11:56:49PM +0400, Cyrill Gorcunov wrote: Al, does the patch below looks better? If so I'll fix up the rest. struct file_operations { struct 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... 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 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 01:56:16AM +0400, Cyrill Gorcunov wrote: struct file_operations { struct 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... 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). 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? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 3/8] procfs: Add ability to plug in auxiliary fdinfo providers
On Wed, Aug 15, 2012 at 02:21:47AM +0400, Cyrill Gorcunov wrote: 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). 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? I seriously doubt that it's worth bothering. If somebody cares, they can add making it conditional later. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/