netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephen Hemminger <shemminger@osdl.org>
To: Jeroen Vreeken <pe1rxq@amsat.org>
Cc: "David S . Miller" <davem@redhat.com>,
	linux-hams@vger.kernel.org, ralf@linux-mips.org,
	netdev@oss.sgi.com
Subject: [RFT][PATCH] ax25 using seq_file
Date: Fri, 22 Aug 2003 13:15:47 -0700	[thread overview]
Message-ID: <20030822131547.0d95fb16.shemminger@osdl.org> (raw)
In-Reply-To: <20030820204518.C5568@jeroen.pe1rxq.ampr.org>

Convert AX25 to use the seq_file interface for it's /proc hook.

Jeroen could you test this with real hardware, since without hardware
the table always comes up empty which is not a good enough test.

diff -Nru a/include/net/ax25.h b/include/net/ax25.h
--- a/include/net/ax25.h	Fri Aug 22 08:21:10 2003
+++ b/include/net/ax25.h	Fri Aug 22 08:21:10 2003
@@ -314,7 +314,7 @@
 /* ax25_route.c */
 extern void ax25_rt_device_down(struct net_device *);
 extern int  ax25_rt_ioctl(unsigned int, void *);
-extern int  ax25_rt_get_info(char *, char **, off_t, int);
+extern struct file_operations ax25_route_fops;
 extern int  ax25_rt_autobind(ax25_cb *, ax25_address *);
 extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *,
 	struct net_device *);
@@ -373,7 +373,7 @@
 extern int  ax25_uid_policy;
 extern ax25_address *ax25_findbyuid(uid_t);
 extern int  ax25_uid_ioctl(int, struct sockaddr_ax25 *);
-extern int  ax25_uid_get_info(char *, char **, off_t, int);
+extern struct file_operations ax25_uid_fops;
 extern void ax25_uid_free(void);
 
 /* sysctl_net_ax25.c */
diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
--- a/net/ax25/af_ax25.c	Fri Aug 22 08:21:10 2003
+++ b/net/ax25/af_ax25.c	Fri Aug 22 08:21:10 2003
@@ -1842,81 +1842,107 @@
 	return res;
 }
 
-static int ax25_get_info(char *buffer, char **start, off_t offset, int length)
+#ifdef CONFIG_PROC_FS
+
+static void *ax25_info_start(struct seq_file *seq, loff_t *pos)
 {
-	ax25_cb *ax25;
-	int k;
-	int len = 0;
-	off_t pos = 0;
-	off_t begin = 0;
+	struct ax25_cb *ax25;
 	struct hlist_node *node;
+	int i = 0;
 
 	spin_lock_bh(&ax25_list_lock);
+	ax25_for_each(ax25, node, &ax25_list) {
+		if (i == *pos)
+			return ax25;
+		++i;
+	}
+	return NULL;
+}
+
+static void *ax25_info_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	++*pos;
+
+	return hlist_entry( ((struct ax25_cb *)v)->ax25_node.next,
+			    struct ax25_cb, ax25_node);
+}
+	
+static void ax25_info_stop(struct seq_file *seq, void *v)
+{
+	spin_unlock_bh(&ax25_list_lock);
+}
+
+static int ax25_info_show(struct seq_file *seq, void *v)
+{
+	ax25_cb *ax25 = v;
+	int k;
+
 
 	/*
 	 * New format:
 	 * magic dev src_addr dest_addr,digi1,digi2,.. st vs vr va t1 t1 t2 t2 t3 t3 idle idle n2 n2 rtt window paclen Snd-Q Rcv-Q inode
 	 */
 
-	ax25_for_each(ax25, node, &ax25_list) {
-		len += sprintf(buffer+len, "%8.8lx %s %s%s ",
-				(long) ax25,
-				ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
-				ax2asc(&ax25->source_addr),
-				ax25->iamdigi? "*":"");
-
-		len += sprintf(buffer+len, "%s", ax2asc(&ax25->dest_addr));
-
-		for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
-			len += sprintf(buffer+len, ",%s%s",
-					ax2asc(&ax25->digipeat->calls[k]),
-					ax25->digipeat->repeated[k]? "*":"");
-		}
-
-		len += sprintf(buffer+len, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d",
-			ax25->state,
-			ax25->vs, ax25->vr, ax25->va,
-			ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ,
-			ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ,
-			ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ,
-			ax25_display_timer(&ax25->idletimer) / (60 * HZ),
-			ax25->idle / (60 * HZ),
-			ax25->n2count, ax25->n2,
-			ax25->rtt / HZ,
-			ax25->window,
-			ax25->paclen);
-
-		if (ax25->sk != NULL) {
-			bh_lock_sock(ax25->sk);
-			len += sprintf(buffer + len, " %d %d %ld\n",
-				atomic_read(&ax25->sk->sk_wmem_alloc),
-				atomic_read(&ax25->sk->sk_rmem_alloc),
-				ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L);
-			bh_unlock_sock(ax25->sk);
-		} else {
-			len += sprintf(buffer + len, " * * *\n");
-		}
-
-		pos = begin + len;
-
-		if (pos < offset) {
-			len   = 0;
-			begin = pos;
-		}
+	seq_printf(seq, "%8.8lx %s %s%s ",
+		   (long) ax25,
+		   ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
+		   ax2asc(&ax25->source_addr),
+		   ax25->iamdigi? "*":"");
+	seq_printf(seq, "%s", ax2asc(&ax25->dest_addr));
+
+	for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
+		seq_printf(seq, ",%s%s",
+			   ax2asc(&ax25->digipeat->calls[k]),
+			   ax25->digipeat->repeated[k]? "*":"");
+	}
 
-		if (pos > offset + length)
-			break;
+	seq_printf(seq, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d",
+		   ax25->state,
+		   ax25->vs, ax25->vr, ax25->va,
+		   ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ,
+		   ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ,
+		   ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ,
+		   ax25_display_timer(&ax25->idletimer) / (60 * HZ),
+		   ax25->idle / (60 * HZ),
+		   ax25->n2count, ax25->n2,
+		   ax25->rtt / HZ,
+		   ax25->window,
+		   ax25->paclen);
+
+	if (ax25->sk != NULL) {
+		bh_lock_sock(ax25->sk);
+		seq_printf(seq," %d %d %ld\n",
+			   atomic_read(&ax25->sk->sk_wmem_alloc),
+			   atomic_read(&ax25->sk->sk_rmem_alloc),
+			   ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L);
+		bh_unlock_sock(ax25->sk);
+	} else {
+		seq_puts(seq, " * * *\n");
 	}
+	return 0;
+}
 
-	spin_unlock_bh(&ax25_list_lock);
+static struct seq_operations ax25_info_seqops = {
+	.start = ax25_info_start,
+	.next = ax25_info_next,
+	.stop = ax25_info_stop,
+	.show = ax25_info_show,
+};
 
-	*start = buffer + (offset - begin);
-	len   -= (offset - begin);
+static int ax25_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &ax25_info_seqops);
+}
 
-	if (len > length) len = length;
+static struct file_operations ax25_info_fops = {
+	.owner = THIS_MODULE,
+	.open = ax25_info_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
 
-	return(len);
-}
+#endif
 
 static struct net_proto_family ax25_family_ops = {
 	.family =	PF_AX25,
@@ -1986,9 +2012,9 @@
 	register_netdevice_notifier(&ax25_dev_notifier);
 	ax25_register_sysctl();
 
-	proc_net_create("ax25_route", 0, ax25_rt_get_info);
-	proc_net_create("ax25", 0, ax25_get_info);
-	proc_net_create("ax25_calls", 0, ax25_uid_get_info);
+	proc_net_fops_create("ax25_route", S_IRUGO, &ax25_route_fops);
+	proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops);
+	proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops);
 
 	printk(banner);
 	return 0;
diff -Nru a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
--- a/net/ax25/ax25_route.c	Fri Aug 22 08:21:10 2003
+++ b/net/ax25/ax25_route.c	Fri Aug 22 08:21:10 2003
@@ -34,6 +34,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/seq_file.h>
 
 static ax25_route *ax25_route_list;
 static rwlock_t ax25_route_lock = RW_LOCK_UNLOCKED;
@@ -278,66 +279,100 @@
 	}
 }
 
-int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length)
-{
-	ax25_route *ax25_rt;
-	int len     = 0;
-	off_t pos   = 0;
-	off_t begin = 0;
-	char *callsign;
-	int i;
+#ifdef CONFIG_PROC_FS
 
-	read_lock(&ax25_route_lock);
+#define AX25_PROC_START	((void *)1)
 
-	len += sprintf(buffer, "callsign  dev  mode digipeaters\n");
+static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	struct ax25_route *ax25_rt;
+	int i = 1;
+ 
+ 	read_lock(&ax25_route_lock);
+	if (*pos == 0)
+		return AX25_PROC_START;
 
 	for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
+		if (i == *pos)
+			return ax25_rt;
+		++i;
+	}
+
+	return NULL;
+}
+
+static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	++*pos;
+	return (v == AX25_PROC_START) ? ax25_route_list : 
+		((struct ax25_route *) v)->next;
+}
+
+static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
+{
+	read_unlock(&ax25_route_lock);
+}
+
+static int ax25_rt_seq_show(struct seq_file *seq, void *v)
+{
+	if (v == AX25_PROC_START)
+		seq_puts(seq, "callsign  dev  mode digipeaters\n");
+	else {
+		struct ax25_route *ax25_rt = v;
+		const char *callsign;
+		int i;
+
 		if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
 			callsign = "default";
 		else
 			callsign = ax2asc(&ax25_rt->callsign);
-		len += sprintf(buffer + len, "%-9s %-4s",
+
+		seq_printf(seq, "%-9s %-4s",
 			callsign,
 			ax25_rt->dev ? ax25_rt->dev->name : "???");
 
 		switch (ax25_rt->ip_mode) {
 		case 'V':
-			len += sprintf(buffer + len, "   vc");
+			seq_puts(seq, "   vc");
 			break;
 		case 'D':
-			len += sprintf(buffer + len, "   dg");
+			seq_puts(seq, "   dg");
 			break;
 		default:
-			len += sprintf(buffer + len, "    *");
+			seq_puts(seq, "    *");
 			break;
 		}
 
 		if (ax25_rt->digipeat != NULL)
 			for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
-				len += sprintf(buffer + len, " %s", ax2asc(&ax25_rt->digipeat->calls[i]));
-
-		len += sprintf(buffer + len, "\n");
+				seq_printf(seq, " %s", ax2asc(&ax25_rt->digipeat->calls[i]));
 
-		pos = begin + len;
-
-		if (pos < offset) {
-			len   = 0;
-			begin = pos;
-		}
-
-		if (pos > offset + length)
-			break;
+		seq_puts(seq, "\n");
 	}
-	read_unlock(&ax25_route_lock);
-
-	*start = buffer + (offset - begin);
-	len   -= (offset - begin);
+	return 0;
+}
 
-	if (len > length)
-		len = length;
+static struct seq_operations ax25_rt_seqops = {
+	.start = ax25_rt_seq_start,
+	.next = ax25_rt_seq_next,
+	.stop = ax25_rt_seq_stop,
+	.show = ax25_rt_seq_show,
+};
 
-	return len;
+static int ax25_rt_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &ax25_rt_seqops);
 }
+
+struct file_operations ax25_route_fops = {
+	.owner = THIS_MODULE,
+	.open = ax25_rt_info_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+#endif
 
 /*
  *	Find AX.25 route
diff -Nru a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
--- a/net/ax25/ax25_uid.c	Fri Aug 22 08:21:10 2003
+++ b/net/ax25/ax25_uid.c	Fri Aug 22 08:21:10 2003
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/stat.h>
 #include <linux/netfilter.h>
 #include <linux/sysctl.h>
@@ -141,39 +142,73 @@
 	return -EINVAL;	/*NOTREACHED */
 }
 
-int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length)
+#ifdef CONFIG_PROC_FS
+
+#define AX25_PROC_START	((void *)1)
+
+static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	ax25_uid_assoc *pt;
-	int len     = 0;
-	off_t pos   = 0;
-	off_t begin = 0;
+	struct ax25_uid_assoc *pt;
+	int i = 1;
 
 	read_lock(&ax25_uid_lock);
-	len += sprintf(buffer, "Policy: %d\n", ax25_uid_policy);
+	if (*pos == 0)
+		return AX25_PROC_START;
 
 	for (pt = ax25_uid_list; pt != NULL; pt = pt->next) {
-		len += sprintf(buffer + len, "%6d %s\n", pt->uid, ax2asc(&pt->call));
-
-		pos = begin + len;
+		if (i == *pos)
+			return pt;
+		++i;
+	}
+	return NULL;
+}
 
-		if (pos < offset) {
-			len = 0;
-			begin = pos;
-		}
+static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	++*pos;
+	return (v == AX25_PROC_START) ? ax25_uid_list : 
+		((struct ax25_uid_assoc *) v)->next;
+}
 
-		if (pos > offset + length)
-			break;
-	}
+static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
+{
 	read_unlock(&ax25_uid_lock);
+}
+
+static int ax25_uid_seq_show(struct seq_file *seq, void *v)
+{
+	if (v == AX25_PROC_START)
+		seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
+	else {
+		struct ax25_uid_assoc *pt = v;
+		
 
-	*start = buffer + (offset - begin);
-	len   -= offset - begin;
+		seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call));
+	}
+	return 0;
+}
 
-	if (len > length)
-		len = length;
+static struct seq_operations ax25_uid_seqops = {
+	.start = ax25_uid_seq_start,
+	.next = ax25_uid_seq_next,
+	.stop = ax25_uid_seq_stop,
+	.show = ax25_uid_seq_show,
+};
 
-	return len;
+static int ax25_uid_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &ax25_uid_seqops);
 }
+
+struct file_operations ax25_uid_fops = {
+	.owner = THIS_MODULE,
+	.open = ax25_uid_info_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+#endif
 
 /*
  *	Free all memory associated with UID/Callsign structures.

  parent reply	other threads:[~2003-08-22 20:15 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-12 17:46 [PATCH] ax25 & netrom fixes for 2.6 Jeroen Vreeken
2003-08-12 19:48 ` Stephen Hemminger
2003-08-12 20:59   ` Jeroen Vreeken
2003-08-12 20:56 ` Stephen Hemminger
2003-08-12 21:09   ` Jeroen Vreeken
2003-08-12 22:39     ` [PATCH] ax25 fix for premature free Stephen Hemminger
2003-08-12 23:03       ` Jeroen Vreeken
2003-08-12 23:49         ` [PATCH] ax25 use dev_hold/dev_put as required for net_devices Stephen Hemminger
2003-08-13  0:19         ` [PATCH] ax25 setsockopt(SO_BINDTODEVICE) bug fix Stephen Hemminger
2003-08-13  0:21         ` [PATCH] Convert ax25 to seq_file Stephen Hemminger
2003-08-13 10:11           ` David S. Miller
2003-08-13 15:34             ` Jeroen Vreeken
2003-08-13 15:42               ` David S. Miller
2003-08-13 22:35                 ` [PATCH] (0/11) Netrom patches Stephen Hemminger
2003-08-15  4:13                   ` David S. Miller
2003-08-20 18:45                 ` [PATCH] ax25 changes Jeroen Vreeken
2003-08-21 19:18                   ` David S. Miller
2003-08-22 20:13                   ` [PATCH] ax25 - make sure and hold ref to dev Stephen Hemminger
2003-08-24 11:28                     ` David S. Miller
2003-08-22 20:15                   ` Stephen Hemminger [this message]
2003-08-24 11:29                     ` [RFT][PATCH] ax25 using seq_file David S. Miller
2003-08-24 22:35                       ` Jeroen Vreeken
2003-08-13 10:10     ` [PATCH] ax25 & netrom fixes for 2.6 David S. Miller

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=20030822131547.0d95fb16.shemminger@osdl.org \
    --to=shemminger@osdl.org \
    --cc=davem@redhat.com \
    --cc=linux-hams@vger.kernel.org \
    --cc=netdev@oss.sgi.com \
    --cc=pe1rxq@amsat.org \
    --cc=ralf@linux-mips.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;
as well as URLs for NNTP newsgroup(s).