linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Francois Romieu <romieu@fr.zoreil.com>
To: chas@locutus.cmf.nrl.navy.mil
Cc: linux-kernel@vger.kernel.org, davem@redhat.com
Subject: [PATCH 6/8] 2.5.74 - seq_file conversion of /proc/net/atm (arp)
Date: Wed, 9 Jul 2003 02:30:51 +0200	[thread overview]
Message-ID: <20030709023051.H11897@electric-eye.fr.zoreil.com> (raw)
In-Reply-To: <20030709021152.B11897@electric-eye.fr.zoreil.com>; from romieu@fr.zoreil.com on Wed, Jul 09, 2003 at 02:11:52AM +0200

seq_file support for /proc/net/atm/arp:
- svc_addr/atmarp_info(): seq_printf/seq_putc replace sprintf and friends;
- atm_arp_getidx/atm_arp_vc_walk() take care of the usual seq_file cursor
  positionning: they both return NULL until the cursor has reached its
  position. struct atm_arp_state is updated accordingly;
- atm_arp_seq_{stop/start} are responsible for clip_tbl_hook (un)locking;
- module refcounting is done in atm_arp_seq_open()/atm_arp_seq_release();
- atm_lec_info() is removed.


 net/atm/proc.c |  269 +++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 185 insertions(+), 84 deletions(-)

diff -puN net/atm/proc.c~atm-proc-seq-arp-conversion net/atm/proc.c
--- linux-2.5.74-1.1360.1.1-to-1.1384/net/atm/proc.c~atm-proc-seq-arp-conversion	Wed Jul  9 01:43:02 2003
+++ linux-2.5.74-1.1360.1.1-to-1.1384-fr/net/atm/proc.c	Wed Jul  9 01:43:02 2003
@@ -91,75 +91,67 @@ static void atm_dev_info(struct seq_file
 
 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 
-
-static int svc_addr(char *buf,struct sockaddr_atmsvc *addr)
+static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
 {
 	static int code[] = { 1,2,10,6,1,0 };
 	static int e164[] = { 1,8,4,6,1,0 };
-	int *fields;
-	int len,i,j,pos;
 
-	len = 0;
 	if (*addr->sas_addr.pub) {
-		strcpy(buf,addr->sas_addr.pub);
-		len = strlen(addr->sas_addr.pub);
-		buf += len;
-		if (*addr->sas_addr.prv) {
-			*buf++ = '+';
-			len++;
-		}
+		seq_printf(seq, "%s", addr->sas_addr.pub);
+		if (*addr->sas_addr.prv)
+			seq_putc(seq, '+');
+	} else if (!*addr->sas_addr.prv) {
+		seq_printf(seq, "%s", "(none)");
+		return;
 	}
-	else if (!*addr->sas_addr.prv) {
-			strcpy(buf,"(none)");
-			return strlen(buf);
-		}
 	if (*addr->sas_addr.prv) {
-		len += 44;
-		pos = 0;
-		fields = *addr->sas_addr.prv == ATM_AFI_E164 ? e164 : code;
+		unsigned char *prv = addr->sas_addr.prv;
+		int *fields;
+		int i, j;
+
+		fields = *prv == ATM_AFI_E164 ? e164 : code;
 		for (i = 0; fields[i]; i++) {
-			for (j = fields[i]; j; j--) {
-				sprintf(buf,"%02X",addr->sas_addr.prv[pos++]);
-				buf += 2;
-			}
-			if (fields[i+1]) *buf++ = '.';
+			for (j = fields[i]; j; j--)
+				seq_printf(seq, "%02X", *prv++);
+			if (fields[i+1])
+				seq_putc(seq, '.');
 		}
 	}
-	return len;
 }
 
-
-static void atmarp_info(struct net_device *dev,struct atmarp_entry *entry,
-    struct clip_vcc *clip_vcc,char *buf)
+static void atmarp_info(struct seq_file *seq, struct net_device *dev,
+			struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
 {
-	unsigned char *ip;
-	int svc,off,ip_len;
+	char buf[17];
+	int svc, off;
 
 	svc = !clip_vcc || clip_vcc->vcc->sk->sk_family == AF_ATMSVC;
-	off = sprintf(buf,"%-6s%-4s%-4s%5ld ",dev->name,svc ? "SVC" : "PVC",
+	seq_printf(seq, "%-6s%-4s%-4s%5ld ", dev->name, svc ? "SVC" : "PVC",
 	    !clip_vcc || clip_vcc->encap ? "LLC" : "NULL",
-	    (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/
-	    HZ);
-	ip = (unsigned char *) &entry->ip;
-	ip_len = sprintf(buf+off,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);
-	off += ip_len;
-	while (ip_len++ < 16) buf[off++] = ' ';
-	if (!clip_vcc)
+	    (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/HZ);
+
+	off = snprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d", NIPQUAD(entry->ip));
+	while (off < 16)
+		buf[off++] = ' ';
+	buf[off] = '\0';
+	seq_printf(seq, "%s", buf);
+
+	if (!clip_vcc) {
 		if (time_before(jiffies, entry->expires))
-			strcpy(buf+off,"(resolving)\n");
-		else sprintf(buf+off,"(expired, ref %d)\n",
-			    atomic_read(&entry->neigh->refcnt));
-	else if (!svc)
-			sprintf(buf+off,"%d.%d.%d\n",clip_vcc->vcc->dev->number,
-			    clip_vcc->vcc->vpi,clip_vcc->vcc->vci);
-		else {
-			off += svc_addr(buf+off,&clip_vcc->vcc->remote);
-			strcpy(buf+off,"\n");
-		}
+			seq_printf(seq, "(resolving)\n");
+		else
+			seq_printf(seq, "(expired, ref %d)\n",
+				   atomic_read(&entry->neigh->refcnt));
+	} else if (!svc) {
+		seq_printf(seq, "%d.%d.%d\n", clip_vcc->vcc->dev->number,
+			   clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
+	} else {
+		svc_addr(seq, &clip_vcc->vcc->remote);
+		seq_putc(seq, '\n');
+	}
 }
 
-
-#endif
+#endif /* CONFIG_ATM_CLIP */
 
 struct atm_vc_state {
 	struct sock *sk;
@@ -564,45 +556,154 @@ static struct file_operations atm_seq_sv
 };
 
 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
-static int atm_arp_info(loff_t pos,char *buf)
+
+struct atm_arp_state {
+	int bucket;
+  	struct neighbour *n;
+	struct clip_vcc *vcc;
+};
+  
+static void *atm_arp_vc_walk(struct atm_arp_state *state,
+			     struct atmarp_entry *e, loff_t *l)
+{
+	struct clip_vcc *vcc = state->vcc;
+
+	if (!vcc)
+		vcc = e->vccs;
+	if (vcc == (void *)1) {
+		vcc = e->vccs;
+		--*l;
+  	}
+	for (; vcc; vcc = vcc->next) {
+		if (--*l < 0)
+			break;
+	}
+	state->vcc = vcc;
+	return (*l < 0) ? state : NULL;
+}
+  
+static void *atm_arp_get_idx(struct atm_arp_state *state, loff_t l)
 {
-	struct neighbour *n;
-	int i,count;
+	void *v = NULL;
 
-	if (!pos) {
-		return sprintf(buf,"IPitf TypeEncp Idle IP address      "
-		    "ATM address\n");
+	for (; state->bucket <= NEIGH_HASHMASK; state->bucket++) {
+		for (; state->n; state->n = state->n->next) {
+			v = atm_arp_vc_walk(state, NEIGH2ENTRY(state->n), &l);
+			if (v)
+				goto done;
+  		}
+		state->n = clip_tbl_hook->hash_buckets[state->bucket + 1];
 	}
-	if (!try_atm_clip_ops())
-		return 0;
-	count = pos;
+done:
+	return v;
+}
+
+static void *atm_arp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	struct atm_arp_state *state = seq->private;
+	void *ret = (void *)1;
+
+	if (!clip_tbl_hook) {
+		state->bucket = -1;
+		goto out;
+	}
+
 	read_lock_bh(&clip_tbl_hook->lock);
-	for (i = 0; i <= NEIGH_HASHMASK; i++)
-		for (n = clip_tbl_hook->hash_buckets[i]; n; n = n->next) {
-			struct atmarp_entry *entry = NEIGH2ENTRY(n);
-			struct clip_vcc *vcc;
-
-			if (!entry->vccs) {
-				if (--count) continue;
-				atmarp_info(n->dev,entry,NULL,buf);
-				read_unlock_bh(&clip_tbl_hook->lock);
-				module_put(atm_clip_ops->owner);
-				return strlen(buf);
-			}
-			for (vcc = entry->vccs; vcc;
-			    vcc = vcc->next) {
-				if (--count) continue;
-				atmarp_info(n->dev,entry,vcc,buf);
-				read_unlock_bh(&clip_tbl_hook->lock);
-				module_put(atm_clip_ops->owner);
-				return strlen(buf);
-			}
-		}
-	read_unlock_bh(&clip_tbl_hook->lock);
+	state->bucket = 0;
+	state->n = clip_tbl_hook->hash_buckets[0];
+	state->vcc = (void *)1;
+	if (*pos)
+		ret = atm_arp_get_idx(state, *pos);
+out:
+	return ret;
+}
+
+static void atm_arp_seq_stop(struct seq_file *seq, void *v)
+{
+	struct atm_arp_state *state = seq->private;
+
+	if (state->bucket != -1)
+		read_unlock_bh(&clip_tbl_hook->lock);
+}
+
+static void *atm_arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct atm_arp_state *state = seq->private;
+
+	v = atm_arp_get_idx(state, 1);
+	*pos += !!PTR_ERR(v);
+	return v;
+}
+
+static int atm_arp_seq_show(struct seq_file *seq, void *v)
+{
+	static char atm_arp_banner[] = 
+		"IPitf TypeEncp Idle IP address      ATM address\n";
+
+	if (v == (void *)1)
+		seq_puts(seq, atm_arp_banner);
+	else {
+		struct atm_arp_state *state = seq->private;
+		struct neighbour *n = state->n;	
+		struct clip_vcc *vcc = state->vcc;
+
+		atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
+	}
+  	return 0;
+}
+
+static struct seq_operations atm_arp_seq_ops = {
+	.start	= atm_arp_seq_start,
+	.next	= atm_arp_seq_next,
+	.stop	= atm_arp_seq_stop,
+	.show	= atm_arp_seq_show,
+};
+
+static int atm_arp_seq_open(struct inode *inode, struct file *file)
+{
+	struct atm_arp_state *state;
+	struct seq_file *seq;
+	int rc = -EAGAIN;
+
+	if (!try_atm_clip_ops())
+		goto out;
+
+	state = kmalloc(sizeof(*state), GFP_KERNEL);
+	if (!state) {
+		rc = -ENOMEM;
+		goto out_put;
+	}
+
+	rc = seq_open(file, &atm_arp_seq_ops);
+	if (rc)
+		goto out_kfree;
+
+	seq = file->private_data;
+	seq->private = state;
+out:
+	return rc;
+
+out_put:
 	module_put(atm_clip_ops->owner);
-	return 0;
+out_kfree:
+	kfree(state);
+	goto out;
 }
-#endif
+
+static int atm_arp_seq_release(struct inode *inode, struct file *file)
+{
+	module_put(atm_clip_ops->owner);
+	return seq_release_private(inode, file);
+}
+
+static struct file_operations atm_seq_arp_fops = {
+	.open		= atm_arp_seq_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= atm_arp_seq_release,
+};
+
+#endif /* CONFIG_ATM_CLIP */
 
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
 static int atm_lec_info(loff_t pos,char *buf)
@@ -811,7 +912,7 @@ int __init atm_proc_init(void)
 	CREATE_SEQ_ENTRY(svc);
 	CREATE_SEQ_ENTRY(vc);
 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
-	CREATE_ENTRY(arp);
+	CREATE_SEQ_ENTRY(arp);
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
 	CREATE_ENTRY(lec);

_

  parent reply	other threads:[~2003-07-09  0:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-09  0:11 [PATCHKIT] 2.5.74 - seq_file conversion of /proc/net/atm Francois Romieu
2003-07-09  0:23 ` [PATCH 1/8] 2.5.74 - seq_file conversion of /proc/net/atm (devices) Francois Romieu
2003-07-09  0:26 ` [PATCH 2/8] 2.5.74 - seq_file conversion of /proc/net/atm (vc helpers) Francois Romieu
2003-07-09  0:27 ` [PATCH 3/8] 2.5.74 - seq_file conversion of /proc/net/atm (pvc) Francois Romieu
2003-07-09  0:28 ` [PATCH 4/8] 2.5.74 - seq_file conversion of /proc/net/atm (svc) Francois Romieu
2003-07-09  0:29 ` [PATCH 5/8] 2.5.74 - seq_file conversion of /proc/net/atm (vc) Francois Romieu
2003-07-09 14:35   ` seq_file and proc_dir_entry data (was Re: [PATCH 5/8] 2.5.74 - seq_file conversion of /proc/net/atm (vc)) Ed L Cashin
2003-07-09  0:30 ` Francois Romieu [this message]
2003-07-09  0:31 ` [PATCH 7/8] 2.5.74 - seq_file conversion of /proc/net/atm (lec) Francois Romieu
2003-07-09  0:33 ` [PATCH 8/8] 2.5.74 - seq_file conversion of /proc/net/atm (cleanup) Francois Romieu
2003-07-10  5:49 ` [PATCHKIT] 2.5.74 - seq_file conversion of /proc/net/atm David S. Miller
2003-07-10 10:48   ` chas williams

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=20030709023051.H11897@electric-eye.fr.zoreil.com \
    --to=romieu@fr.zoreil.com \
    --cc=chas@locutus.cmf.nrl.navy.mil \
    --cc=davem@redhat.com \
    --cc=linux-kernel@vger.kernel.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).