linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2
@ 2013-11-06 11:47 Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 1/7] seq-file: Export single_ helpers Cyrill Gorcunov
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel

Hi, in criu we intensively use additional information provided by
/proc/<pid>/fdinfo/<fd> particular to the object opened file
represents. The output is printed out by calling the
file_operations::show_fdinfo method.

The implementation implies that data is getting printed in one
pass and returns error in case if seq buffer is overflowed, which
works fine while data fit one memory page. For epoll it's about
73 epoll targets can be printed, for notify system -- significantly
less depending on notify type and file handler. This limitation
didn't cause any problems in applications we're checkpointing
and restoring at moment, but might become a problem in future.

So to resolve the problem I considered two ways

1) Don't return error if seq-buffer overflowed thus, one
   show() method is called the kernel will notice that buffer is
   overflowed and double its size returning -EAGAIN. But I fear such
   interface might be misused (say process creates epoll with a number
   of target descriptors, then application opens a big number of fdinfo
   reader causing kernel to allocate big seq-buffer for each reader).

2) Instead of printing fdinfo in one pass rather provide seq-operations
   pointer in file_operations, and subsystems which need it simply hook
   own seq-operations here. The main code in fs/proc/fd.c will call for
   underlied seq-operation methods.

The second way looks more preferrable from my POV, here is the series.
Please take a look, thanks. Any comments are highly appreciated!

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 1/7] seq-file: Export single_ helpers
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  2013-11-06 11:50   ` Christoph Hellwig
  2013-11-06 11:47 ` [patch 2/7] procfs: Introduce sequential fdinfo engine Cyrill Gorcunov
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0000-seq-export-single --]
[-- Type: text/plain, Size: 2375 bytes --]

The single_ helpers will be used in fdinfo output to
eliminate code duplication.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/seq_file.c            |    9 ++++++---
 include/linux/seq_file.h |    3 +++
 2 files changed, 9 insertions(+), 3 deletions(-)

Index: linux-2.6.git/fs/seq_file.c
===================================================================
--- linux-2.6.git.orig/fs/seq_file.c
+++ linux-2.6.git/fs/seq_file.c
@@ -565,20 +565,23 @@ int seq_bitmap_list(struct seq_file *m,
 }
 EXPORT_SYMBOL(seq_bitmap_list);
 
-static void *single_start(struct seq_file *p, loff_t *pos)
+void *single_start(struct seq_file *p, loff_t *pos)
 {
 	return NULL + (*pos == 0);
 }
+EXPORT_SYMBOL(single_start);
 
-static void *single_next(struct seq_file *p, void *v, loff_t *pos)
+void *single_next(struct seq_file *p, void *v, loff_t *pos)
 {
 	++*pos;
 	return NULL;
 }
+EXPORT_SYMBOL(single_next);
 
-static void single_stop(struct seq_file *p, void *v)
+void single_stop(struct seq_file *p, void *v)
 {
 }
+EXPORT_SYMBOL(single_stop);
 
 int single_open(struct file *file, int (*show)(struct seq_file *, void *),
 		void *data)
Index: linux-2.6.git/include/linux/seq_file.h
===================================================================
--- linux-2.6.git.orig/include/linux/seq_file.h
+++ linux-2.6.git/include/linux/seq_file.h
@@ -122,6 +122,9 @@ static inline int seq_nodemask_list(stru
 	return seq_bitmap_list(m, mask->bits, MAX_NUMNODES);
 }
 
+void *single_start(struct seq_file *, loff_t *);
+void *single_next(struct seq_file *, void *, loff_t *);
+void single_stop(struct seq_file *, void *);
 int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
 int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t);
 int single_release(struct inode *, struct file *);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 2/7] procfs: Introduce sequential fdinfo engine
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 1/7] seq-file: Export single_ helpers Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 3/7] epoll: Use " Cyrill Gorcunov
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0001-procfs-fdinfo-new-6 --]
[-- Type: text/plain, Size: 6123 bytes --]

At moment the fdinfo operations (ie the output from /proc/$pid/fdinfo/$fd)
are generating output in one pass, allocating one page buffer as a maximum.
But in case of lots of event polls watchees (75 and more) read procedure
will fail because one page is not enough to provide all information
associated with watch descriptors.

Instead, provide proc_fdinfo structure where each file hook own seq_operations
for fdinfo output and the seq-file engine will be able to traverse over the all
records and provide the reader complete information increasing buffer size if
needed.

Once all fdinfo callers are converted (addressed in next patches) the former
@show_fdinfo member will be removed.

Note the patch doesn't change current output it's rather preparing
the ground for next patches.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/proc/fd.c       |  141 ++++++++++++++++++++++++++++++++++++++++-------------
 include/linux/fs.h |    1 
 2 files changed, 109 insertions(+), 33 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
@@ -14,60 +14,135 @@
 #include "internal.h"
 #include "fd.h"
 
+struct proc_fdinfo {
+	struct seq_file		seq;	/* Make sure it's first */
+	struct seq_operations	*op;
+	struct file		*f_file;
+	unsigned int		f_flags;
+};
+
+#define seq_info(m)	(container_of(m, struct proc_fdinfo, seq))
+
+static void *seq_start(struct seq_file *m, loff_t *pos)
+{
+	struct proc_fdinfo *info = seq_info(m);
+
+	if (*pos == 0)
+		seq_printf(m, "pos:\t%lli\nflags:\t0%o\n",
+			   (long long)info->f_file->f_pos, info->f_flags);
+
+	return info->op ? info->op->start(m, pos) : NULL + (*pos == 0);
+}
+
+static void seq_stop(struct seq_file *m, void *v)
+{
+	struct proc_fdinfo *info = seq_info(m);
+
+	if (info->op)
+		info->op->stop(m, v);
+}
+
+static void *seq_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct proc_fdinfo *info = seq_info(m);
+
+	if (info->op)
+		return info->op->next(m, p, pos);
+
+	++*pos;
+	return NULL;
+}
+
 static int seq_show(struct seq_file *m, void *v)
 {
+	struct proc_fdinfo *info = seq_info(m);
+
+	if (info->op)
+		return info->op->show(m, v);
+
+	/* Legacy interface */
+	if (info->f_file->f_op->show_fdinfo)
+		return info->f_file->f_op->show_fdinfo(m, info->f_file);
+
+	return 0;
+}
+
+static const struct seq_operations fdinfo_seq_ops = {
+	.start	= seq_start,
+	.stop	= seq_stop,
+	.next	= seq_next,
+	.show	= seq_show,
+};
+
+static int seq_fdinfo_open(struct inode *inode, struct file *file)
+{
 	struct files_struct *files = NULL;
-	int f_flags = 0, ret = -ENOENT;
-	struct file *file = NULL;
+	struct proc_fdinfo *info;
 	struct task_struct *task;
+	int ret;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	file->private_data = &info->seq;
+
+	ret = seq_open(file, &fdinfo_seq_ops);
+	if (!ret) {
+		ret = -ENOENT;
 
-	task = get_proc_task(m->private);
-	if (!task)
-		return -ENOENT;
-
-	files = get_files_struct(task);
-	put_task_struct(task);
-
-	if (files) {
-		int fd = proc_fd(m->private);
-
-		spin_lock(&files->file_lock);
-		file = fcheck_files(files, fd);
-		if (file) {
-			struct fdtable *fdt = files_fdtable(files);
-
-			f_flags = file->f_flags;
-			if (close_on_exec(fd, fdt))
-				f_flags |= O_CLOEXEC;
+		task = get_proc_task(inode);
+		if (task) {
+			files = get_files_struct(task);
+			put_task_struct(task);
+		}
 
-			get_file(file);
-			ret = 0;
+		if (files) {
+			struct seq_file *m = file->private_data;
+			int fd = proc_fd(inode);
+
+			spin_lock(&files->file_lock);
+			info->f_file = fcheck_files(files, fd);
+			if (info->f_file) {
+				struct fdtable *fdt = files_fdtable(files);
+
+				info->f_flags = info->f_file->f_flags & ~O_CLOEXEC;
+				if (close_on_exec(fd, fdt))
+					info->f_flags |= O_CLOEXEC;
+				info->op = info->f_file->f_op->fdinfo_op;
+				m->private = info->f_file;
+
+				get_file(info->f_file);
+				ret = 0;
+			}
+			spin_unlock(&files->file_lock);
+			put_files_struct(files);
 		}
-		spin_unlock(&files->file_lock);
-		put_files_struct(files);
 	}
 
-	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);
+	if (ret) {
+		if (info->f_file)
+			fput(info->f_file);
+		file->private_data = NULL;
+		kfree(info);
 	}
 
 	return ret;
 }
 
-static int seq_fdinfo_open(struct inode *inode, struct file *file)
+static int seq_fdinfo_release(struct inode *inode, struct file *file)
 {
-	return single_open(file, seq_show, inode);
+	struct seq_file *m = file->private_data;
+	struct proc_fdinfo *info = seq_info(m);
+
+	fput(info->f_file);
+	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	= single_release,
+	.release	= seq_fdinfo_release,
 };
 
 static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
Index: linux-2.6.git/include/linux/fs.h
===================================================================
--- linux-2.6.git.orig/include/linux/fs.h
+++ linux-2.6.git/include/linux/fs.h
@@ -1552,6 +1552,7 @@ struct file_operations {
 	long (*fallocate)(struct file *file, int mode, loff_t offset,
 			  loff_t len);
 	int (*show_fdinfo)(struct seq_file *m, struct file *f);
+	struct seq_operations *fdinfo_op;
 };
 
 struct inode_operations {


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 3/7] epoll: Use sequential fdinfo engine
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 1/7] seq-file: Export single_ helpers Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 2/7] procfs: Introduce sequential fdinfo engine Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 4/7] eventfd: " Cyrill Gorcunov
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0002-procfs-fdinfo-epoll-2 --]
[-- Type: text/plain, Size: 2599 bytes --]

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/eventpoll.c |   46 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 12 deletions(-)

Index: linux-2.6.git/fs/eventpoll.c
===================================================================
--- linux-2.6.git.orig/fs/eventpoll.c
+++ linux-2.6.git/fs/eventpoll.c
@@ -833,32 +833,54 @@ static unsigned int ep_eventpoll_poll(st
 }
 
 #ifdef CONFIG_PROC_FS
-static int ep_show_fdinfo(struct seq_file *m, struct file *f)
+static void *seq_start(struct seq_file *m, loff_t *pos)
 {
-	struct eventpoll *ep = f->private_data;
+	struct eventpoll *ep = ((struct file *)m->private)->private_data;
 	struct rb_node *rbp;
-	int ret = 0;
+	loff_t num = *pos;
 
 	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;
+		if (num-- == 0)
+			return rbp;
 	}
+	return NULL;
+}
+
+static void seq_stop(struct seq_file *m, void *v)
+{
+	struct eventpoll *ep = ((struct file *)m->private)->private_data;
 	mutex_unlock(&ep->mtx);
+}
 
-	return ret;
+static void *seq_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	++*pos;
+	return (void *)rb_next(p);
 }
+
+static int seq_show(struct seq_file *m, void *v)
+{
+	struct epitem *epi = rb_entry(v, struct epitem, rbn);
+
+	seq_printf(m, "tfd: %8d events: %8x data: %16llx\n",
+		   epi->ffd.fd, epi->event.events,
+		   (long long)epi->event.data);
+	return 0;
+}
+
+static struct seq_operations ep_fdinfo_op = {
+	.start		= seq_start,
+	.next		= seq_next,
+	.stop		= seq_stop,
+	.show		= seq_show,
+};
 #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,
+	.fdinfo_op	= &ep_fdinfo_op,
 #endif
 	.release	= ep_eventpoll_release,
 	.poll		= ep_eventpoll_poll,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 4/7] eventfd: Use sequential fdinfo engine
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
                   ` (2 preceding siblings ...)
  2013-11-06 11:47 ` [patch 3/7] epoll: Use " Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 5/7] signalfd: " Cyrill Gorcunov
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0003-procfs-eventfd-2 --]
[-- Type: text/plain, Size: 1832 bytes --]

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/eventfd.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Index: linux-2.6.git/fs/eventfd.c
===================================================================
--- linux-2.6.git.orig/fs/eventfd.c
+++ linux-2.6.git/fs/eventfd.c
@@ -287,23 +287,28 @@ static ssize_t eventfd_write(struct file
 }
 
 #ifdef CONFIG_PROC_FS
-static int eventfd_show_fdinfo(struct seq_file *m, struct file *f)
+static int seq_show(struct seq_file *m, void *v)
 {
-	struct eventfd_ctx *ctx = f->private_data;
-	int ret;
+	struct eventfd_ctx *ctx = ((struct file *)m->private)->private_data;
 
 	spin_lock_irq(&ctx->wqh.lock);
-	ret = seq_printf(m, "eventfd-count: %16llx\n",
-			 (unsigned long long)ctx->count);
+	seq_printf(m, "eventfd-count: %16llx\n", (unsigned long long)ctx->count);
 	spin_unlock_irq(&ctx->wqh.lock);
 
-	return ret;
+	return 0;
 }
+
+static struct seq_operations eventfd_fdinfo_op = {
+	.start		= single_start,
+	.next		= single_next,
+	.stop		= single_stop,
+	.show		= seq_show,
+};
 #endif
 
 static const struct file_operations eventfd_fops = {
 #ifdef CONFIG_PROC_FS
-	.show_fdinfo	= eventfd_show_fdinfo,
+	.fdinfo_op	= &eventfd_fdinfo_op,
 #endif
 	.release	= eventfd_release,
 	.poll		= eventfd_poll,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 5/7] signalfd: Use sequential fdinfo engine
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
                   ` (3 preceding siblings ...)
  2013-11-06 11:47 ` [patch 4/7] eventfd: " Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 6/7] fsnotify: " Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 7/7] procfs: Drop legacy show_fdinfo file operation Cyrill Gorcunov
  6 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0004-procfs-signalfd-2 --]
[-- Type: text/plain, Size: 1690 bytes --]

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/signalfd.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Index: linux-2.6.git/fs/signalfd.c
===================================================================
--- linux-2.6.git.orig/fs/signalfd.c
+++ linux-2.6.git/fs/signalfd.c
@@ -230,9 +230,9 @@ static ssize_t signalfd_read(struct file
 }
 
 #ifdef CONFIG_PROC_FS
-static int signalfd_show_fdinfo(struct seq_file *m, struct file *f)
+static int seq_show(struct seq_file *m, void *v)
 {
-	struct signalfd_ctx *ctx = f->private_data;
+	struct signalfd_ctx *ctx = ((struct file *)m->private)->private_data;
 	sigset_t sigmask;
 
 	sigmask = ctx->sigmask;
@@ -241,11 +241,18 @@ static int signalfd_show_fdinfo(struct s
 
 	return 0;
 }
+
+static struct seq_operations signalfd_fdinfo_op = {
+	.start		= single_start,
+	.next		= single_next,
+	.stop		= single_stop,
+	.show		= seq_show,
+};
 #endif
 
 static const struct file_operations signalfd_fops = {
 #ifdef CONFIG_PROC_FS
-	.show_fdinfo	= signalfd_show_fdinfo,
+	.fdinfo_op	= &signalfd_fdinfo_op,
 #endif
 	.release	= signalfd_release,
 	.poll		= signalfd_poll,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 6/7] fsnotify: Use sequential fdinfo engine
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
                   ` (4 preceding siblings ...)
  2013-11-06 11:47 ` [patch 5/7] signalfd: " Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  2013-11-06 11:47 ` [patch 7/7] procfs: Drop legacy show_fdinfo file operation Cyrill Gorcunov
  6 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0005-procfs-notify-2 --]
[-- Type: text/plain, Size: 9815 bytes --]

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/notify/fanotify/fanotify_user.c |    4 
 fs/notify/fdinfo.c                 |  167 +++++++++++++++++++++++--------------
 fs/notify/fdinfo.h                 |   12 --
 fs/notify/inotify/inotify_user.c   |    4 
 4 files changed, 116 insertions(+), 71 deletions(-)

Index: linux-2.6.git/fs/notify/fanotify/fanotify_user.c
===================================================================
--- linux-2.6.git.orig/fs/notify/fanotify/fanotify_user.c
+++ linux-2.6.git/fs/notify/fanotify/fanotify_user.c
@@ -432,7 +432,9 @@ static long fanotify_ioctl(struct file *
 }
 
 static const struct file_operations fanotify_fops = {
-	.show_fdinfo	= fanotify_show_fdinfo,
+#ifdef CONFIG_PROC_FS
+	.fdinfo_op	= &fanotify_fdinfo_op,
+#endif
 	.poll		= fanotify_poll,
 	.read		= fanotify_read,
 	.write		= fanotify_write,
Index: linux-2.6.git/fs/notify/fdinfo.c
===================================================================
--- linux-2.6.git.orig/fs/notify/fdinfo.c
+++ linux-2.6.git/fs/notify/fdinfo.c
@@ -16,25 +16,50 @@
 #include "inotify/inotify.h"
 #include "../fs/mount.h"
 
+#define seq_notify_group(m) ((struct file*)(m)->private)->private_data
+
 #if defined(CONFIG_PROC_FS)
 
 #if defined(CONFIG_INOTIFY_USER) || defined(CONFIG_FANOTIFY)
 
-static int show_fdinfo(struct seq_file *m, struct file *f,
-		       int (*show)(struct seq_file *m, struct fsnotify_mark *mark))
+static void *notify_start(struct seq_file *m, loff_t *pos,
+			  void *(*__start)(struct seq_file *m, loff_t *pos,
+					   struct fsnotify_group *group,
+					   struct fsnotify_mark *mark))
 {
-	struct fsnotify_group *group = f->private_data;
+	struct fsnotify_group *group = seq_notify_group(m);
 	struct fsnotify_mark *mark;
-	int ret = 0;
+	loff_t num = *pos;
 
 	mutex_lock(&group->mark_mutex);
 	list_for_each_entry(mark, &group->marks_list, g_list) {
-		ret = show(m, mark);
-		if (ret)
-			break;
+		if (num-- == 0) {
+			if (__start)
+				return __start(m, pos, group, mark);
+			return mark;
+		}
 	}
+
+	return NULL;
+}
+
+static void notify_stop(struct seq_file *m, void *v)
+{
+	struct fsnotify_group *group = seq_notify_group(m);
 	mutex_unlock(&group->mark_mutex);
-	return ret;
+}
+
+static void *notify_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct fsnotify_group *group = seq_notify_group(m);
+	struct fsnotify_mark *mark = p;
+
+	if (!list_is_last(&mark->g_list, &group->marks_list))
+		mark = list_first_entry(&mark->g_list, struct fsnotify_mark, g_list);
+	else
+		mark = NULL;
+	++*pos;
+	return mark;
 }
 
 #if defined(CONFIG_EXPORTFS)
@@ -58,13 +83,13 @@ static int show_mark_fhandle(struct seq_
 	f.handle.handle_type = ret;
 	f.handle.handle_bytes = size * sizeof(u32);
 
-	ret = seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:",
-			 f.handle.handle_bytes, f.handle.handle_type);
+	seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:",
+		   f.handle.handle_bytes, f.handle.handle_type);
 
 	for (i = 0; i < f.handle.handle_bytes; i++)
-		ret |= seq_printf(m, "%02x", (int)f.handle.f_handle[i]);
+		seq_printf(m, "%02x", (int)f.handle.f_handle[i]);
 
-	return ret;
+	return 0;
 }
 #else
 static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
@@ -75,11 +100,16 @@ static int show_mark_fhandle(struct seq_
 
 #ifdef CONFIG_INOTIFY_USER
 
-static int inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
+static void *inotify_start(struct seq_file *m, loff_t *pos)
+{
+	return notify_start(m, pos, NULL);
+}
+
+static int inotify_show(struct seq_file *m, void *v)
 {
 	struct inotify_inode_mark *inode_mark;
+	struct fsnotify_mark *mark = v;
 	struct inode *inode;
-	int ret = 0;
 
 	if (!(mark->flags & (FSNOTIFY_MARK_FLAG_ALIVE | FSNOTIFY_MARK_FLAG_INODE)))
 		return 0;
@@ -87,33 +117,35 @@ static int inotify_fdinfo(struct seq_fil
 	inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
 	inode = igrab(mark->i.inode);
 	if (inode) {
-		ret = seq_printf(m, "inotify wd:%x ino:%lx sdev:%x "
-				 "mask:%x ignored_mask:%x ",
-				 inode_mark->wd, inode->i_ino,
-				 inode->i_sb->s_dev,
-				 mark->mask, mark->ignored_mask);
-		ret |= show_mark_fhandle(m, inode);
-		ret |= seq_putc(m, '\n');
+		seq_printf(m, "inotify wd:%x ino:%lx sdev:%x "
+			   "mask:%x ignored_mask:%x ",
+			   inode_mark->wd, inode->i_ino,
+			   inode->i_sb->s_dev,
+			   mark->mask, mark->ignored_mask);
+		show_mark_fhandle(m, inode);
+		seq_putc(m, '\n');
 		iput(inode);
 	}
 
-	return ret;
+	return 0;
 }
 
-int inotify_show_fdinfo(struct seq_file *m, struct file *f)
-{
-	return show_fdinfo(m, f, inotify_fdinfo);
-}
+struct seq_operations inotify_fdinfo_op = {
+	.start		= inotify_start,
+	.next		= notify_next,
+	.stop		= notify_stop,
+	.show		= inotify_show,
+};
 
 #endif /* CONFIG_INOTIFY_USER */
 
 #ifdef CONFIG_FANOTIFY
 
-static int fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
+static int fanotify_show(struct seq_file *m, void *v)
 {
+	struct fsnotify_mark *mark = v;
 	unsigned int mflags = 0;
 	struct inode *inode;
-	int ret = 0;
 
 	if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE))
 		return 0;
@@ -125,53 +157,68 @@ static int fanotify_fdinfo(struct seq_fi
 		inode = igrab(mark->i.inode);
 		if (!inode)
 			goto out;
-		ret = seq_printf(m, "fanotify ino:%lx sdev:%x "
-				 "mflags:%x mask:%x ignored_mask:%x ",
-				 inode->i_ino, inode->i_sb->s_dev,
-				 mflags, mark->mask, mark->ignored_mask);
-		ret |= show_mark_fhandle(m, inode);
-		ret |= seq_putc(m, '\n');
+		seq_printf(m, "fanotify ino:%lx sdev:%x "
+			   "mflags:%x mask:%x ignored_mask:%x ",
+			   inode->i_ino, inode->i_sb->s_dev,
+			   mflags, mark->mask, mark->ignored_mask);
+		show_mark_fhandle(m, inode);
+		seq_putc(m, '\n');
 		iput(inode);
 	} else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) {
 		struct mount *mnt = real_mount(mark->m.mnt);
 
-		ret = seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x "
-				 "ignored_mask:%x\n", mnt->mnt_id, mflags,
-				 mark->mask, mark->ignored_mask);
+		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x "
+			   "ignored_mask:%x\n", mnt->mnt_id, mflags,
+			   mark->mask, mark->ignored_mask);
 	}
 out:
-	return ret;
+	return 0;
 }
 
-int fanotify_show_fdinfo(struct seq_file *m, struct file *f)
-{
-	struct fsnotify_group *group = f->private_data;
-	unsigned int flags = 0;
+static void *__fanotify_start(struct seq_file *m, loff_t *pos,
+			      struct fsnotify_group *group,
+			      struct fsnotify_mark *mark)
+{
+	if (*pos == 0) {
+		unsigned int flags = 0;
+
+		switch (group->priority) {
+		case FS_PRIO_0:
+			flags |= FAN_CLASS_NOTIF;
+			break;
+		case FS_PRIO_1:
+			flags |= FAN_CLASS_CONTENT;
+			break;
+		case FS_PRIO_2:
+			flags |= FAN_CLASS_PRE_CONTENT;
+			break;
+		}
 
-	switch (group->priority) {
-	case FS_PRIO_0:
-		flags |= FAN_CLASS_NOTIF;
-		break;
-	case FS_PRIO_1:
-		flags |= FAN_CLASS_CONTENT;
-		break;
-	case FS_PRIO_2:
-		flags |= FAN_CLASS_PRE_CONTENT;
-		break;
-	}
+		if (group->max_events == UINT_MAX)
+			flags |= FAN_UNLIMITED_QUEUE;
 
-	if (group->max_events == UINT_MAX)
-		flags |= FAN_UNLIMITED_QUEUE;
+		if (group->fanotify_data.max_marks == UINT_MAX)
+			flags |= FAN_UNLIMITED_MARKS;
 
-	if (group->fanotify_data.max_marks == UINT_MAX)
-		flags |= FAN_UNLIMITED_MARKS;
+		seq_printf(m, "fanotify flags:%x event-flags:%x\n",
+			   flags, group->fanotify_data.f_flags);
+	}
 
-	seq_printf(m, "fanotify flags:%x event-flags:%x\n",
-		   flags, group->fanotify_data.f_flags);
+	return mark;
+}
 
-	return show_fdinfo(m, f, fanotify_fdinfo);
+static void *fanotify_start(struct seq_file *m, loff_t *pos)
+{
+	return notify_start(m, pos, __fanotify_start);
 }
 
+struct seq_operations fanotify_fdinfo_op = {
+	.start		= fanotify_start,
+	.next		= notify_next,
+	.stop		= notify_stop,
+	.show		= fanotify_show,
+};
+
 #endif /* CONFIG_FANOTIFY */
 
 #endif /* CONFIG_INOTIFY_USER || CONFIG_FANOTIFY */
Index: linux-2.6.git/fs/notify/fdinfo.h
===================================================================
--- linux-2.6.git.orig/fs/notify/fdinfo.h
+++ linux-2.6.git/fs/notify/fdinfo.h
@@ -4,24 +4,18 @@
 #include <linux/errno.h>
 #include <linux/proc_fs.h>
 
-struct seq_file;
-struct file;
+struct seq_operations;
 
 #ifdef CONFIG_PROC_FS
 
 #ifdef CONFIG_INOTIFY_USER
-extern int inotify_show_fdinfo(struct seq_file *m, struct file *f);
+extern struct seq_operations inotify_fdinfo_op;
 #endif
 
 #ifdef CONFIG_FANOTIFY
-extern int fanotify_show_fdinfo(struct seq_file *m, struct file *f);
+extern struct seq_operations fanotify_fdinfo_op;
 #endif
 
-#else /* CONFIG_PROC_FS */
-
-#define inotify_show_fdinfo	NULL
-#define fanotify_show_fdinfo	NULL
-
 #endif /* CONFIG_PROC_FS */
 
 #endif /* __FSNOTIFY_FDINFO_H__ */
Index: linux-2.6.git/fs/notify/inotify/inotify_user.c
===================================================================
--- linux-2.6.git.orig/fs/notify/inotify/inotify_user.c
+++ linux-2.6.git/fs/notify/inotify/inotify_user.c
@@ -327,7 +327,9 @@ static long inotify_ioctl(struct file *f
 }
 
 static const struct file_operations inotify_fops = {
-	.show_fdinfo	= inotify_show_fdinfo,
+#ifdef CONFIG_PROC_FS
+	.fdinfo_op	= &inotify_fdinfo_op,
+#endif
 	.poll		= inotify_poll,
 	.read		= inotify_read,
 	.fasync		= fsnotify_fasync,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 7/7] procfs: Drop legacy show_fdinfo file operation
  2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
                   ` (5 preceding siblings ...)
  2013-11-06 11:47 ` [patch 6/7] fsnotify: " Cyrill Gorcunov
@ 2013-11-06 11:47 ` Cyrill Gorcunov
  6 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Cyrill Gorcunov, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

[-- Attachment #1: 0006-procfs-ridof-2 --]
[-- Type: text/plain, Size: 1695 bytes --]

All former users of show_fdinfo are converted to sequential
output engine thus we don't need it anymore.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: James Bottomley <jbottomley@parallels.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Matthew Helsley <matt.helsley@gmail.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 fs/proc/fd.c       |    5 -----
 include/linux/fs.h |    1 -
 2 files changed, 6 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
@@ -59,11 +59,6 @@ static int seq_show(struct seq_file *m,
 
 	if (info->op)
 		return info->op->show(m, v);
-
-	/* Legacy interface */
-	if (info->f_file->f_op->show_fdinfo)
-		return info->f_file->f_op->show_fdinfo(m, info->f_file);
-
 	return 0;
 }
 
Index: linux-2.6.git/include/linux/fs.h
===================================================================
--- linux-2.6.git.orig/include/linux/fs.h
+++ linux-2.6.git/include/linux/fs.h
@@ -1551,7 +1551,6 @@ 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 seq_operations *fdinfo_op;
 };
 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch 1/7] seq-file: Export single_ helpers
  2013-11-06 11:47 ` [patch 1/7] seq-file: Export single_ helpers Cyrill Gorcunov
@ 2013-11-06 11:50   ` Christoph Hellwig
  2013-11-06 11:58     ` Cyrill Gorcunov
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2013-11-06 11:50 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: linux-kernel, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

On Wed, Nov 06, 2013 at 03:47:43PM +0400, Cyrill Gorcunov wrote:
> The single_ helpers will be used in fdinfo output to
> eliminate code duplication.

There is no need to export symbols just to use them in procfs or
eventfd, which are always built in.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch 1/7] seq-file: Export single_ helpers
  2013-11-06 11:50   ` Christoph Hellwig
@ 2013-11-06 11:58     ` Cyrill Gorcunov
  0 siblings, 0 replies; 10+ messages in thread
From: Cyrill Gorcunov @ 2013-11-06 11:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, Pavel Emelyanov, Oleg Nesterov, Andrey Vagin,
	Al Viro, Alexey Dobriyan, James Bottomley, Aneesh Kumar K.V,
	Matthew Helsley, J. Bruce Fields, Andrew Morton

On Wed, Nov 06, 2013 at 03:50:54AM -0800, Christoph Hellwig wrote:
> On Wed, Nov 06, 2013 at 03:47:43PM +0400, Cyrill Gorcunov wrote:
> > The single_ helpers will be used in fdinfo output to
> > eliminate code duplication.
> 
> There is no need to export symbols just to use them in procfs or
> eventfd, which are always built in.

I still need to declare them (they were static), so since single-open
already exported I thought I need to export the rest of single_ helper
as well.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-11-06 11:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-06 11:47 [patch 0/7] Rework file::show_fdinfo method to use seq-files engine, v2 Cyrill Gorcunov
2013-11-06 11:47 ` [patch 1/7] seq-file: Export single_ helpers Cyrill Gorcunov
2013-11-06 11:50   ` Christoph Hellwig
2013-11-06 11:58     ` Cyrill Gorcunov
2013-11-06 11:47 ` [patch 2/7] procfs: Introduce sequential fdinfo engine Cyrill Gorcunov
2013-11-06 11:47 ` [patch 3/7] epoll: Use " Cyrill Gorcunov
2013-11-06 11:47 ` [patch 4/7] eventfd: " Cyrill Gorcunov
2013-11-06 11:47 ` [patch 5/7] signalfd: " Cyrill Gorcunov
2013-11-06 11:47 ` [patch 6/7] fsnotify: " Cyrill Gorcunov
2013-11-06 11:47 ` [patch 7/7] procfs: Drop legacy show_fdinfo file operation Cyrill Gorcunov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).