mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: viro@parcelfarce.linux.theplanet.co.uk
To: Linus Torvalds <torvalds@osdl.org>
Cc: Marcelo Tosatti <marcelo@conectiva.com.br>,
	lkml <linux-kernel@vger.kernel.org>,
	olof@austin.ibm.com
Subject: Re: [PATCH] [2.4] Re: /proc/ioports overrun patch
Date: Wed, 24 Sep 2003 22:47:14 +0100	[thread overview]
Message-ID: <20030924214713.GA7665@parcelfarce.linux.theplanet.co.uk> (raw)
In-Reply-To: <20030924195926.GZ7665@parcelfarce.linux.theplanet.co.uk>

> Hey - it's already there.  That makes life very easy - ->next() should
> do the following:
> 	if (resource->child)
> 		return resource->child;
> 	while (!resource->sibling) {
> 		resource = resource->parent;
> 		if (!resource)
> 			return NULL;
> 	}
> 	return resource->sibling;
> 
> AFAICS that should be it - walks the tree in right order.  Depth can be
> trivially found by ->show(), so there's no problems either...

OK, here's the 2.6 variant; it should also apply on top of 2.4 backport,
AFAICS.  Works here...

It replaces iterator of /proc/io{ports,mem} with normal tree traversal and
cleans the thing up a bit.

diff -urN B5-09241809/kernel/resource.c B5-current/kernel/resource.c
--- B5-09241809/kernel/resource.c	Sat Aug  9 02:21:03 2003
+++ B5-current/kernel/resource.c	Wed Sep 24 17:28:22 2003
@@ -38,75 +38,91 @@
 
 #ifdef CONFIG_PROC_FS
 
-#define MAX_IORES_LEVEL		5
+enum { MAX_IORES_LEVEL = 5 };
 
-/*
- * do_resource_list():
- * for reports of /proc/ioports and /proc/iomem;
- * do current entry, then children, then siblings;
- */
-static int do_resource_list(struct seq_file *m, struct resource *res, const char *fmt, int level)
-{
-	while (res) {
-		const char *name;
-
-		name = res->name ? res->name : "<BAD>";
-		if (level > MAX_IORES_LEVEL)
-			level = MAX_IORES_LEVEL;
-		seq_printf (m, fmt + 2 * MAX_IORES_LEVEL - 2 * level,
-				res->start, res->end, name);
-
-		if (res->child)
-			do_resource_list(m, res->child, fmt, level + 1);
-
-		res = res->sibling;
-	}
-
-	return 0;
+static void *r_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct resource *p = v;
+	(*pos)++;
+	if (p->child)
+		return p->child;
+	while (!p->sibling && p->parent)
+		p = p->parent;
+	return p->sibling;
 }
 
-static int ioresources_show(struct seq_file *m, void *v)
+static void *r_start(struct seq_file *m, loff_t *pos)
 {
-	struct resource *root = m->private;
-	char *fmt;
-	int retval;
-
-	fmt = root->end < 0x10000
-		? "          %04lx-%04lx : %s\n"
-		: "          %08lx-%08lx : %s\n";
+	struct resource *p = m->private;
+	loff_t l = 0;
 	read_lock(&resource_lock);
-	retval = do_resource_list(m, root->child, fmt, 0);
+	for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
+		;
+	return p;
+}
+
+static void r_stop(struct seq_file *m, void *v)
+{
 	read_unlock(&resource_lock);
-	return retval;
 }
 
-static int ioresources_open(struct file *file, struct resource *root)
+static int r_show(struct seq_file *m, void *v)
 {
-	return single_open(file, ioresources_show, root);
+	struct resource *root = m->private;
+	struct resource *r = v, *p;
+	int width = root->end < 0x10000 ? 4 : 8;
+	int depth;
+
+	for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
+		if (p->parent == root)
+			break;
+	seq_printf(m, "%*s%0*lx-%0*lx : %s\n",
+			depth * 2, "",
+			width, r->start,
+			width, r->end,
+			r->name ? r->name : "<BAD>");
+	return 0;
 }
 
+struct seq_operations resource_op = {
+	.start	= r_start,
+	.next	= r_next,
+	.stop	= r_stop,
+	.show	= r_show,
+};
+
 static int ioports_open(struct inode *inode, struct file *file)
 {
-	return ioresources_open(file, &ioport_resource);
+	int res = seq_open(file, &resource_op);
+	if (!res) {
+		struct seq_file *m = file->private_data;
+		m->private = &ioport_resource;
+	}
+	return res;
+}
+
+static int iomem_open(struct inode *inode, struct file *file)
+{
+	int res = seq_open(file, &resource_op);
+	if (!res) {
+		struct seq_file *m = file->private_data;
+		m->private = &iomem_resource;
+	}
+	return res;
 }
 
 static struct file_operations proc_ioports_operations = {
 	.open		= ioports_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= single_release,
+	.release	= seq_release,
 };
 
-static int iomem_open(struct inode *inode, struct file *file)
-{
-	return ioresources_open(file, &iomem_resource);
-}
-
 static struct file_operations proc_iomem_operations = {
 	.open		= iomem_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= single_release,
+	.release	= seq_release,
 };
 
 static int __init ioresources_init(void)

  reply	other threads:[~2003-09-24 21:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-29 13:30 Marcelo Tosatti
2003-08-29 18:59 ` john stultz
2003-09-24 19:42 ` [PATCH] [2.4] " olof
2003-09-24 19:51   ` viro
2003-09-24 19:59     ` viro
2003-09-24 21:47       ` viro [this message]
2003-09-24 22:36         ` viro
2003-09-24 22:54           ` Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030924214713.GA7665@parcelfarce.linux.theplanet.co.uk \
    --to=viro@parcelfarce.linux.theplanet.co.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo@conectiva.com.br \
    --cc=olof@austin.ibm.com \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®