* [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm
@ 2003-08-08 22:03 Francois Romieu
2003-08-08 22:06 ` [PATCH 1/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (devices) Francois Romieu
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Francois Romieu @ 2003-08-08 22:03 UTC (permalink / raw)
To: chas; +Cc: linux-kernel, davem
followup to the posting of 2003/07/09. Patchkit is still divided in 8 parts:
1 - devices;
2 - utility and common code for vcs (vc/pvc/svc);
3 - pvc;
4 - svc;
5 - vc;
6 - arp;
7 - lec;
8 - final cleanup.
Gross bugs have been fixed in #7. It now passes some basic testing. Its
behavior with a huge number of lec remains to be proved. Others parts
already seemed quite nice last month.
--
Ueimor
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 1/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (devices) 2003-08-08 22:03 [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm Francois Romieu @ 2003-08-08 22:06 ` Francois Romieu 2003-08-08 22:08 ` [PATCH 2/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc helpers) Francois Romieu 2003-08-09 9:05 ` [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm David S. Miller 2003-08-09 10:11 ` Francois Romieu 2 siblings, 1 reply; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:06 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem seq_file conversion for proc/atm/devices: - code inspired from seq_file use in net/core/dev.c; - atm_dev_lock taken/released in atm_devices_seq_{start/stop}; - add a helper CREATE_SEQ_ENTRY() similar to CREATE_ENTRY() (both are removed once conversion is done). net/atm/proc.c | 111 ++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 79 insertions(+), 32 deletions(-) diff -puN net/atm/proc.c~atm-proc-seq-devices net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-devices Fri Aug 8 20:28:48 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:28:48 2003 @@ -24,6 +24,7 @@ #include <linux/fs.h> #include <linux/stat.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/errno.h> #include <linux/atm.h> #include <linux/atmdev.h> @@ -64,32 +65,30 @@ static struct file_operations proc_spec_ .read = proc_spec_atm_read, }; -static void add_stats(char *buf,const char *aal, +static void add_stats(struct seq_file *seq, const char *aal, const struct k_atm_aal_stats *stats) { - sprintf(strchr(buf,0),"%s ( %d %d %d %d %d )",aal, + seq_printf(seq, "%s ( %d %d %d %d %d )", aal, atomic_read(&stats->tx),atomic_read(&stats->tx_err), atomic_read(&stats->rx),atomic_read(&stats->rx_err), atomic_read(&stats->rx_drop)); } - -static void atm_dev_info(const struct atm_dev *dev,char *buf) +static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev) { - int off,i; + int i; - off = sprintf(buf,"%3d %-8s",dev->number,dev->type); + seq_printf(seq, "%3d %-8s", dev->number, dev->type); for (i = 0; i < ESI_LEN; i++) - off += sprintf(buf+off,"%02x",dev->esi[i]); - strcat(buf," "); - add_stats(buf,"0",&dev->stats.aal0); - strcat(buf," "); - add_stats(buf,"5",&dev->stats.aal5); - sprintf(strchr(buf,0), "\t[%d]", atomic_read(&dev->refcnt)); - strcat(buf,"\n"); + seq_printf(seq, "%02x", dev->esi[i]); + seq_puts(seq, " "); + add_stats(seq, "0", &dev->stats.aal0); + seq_puts(seq, " "); + add_stats(seq, "5", &dev->stats.aal5); + seq_printf(seq, "\t[%d]", atomic_read(&dev->refcnt)); + seq_putc(seq, '\n'); } - #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) @@ -303,30 +302,70 @@ lec_info(struct lec_arp_table *entry, ch #endif -static int atm_devices_info(loff_t pos,char *buf) +static __inline__ void *dev_get_idx(struct seq_file *seq, loff_t left) { - struct atm_dev *dev; struct list_head *p; - int left; - if (!pos) { - return sprintf(buf,"Itf Type ESI/\"MAC\"addr " - "AAL(TX,err,RX,err,drop) ... [refcnt]\n"); - } - left = pos-1; - spin_lock(&atm_dev_lock); list_for_each(p, &atm_devs) { - dev = list_entry(p, struct atm_dev, dev_list); - if (left-- == 0) { - atm_dev_info(dev,buf); - spin_unlock(&atm_dev_lock); - return strlen(buf); - } + if (!--left) + break; } - spin_unlock(&atm_dev_lock); - return 0; + return (p != &atm_devs) ? p : NULL; +} + +static void *atm_devices_seq_start(struct seq_file *seq, loff_t *pos) +{ + spin_lock(&atm_dev_lock); + return *pos ? dev_get_idx(seq, *pos) : (void *) 1; } +static void atm_devices_seq_stop(struct seq_file *seq, void *v) +{ + spin_unlock(&atm_dev_lock); +} + +static void *atm_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + v = (v == (void *)1) ? atm_devs.next : ((struct list_head *)v)->next; + return (v == &atm_devs) ? NULL : v; +} + +static int atm_devices_seq_show(struct seq_file *seq, void *v) +{ + static char atm_devices_banner[] = + "Itf Type ESI/\"MAC\"addr " + "AAL(TX,err,RX,err,drop) ... [refcnt]\n"; + + if (v == (void *)1) + seq_puts(seq, atm_devices_banner); + else { + struct atm_dev *dev = list_entry(v, struct atm_dev, dev_list); + + atm_dev_info(seq, dev); + } + return 0; +} + +static struct seq_operations atm_devices_seq_ops = { + .start = atm_devices_seq_start, + .next = atm_devices_seq_next, + .stop = atm_devices_seq_stop, + .show = atm_devices_seq_show, +}; + +static int atm_devices_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atm_devices_seq_ops); +} + +static struct file_operations atm_seq_devices_fops = { + .open = atm_devices_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + /* * FIXME: it isn't safe to walk the VCC list without turning off interrupts. * What is really needed is some lock on the devices. Ditto for ATMARP. @@ -623,6 +662,14 @@ void atm_proc_dev_deregister(struct atm_ kfree(dev->proc_name); } +#define CREATE_SEQ_ENTRY(name) \ + do { \ + name = create_proc_entry(#name, S_IRUGO, atm_proc_root); \ + if (!name) \ + goto cleanup; \ + name->proc_fops = &atm_seq_##name##_fops; \ + name->owner = THIS_MODULE; \ + } while (0) #define CREATE_ENTRY(name) \ name = create_proc_entry(#name,0,atm_proc_root); \ @@ -656,7 +703,7 @@ int __init atm_proc_init(void) atm_proc_root = proc_mkdir("net/atm",NULL); if (!atm_proc_root) return -ENOMEM; - CREATE_ENTRY(devices); + CREATE_SEQ_ENTRY(devices); CREATE_ENTRY(pvc); CREATE_ENTRY(svc); CREATE_ENTRY(vc); _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc helpers) 2003-08-08 22:06 ` [PATCH 1/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (devices) Francois Romieu @ 2003-08-08 22:08 ` Francois Romieu 2003-08-08 22:10 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) Francois Romieu 0 siblings, 1 reply; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:08 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem Helpers for seq_file conversion of proc/atm/{pvc/svc/vc}: - struct atm_vc_state keeps 1) the struct sock from which the current struct atm_vcc is deduced 2) the family to which must belong the vcc (PF_ATM{SVC/PVC/any}) 3) the availability of clip module - atm_vc_common_seq_{start/stop} are responsible for vcc_sklist locking - atm_vc_common_seq_{open/release} take care of get/put for the clip module. net/atm/proc.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 100 insertions(+) diff -puN net/atm/proc.c~atm-proc-seq-vc-utils net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-vc-utils Fri Aug 8 20:29:03 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:17 2003 @@ -161,6 +161,106 @@ static void atmarp_info(struct net_devic #endif +struct atm_vc_state { + struct sock *sk; + int family; + int clip_info; +}; + +static inline int compare_family(struct sock *sk, int family) +{ + struct atm_vcc *vcc = atm_sk(sk); + + return !family || (vcc->sk->sk_family == family); +} + +static int __atm_vc_common_walk(struct sock **sock, int family, loff_t l) +{ + struct sock *sk = *sock; + + if (sk == (void *)1) { + sk = hlist_empty(&vcc_sklist) ? NULL : __sk_head(&vcc_sklist); + l--; + } + for (; sk; sk = sk_next(sk)) { + l -= compare_family(sk, family); + if (l < 0) + goto out; + } + sk = (void *)1; +out: + *sock = sk; + return (l < 0); +} + +static void *atm_vc_common_walk(struct atm_vc_state *state, loff_t l) +{ + return __atm_vc_common_walk(&state->sk, state->family, l) ? + state : NULL; +} + +static int atm_vc_common_seq_open(struct inode *inode, struct file *file, + int family, struct seq_operations *ops) +{ + struct atm_vc_state *state; + struct seq_file *seq; + int rc = -ENOMEM; + + state = kmalloc(sizeof(*state), GFP_KERNEL); + if (!state) + goto out; + + rc = seq_open(file, ops); + if (rc) + goto out_kfree; + + state->family = family; + state->clip_info = try_atm_clip_ops(); + + seq = file->private_data; + seq->private = state; +out: + return rc; +out_kfree: + kfree(state); + goto out; +} + +static int atm_vc_common_seq_release(struct inode *inode, struct file *file) +{ +#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) + struct seq_file *seq = file->private_data; + struct atm_vc_state *state = seq->private; + + if (state->clip_info) + module_put(atm_clip_ops->owner); +#endif + return seq_release_private(inode, file); +} + +static void *atm_vc_common_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct atm_vc_state *state = seq->private; + loff_t left = *pos; + + read_lock(&vcc_sklist_lock); + state->sk = (void *)1; + return left ? atm_vc_common_walk(state, left) : (void *)1; +} + +static void atm_vc_common_seq_stop(struct seq_file *seq, void *v) +{ + read_unlock(&vcc_sklist_lock); +} + +static void *atm_vc_common_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct atm_vc_state *state = seq->private; + + v = atm_vc_common_walk(state, 1); + *pos += !!PTR_ERR(v); + return v; +} static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info) { _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) 2003-08-08 22:08 ` [PATCH 2/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc helpers) Francois Romieu @ 2003-08-08 22:10 ` Francois Romieu 2003-08-08 22:11 ` [PATCH 4/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (svc) Francois Romieu 2003-08-22 19:34 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) chas williams 0 siblings, 2 replies; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:10 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem seq_file support for /proc/net/atm/pvc: - pvc_info(): seq_printf/seq_putc replaces sprintf; - atm_pvc_info() removal; - the vc helpers (atm_vc_common_seq_xxx) do the remaining work. net/atm/proc.c | 81 +++++++++++++++++++++++---------------------------------- 1 files changed, 34 insertions(+), 47 deletions(-) diff -puN net/atm/proc.c~atm-proc-seq-pvc-conversion net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-pvc-conversion Fri Aug 8 20:29:25 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:25 2003 @@ -262,7 +262,7 @@ static void *atm_vc_common_seq_next(stru return v; } -static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info) +static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc, int clip_info) { static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" }; static const char *aal_name[] = { @@ -270,9 +270,8 @@ static void pvc_info(struct atm_vcc *vcc "???", "5", "???", "???", /* 4- 7 */ "???", "???", "???", "???", /* 8-11 */ "???", "0", "???", "???"}; /* 12-15 */ - int off; - off = sprintf(buf,"%3d %3d %5d %-3s %7d %-5s %7d %-6s", + seq_printf(seq, "%3d %3d %5d %-3s %7d %-5s %7d %-6s", vcc->dev->number,vcc->vpi,vcc->vci, vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" : aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr, @@ -284,18 +283,14 @@ static void pvc_info(struct atm_vcc *vcc struct net_device *dev; dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL; - off += sprintf(buf+off,"CLIP, Itf:%s, Encap:", + seq_printf(seq, "CLIP, Itf:%s, Encap:", dev ? dev->name : "none?"); - if (clip_vcc->encap) - off += sprintf(buf+off,"LLC/SNAP"); - else - off += sprintf(buf+off,"None"); + seq_printf(seq, "%s", clip_vcc->encap ? "LLC/SNAP" : "None"); } #endif - strcpy(buf+off,"\n"); + seq_putc(seq, '\n'); } - static const char *vcc_state(struct atm_vcc *vcc) { static const char *map[] = { ATM_VS2TXT_MAP }; @@ -466,48 +461,40 @@ static struct file_operations atm_seq_de .release = seq_release, }; -/* - * FIXME: it isn't safe to walk the VCC list without turning off interrupts. - * What is really needed is some lock on the devices. Ditto for ATMARP. - */ - -static int atm_pvc_info(loff_t pos,char *buf) +static int atm_pvc_seq_show(struct seq_file *seq, void *v) { - struct hlist_node *node; - struct sock *s; - struct atm_vcc *vcc; - int left, clip_info = 0; + static char atm_pvc_banner[] = + "Itf VPI VCI AAL RX(PCR,Class) TX(PCR,Class)\n"; - if (!pos) { - return sprintf(buf,"Itf VPI VCI AAL RX(PCR,Class) " - "TX(PCR,Class)\n"); - } - left = pos-1; -#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - if (try_atm_clip_ops()) - clip_info = 1; -#endif - read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - vcc = atm_sk(s); - if (vcc->sk->sk_family == PF_ATMPVC && vcc->dev && !left--) { - pvc_info(vcc,buf,clip_info); - read_unlock(&vcc_sklist_lock); -#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - if (clip_info) - module_put(atm_clip_ops->owner); -#endif - return strlen(buf); - } + if (v == (void *)1) + seq_puts(seq, atm_pvc_banner); + else { + struct atm_vc_state *state = seq->private; + struct atm_vcc *vcc = atm_sk(state->sk); + + pvc_info(seq, vcc, state->clip_info); } - read_unlock(&vcc_sklist_lock); -#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - if (clip_info) - module_put(atm_clip_ops->owner); -#endif return 0; } +static struct seq_operations atm_pvc_seq_ops = { + .start = atm_vc_common_seq_start, + .next = atm_vc_common_seq_next, + .stop = atm_vc_common_seq_stop, + .show = atm_pvc_seq_show, +}; + +static int atm_pvc_seq_open(struct inode *inode, struct file *file) +{ + return atm_vc_common_seq_open(inode, file, PF_ATMPVC, &atm_pvc_seq_ops); +} + +static struct file_operations atm_seq_pvc_fops = { + .open = atm_pvc_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = atm_vc_common_seq_release, +}; static int atm_vc_info(loff_t pos,char *buf) { @@ -804,7 +791,7 @@ int __init atm_proc_init(void) if (!atm_proc_root) return -ENOMEM; CREATE_SEQ_ENTRY(devices); - CREATE_ENTRY(pvc); + CREATE_SEQ_ENTRY(pvc); CREATE_ENTRY(svc); CREATE_ENTRY(vc); #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (svc) 2003-08-08 22:10 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) Francois Romieu @ 2003-08-08 22:11 ` Francois Romieu 2003-08-08 22:13 ` [PATCH 5/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc) Francois Romieu 2003-08-22 19:34 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) chas williams 1 sibling, 1 reply; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:11 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem seq_file support for /proc/net/atm/svc: Same comments as pvc. Just s/p/s/ net/atm/proc.c | 81 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 44 insertions(+), 37 deletions(-) diff -puN net/atm/proc.c~atm-proc-seq-svc-conversion net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-svc-conversion Fri Aug 8 20:29:28 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:28 2003 @@ -323,29 +323,26 @@ static void vc_info(struct atm_vcc *vcc, atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf); } - -static void svc_info(struct atm_vcc *vcc,char *buf) +static void svc_info(struct seq_file *seq, struct atm_vcc *vcc) { - char *here; - int i; - if (!vcc->dev) - sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%10s" : "N/A@%p%2s", - vcc,""); - else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi, - vcc->vci); - here = strchr(buf,0); - here += sprintf(here,"%-10s ",vcc_state(vcc)); - here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub, + seq_printf(seq, sizeof(void *) == 4 ? + "N/A@%p%10s" : "N/A@%p%2s", vcc, ""); + else + seq_printf(seq, "%3d %3d %5d ", + vcc->dev->number, vcc->vpi, vcc->vci); + seq_printf(seq, "%-10s ", vcc_state(vcc)); + seq_printf(seq, "%s%s", vcc->remote.sas_addr.pub, *vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : ""); - if (*vcc->remote.sas_addr.prv) + if (*vcc->remote.sas_addr.prv) { + int i; + for (i = 0; i < ATM_ESA_LEN; i++) - here += sprintf(here,"%02x", - vcc->remote.sas_addr.prv[i]); - strcat(here,"\n"); + seq_printf(seq, "%02x", vcc->remote.sas_addr.prv[i]); + } + seq_putc(seq, '\n'); } - #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) static char* @@ -522,31 +519,41 @@ static int atm_vc_info(loff_t pos,char * return 0; } - -static int atm_svc_info(loff_t pos,char *buf) +static int atm_svc_seq_show(struct seq_file *seq, void *v) { - struct hlist_node *node; - struct sock *s; - struct atm_vcc *vcc; - int left; + static char atm_svc_banner[] = + "Itf VPI VCI State Remote\n"; - if (!pos) - return sprintf(buf,"Itf VPI VCI State Remote\n"); - left = pos-1; - read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - vcc = atm_sk(s); - if (vcc->sk->sk_family == PF_ATMSVC && !left--) { - svc_info(vcc,buf); - read_unlock(&vcc_sklist_lock); - return strlen(buf); - } - } - read_unlock(&vcc_sklist_lock); + if (v == (void *)1) + seq_puts(seq, atm_svc_banner); + else { + struct atm_vc_state *state = seq->private; + struct atm_vcc *vcc = atm_sk(state->sk); + svc_info(seq, vcc); + } return 0; } +static struct seq_operations atm_svc_seq_ops = { + .start = atm_vc_common_seq_start, + .next = atm_vc_common_seq_next, + .stop = atm_vc_common_seq_stop, + .show = atm_svc_seq_show, +}; + +static int atm_svc_seq_open(struct inode *inode, struct file *file) +{ + return atm_vc_common_seq_open(inode, file, PF_ATMSVC, &atm_svc_seq_ops); +} + +static struct file_operations atm_seq_svc_fops = { + .open = atm_svc_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = atm_vc_common_seq_release, +}; + #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) static int atm_arp_info(loff_t pos,char *buf) { @@ -792,7 +799,7 @@ int __init atm_proc_init(void) return -ENOMEM; CREATE_SEQ_ENTRY(devices); CREATE_SEQ_ENTRY(pvc); - CREATE_ENTRY(svc); + CREATE_SEQ_ENTRY(svc); CREATE_ENTRY(vc); #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) CREATE_ENTRY(arp); _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc) 2003-08-08 22:11 ` [PATCH 4/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (svc) Francois Romieu @ 2003-08-08 22:13 ` Francois Romieu 2003-08-08 22:15 ` [PATCH 6/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (arp) Francois Romieu 0 siblings, 1 reply; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:13 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem seq_file support for /proc/net/atm/vc: Same comments as for pvc and svc. net/atm/proc.c | 80 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 43 insertions(+), 37 deletions(-) diff -puN net/atm/proc.c~atm-proc-seq-vc-conversion net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-vc-conversion Fri Aug 8 20:29:29 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:29 2003 @@ -298,29 +298,27 @@ static const char *vcc_state(struct atm_ return map[ATM_VF2VS(vcc->flags)]; } - -static void vc_info(struct atm_vcc *vcc,char *buf) +static void vc_info(struct seq_file *seq, struct atm_vcc *vcc) { - char *here; - - here = buf+sprintf(buf,"%p ",vcc); - if (!vcc->dev) here += sprintf(here,"Unassigned "); - else here += sprintf(here,"%3d %3d %5d ",vcc->dev->number,vcc->vpi, - vcc->vci); + seq_printf(seq, "%p ", vcc); + if (!vcc->dev) + seq_printf(seq, "Unassigned "); + else + seq_printf(seq, "%3d %3d %5d ", vcc->dev->number, vcc->vpi, + vcc->vci); switch (vcc->sk->sk_family) { case AF_ATMPVC: - here += sprintf(here,"PVC"); + seq_printf(seq, "PVC"); break; case AF_ATMSVC: - here += sprintf(here,"SVC"); + seq_printf(seq, "SVC"); break; default: - here += sprintf(here, "%3d", vcc->sk->sk_family); + seq_printf(seq, "%3d", vcc->sk->sk_family); } - here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags, - vcc->sk->sk_err, - atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf, - atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf); + seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d\n", vcc->flags, vcc->sk->sk_err, + atomic_read(&vcc->sk->sk_wmem_alloc),vcc->sk->sk_sndbuf, + atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf); } static void svc_info(struct seq_file *seq, struct atm_vcc *vcc) @@ -493,32 +491,33 @@ static struct file_operations atm_seq_pv .release = atm_vc_common_seq_release, }; -static int atm_vc_info(loff_t pos,char *buf) +static int atm_vc_seq_show(struct seq_file *seq, void *v) { - struct atm_vcc *vcc; - struct hlist_node *node; - struct sock *s; - int left; - - if (!pos) - return sprintf(buf,sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s", - "Address"," Itf VPI VCI Fam Flags Reply Send buffer" - " Recv buffer\n"); - left = pos-1; - read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - vcc = atm_sk(s); - if (!left--) { - vc_info(vcc,buf); - read_unlock(&vcc_sklist_lock); - return strlen(buf); - } - } - read_unlock(&vcc_sklist_lock); + if (v == (void *)1) { + seq_printf(seq, sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s", + "Address ", "Itf VPI VCI Fam Flags Reply " + "Send buffer Recv buffer\n"); + } else { + struct atm_vc_state *state = seq->private; + struct atm_vcc *vcc = atm_sk(state->sk); + vc_info(seq, vcc); + } return 0; } +static struct seq_operations atm_vc_seq_ops = { + .start = atm_vc_common_seq_start, + .next = atm_vc_common_seq_next, + .stop = atm_vc_common_seq_stop, + .show = atm_vc_seq_show, +}; + +static int atm_vc_seq_open(struct inode *inode, struct file *file) +{ + return atm_vc_common_seq_open(inode, file, 0, &atm_vc_seq_ops); +} + static int atm_svc_seq_show(struct seq_file *seq, void *v) { static char atm_svc_banner[] = @@ -535,6 +534,13 @@ static int atm_svc_seq_show(struct seq_f return 0; } +static struct file_operations atm_seq_vc_fops = { + .open = atm_vc_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = atm_vc_common_seq_release, +}; + static struct seq_operations atm_svc_seq_ops = { .start = atm_vc_common_seq_start, .next = atm_vc_common_seq_next, @@ -800,7 +806,7 @@ int __init atm_proc_init(void) CREATE_SEQ_ENTRY(devices); CREATE_SEQ_ENTRY(pvc); CREATE_SEQ_ENTRY(svc); - CREATE_ENTRY(vc); + CREATE_SEQ_ENTRY(vc); #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) CREATE_ENTRY(arp); #endif _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (arp) 2003-08-08 22:13 ` [PATCH 5/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc) Francois Romieu @ 2003-08-08 22:15 ` Francois Romieu 2003-08-08 22:19 ` [PATCH 7/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (lec) Francois Romieu 0 siblings, 1 reply; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:15 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem 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(); 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.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-arp-conversion Fri Aug 8 20:29:30 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:30 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; @@ -561,45 +553,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) @@ -808,7 +909,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); _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 7/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (lec) 2003-08-08 22:15 ` [PATCH 6/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (arp) Francois Romieu @ 2003-08-08 22:19 ` Francois Romieu 2003-08-08 22:22 ` [PATCH 8/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (cleanup) Francois Romieu 0 siblings, 1 reply; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:19 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem seq_file support for /proc/net/atm/lec: - lec_info(): seq_printf/seq_putc replaces sprintf; - traversal of the lec structure needs to walk: -> the lec interfaces -> the tables of arp tables(lec_arp_tables); -> the arp tables themselves -> the misc tables (lec_arp_empty_ones/lec_no_forward/mcast_fwds) Sum up of the call tree: atm_lec_seq_start()/atm_lec_seq_next() -> atm_lec_get_idx() -> atm_lec_itf_walk() (responsible for dev_lec/dev_put handling) -> atm_lec_priv_walk() (responsible for lec_priv locking) -> atm_lec_arp_walk() -> atm_lec_tbl_walk() -> atm_lec_misc_walk() (<- this one needed fixing) -> atm_lec_tbl_walk() (<- this one needed fixing) Each of the dedicated functions follows the same convention: return NULL as long as the seq_file cursor hasn't been digested (i.e. until < 0). Locking is only done when an entry (i.e. a lec_arp_table) is referenced. atm_lec_seq_stop()/atm_lec_itf_walk()/atm_lec_priv_walk() are responsible for getting this point right. - module refcounting is done in atm_lec_seq_open()/atm_lec_seq_release(); - atm_lec_info() is removed. net/atm/proc.c | 338 +++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 232 insertions(+), 106 deletions(-) diff -puN net/atm/proc.c~atm-proc-seq-lec-conversion net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-lec-conversion Fri Aug 8 20:29:31 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:31 2003 @@ -335,54 +335,45 @@ static void svc_info(struct seq_file *se #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -static char* -lec_arp_get_status_string(unsigned char status) +static char* lec_arp_get_status_string(unsigned char status) { - switch(status) { - case ESI_UNKNOWN: - return "ESI_UNKNOWN "; - case ESI_ARP_PENDING: - return "ESI_ARP_PENDING "; - case ESI_VC_PENDING: - return "ESI_VC_PENDING "; - case ESI_FLUSH_PENDING: - return "ESI_FLUSH_PENDING "; - case ESI_FORWARD_DIRECT: - return "ESI_FORWARD_DIRECT"; - default: - return "<Unknown> "; - } -} - -static void -lec_info(struct lec_arp_table *entry, char *buf) -{ - int j, offset=0; - - for(j=0;j<ETH_ALEN;j++) { - offset+=sprintf(buf+offset,"%2.2x",0xff&entry->mac_addr[j]); + static char *lec_arp_status_string[] = { + "ESI_UNKNOWN ", + "ESI_ARP_PENDING ", + "ESI_VC_PENDING ", + "ESI_FLUSH_PENDING ", + "ESI_FORWARD_DIRECT", + "<Unknown> " + }; + + if (status > ESI_FORWARD_DIRECT - 1) + status = ESI_FORWARD_DIRECT; + return lec_arp_status_string[status - ESI_UNKNOWN]; +} + +static void lec_info(struct seq_file *seq, struct lec_arp_table *entry) +{ + int i; + + for (i = 0; i < ETH_ALEN; i++) + seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff); + seq_printf(seq, " "); + for (i = 0; i < ATM_ESA_LEN; i++) + seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff); + seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status), + entry->flags & 0xffff); + if (entry->vcc) + seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci); + else + seq_printf(seq, " "); + if (entry->recv_vcc) { + seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi, + entry->recv_vcc->vci); } - offset+=sprintf(buf+offset, " "); - for(j=0;j<ATM_ESA_LEN;j++) { - offset+=sprintf(buf+offset,"%2.2x",0xff&entry->atm_addr[j]); - } - offset+=sprintf(buf+offset, " %s %4.4x", - lec_arp_get_status_string(entry->status), - entry->flags&0xffff); - if (entry->vcc) { - offset+=sprintf(buf+offset, "%3d %3d ", entry->vcc->vpi, - entry->vcc->vci); - } else - offset+=sprintf(buf+offset, " "); - if (entry->recv_vcc) { - offset+=sprintf(buf+offset, " %3d %3d", - entry->recv_vcc->vpi, entry->recv_vcc->vci); - } - - sprintf(buf+offset,"\n"); + seq_putc(seq, '\n'); } -#endif +#endif /* CONFIG_ATM_LANE */ static __inline__ void *dev_get_idx(struct seq_file *seq, loff_t left) { @@ -703,78 +694,213 @@ static struct file_operations atm_seq_ar #endif /* CONFIG_ATM_CLIP */ #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -static int atm_lec_info(loff_t pos,char *buf) -{ + +struct atm_lec_state { unsigned long flags; - struct lec_priv *priv; + struct lec_priv *locked; struct lec_arp_table *entry; - int i, count, d, e; struct net_device *dev; + int itf; + int arp_table; + int misc_table; +}; - if (!pos) { - return sprintf(buf,"Itf MAC ATM destination" - " Status Flags " - "VPI/VCI Recv VPI/VCI\n"); +static void *atm_lec_tbl_walk(struct atm_lec_state *state, + struct lec_arp_table *tbl, loff_t *l) +{ + struct lec_arp_table *e = state->entry; + + if (!e) + e = tbl; + if (e == (void *)1) { + e = tbl; + --*l; } - if (!try_atm_lane_ops()) - return 0; /* the lane module is not there yet */ + for (; e; e = e->next) { + if (--*l < 0) + break; + } + state->entry = e; + return (*l < 0) ? state : NULL; +} + +static void *atm_lec_arp_walk(struct atm_lec_state *state, loff_t *l, + struct lec_priv *priv) +{ + void *v = NULL; + int p; - count = pos; - for(d = 0; d < MAX_LEC_ITF; d++) { - dev = atm_lane_ops->get_lec(d); - if (!dev || !(priv = (struct lec_priv *) dev->priv)) - continue; - spin_lock_irqsave(&priv->lec_arp_lock, flags); - for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - for(entry = priv->lec_arp_tables[i]; entry; entry = entry->next) { - if (--count) - continue; - e = sprintf(buf,"%s ", dev->name); - lec_info(entry, buf+e); - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - dev_put(dev); - module_put(atm_lane_ops->owner); - return strlen(buf); - } - } - for(entry = priv->lec_arp_empty_ones; entry; entry = entry->next) { - if (--count) - continue; - e = sprintf(buf,"%s ", dev->name); - lec_info(entry, buf+e); - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - dev_put(dev); - module_put(atm_lane_ops->owner); - return strlen(buf); - } - for(entry = priv->lec_no_forward; entry; entry=entry->next) { - if (--count) - continue; - e = sprintf(buf,"%s ", dev->name); - lec_info(entry, buf+e); - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - dev_put(dev); - module_put(atm_lane_ops->owner); - return strlen(buf); - } - for(entry = priv->mcast_fwds; entry; entry = entry->next) { - if (--count) - continue; - e = sprintf(buf,"%s ", dev->name); - lec_info(entry, buf+e); - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - dev_put(dev); - module_put(atm_lane_ops->owner); - return strlen(buf); - } - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); + for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) { + v = atm_lec_tbl_walk(state, priv->lec_arp_tables[p], l); + if (v) + break; + } + state->arp_table = p; + return v; +} + +static void *atm_lec_misc_walk(struct atm_lec_state *state, loff_t *l, + struct lec_priv *priv) +{ + struct lec_arp_table *lec_misc_tables[] = { + priv->lec_arp_empty_ones, + priv->lec_no_forward, + priv->mcast_fwds + }; + void *v = NULL; + int q; + + for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) { + v = atm_lec_tbl_walk(state, lec_misc_tables[q], l); + if (v) + break; + } + state->misc_table = q; + return v; +} + +static void *atm_lec_priv_walk(struct atm_lec_state *state, loff_t *l, + struct lec_priv *priv) +{ + if (!state->locked) { + state->locked = priv; + spin_lock_irqsave(&priv->lec_arp_lock, state->flags); + } + if (!atm_lec_arp_walk(state, l, priv) && + !atm_lec_misc_walk(state, l, priv)) { + spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags); + state->locked = NULL; + } + return state->locked; +} + +static void *atm_lec_itf_walk(struct atm_lec_state *state, loff_t *l) +{ + struct net_device *dev; + void *v; + + dev = state->dev ? state->dev : atm_lane_ops->get_lec(state->itf); + v = (dev && dev->priv) ? atm_lec_priv_walk(state, l, dev->priv) : NULL; + if (!v && dev) { dev_put(dev); + dev = NULL; + } + state->dev = dev; + return v; +} + +static void *atm_lec_get_idx(struct atm_lec_state *state, loff_t l) +{ + void *v = NULL; + + for (; state->itf < MAX_LEC_ITF; state->itf++) { + v = atm_lec_itf_walk(state, &l); + if (v) + break; + } + return v; +} + +static void *atm_lec_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct atm_lec_state *state = seq->private; + + state->itf = 0; + state->dev = NULL; + state->locked = NULL; + state->arp_table = 0; + state->misc_table = 0; + state->entry = (void *)1; + + return *pos ? atm_lec_get_idx(state, *pos) : (void*)1; +} + +static void atm_lec_seq_stop(struct seq_file *seq, void *v) +{ + struct atm_lec_state *state = seq->private; + + if (state->dev) { + spin_unlock_irqrestore(&state->locked->lec_arp_lock, + state->flags); + dev_put(state->dev); + } +} + +static void *atm_lec_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct atm_lec_state *state = seq->private; + + v = atm_lec_get_idx(state, 1); + *pos += !!PTR_ERR(v); + return v; +} + +static int atm_lec_seq_show(struct seq_file *seq, void *v) +{ + static char atm_lec_banner[] = "Itf MAC ATM destination" + " Status Flags " + "VPI/VCI Recv VPI/VCI\n"; + + if (v == (void *)1) + seq_puts(seq, atm_lec_banner); + else { + struct atm_lec_state *state = seq->private; + struct net_device *dev = state->dev; + + seq_printf(seq, "%s ", dev->name); + lec_info(seq, state->entry); } - module_put(atm_lane_ops->owner); return 0; } -#endif +static struct seq_operations atm_lec_seq_ops = { + .start = atm_lec_seq_start, + .next = atm_lec_seq_next, + .stop = atm_lec_seq_stop, + .show = atm_lec_seq_show, +}; + +static int atm_lec_seq_open(struct inode *inode, struct file *file) +{ + struct atm_lec_state *state; + struct seq_file *seq; + int rc = -EAGAIN; + + if (!try_atm_lane_ops()) + goto out; + + state = kmalloc(sizeof(*state), GFP_KERNEL); + if (!state) { + rc = -ENOMEM; + goto out; + } + + rc = seq_open(file, &atm_lec_seq_ops); + if (rc) + goto out_kfree; + seq = file->private_data; + seq->private = state; +out: + return rc; +out_kfree: + kfree(state); + goto out; +} + +static int atm_lec_seq_release(struct inode *inode, struct file *file) +{ + module_put(atm_lane_ops->owner); + return seq_release_private(inode, file); +} + +static struct file_operations atm_seq_lec_fops = { + .open = atm_lec_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = atm_lec_seq_release, +}; + +#endif /* CONFIG_ATM_LANE */ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, loff_t *pos) @@ -912,7 +1038,7 @@ int __init atm_proc_init(void) CREATE_SEQ_ENTRY(arp); #endif #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) - CREATE_ENTRY(lec); + CREATE_SEQ_ENTRY(lec); #endif return 0; _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 8/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (cleanup) 2003-08-08 22:19 ` [PATCH 7/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (lec) Francois Romieu @ 2003-08-08 22:22 ` Francois Romieu 0 siblings, 0 replies; 13+ messages in thread From: Francois Romieu @ 2003-08-08 22:22 UTC (permalink / raw) To: chas; +Cc: linux-kernel, davem - introduction of the struct array 'atm_proc_ents': - removal of code duplication in atm_proc_cleanup(); - removal of code duplication in atm_proc_init(); - removal of the macros CREATE_SEQ_ENTRY() and CREATE_ENTRY(); - credits at the top of the file. net/atm/proc.c | 156 +++++++++++++++++++++------------------------------------ 1 files changed, 58 insertions(+), 98 deletions(-) diff -puN net/atm/proc.c~atm-proc-seq-post-conversion-removal net/atm/proc.c --- linux-2.6.0-test2-bk8/net/atm/proc.c~atm-proc-seq-post-conversion-removal Fri Aug 8 20:29:33 2003 +++ linux-2.6.0-test2-bk8-fr/net/atm/proc.c Fri Aug 8 20:29:33 2003 @@ -1,21 +1,13 @@ -/* net/atm/proc.c - ATM /proc interface */ - -/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ - -/* - * The mechanism used here isn't designed for speed but rather for convenience - * of implementation. We only return one entry per read system call, so we can - * be reasonably sure not to overrun the page and race conditions may lead to - * the addition or omission of some lines but never to any corruption of a - * line's internal structure. +/* net/atm/proc.c - ATM /proc interface + * + * Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA * - * Making the whole thing slightly more efficient is left as an exercise to the - * reader. (Suggestions: wrapper which loops to get several entries per system - * call; or make --left slightly more clever to avoid O(n^2) characteristics.) - * I find it fast enough on my unloaded 266 MHz Pentium 2 :-) + * seq_file api usage by romieu@fr.zoreil.com + * + * Evaluating the efficiency of the whole thing if left as an exercise to + * the reader. */ - #include <linux/config.h> #include <linux/module.h> /* for EXPORT_SYMBOL */ #include <linux/string.h> @@ -52,19 +44,12 @@ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, loff_t *pos); -static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count, - loff_t *pos); static struct file_operations proc_dev_atm_operations = { .owner = THIS_MODULE, .read = proc_dev_atm_read, }; -static struct file_operations proc_spec_atm_operations = { - .owner = THIS_MODULE, - .read = proc_spec_atm_read, -}; - static void add_stats(struct seq_file *seq, const char *aal, const struct k_atm_aal_stats *stats) { @@ -927,33 +912,9 @@ static ssize_t proc_dev_atm_read(struct return length; } - -static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count, - loff_t *pos) -{ - unsigned long page; - int length; - int (*info)(loff_t,char *); - info = PDE(file->f_dentry->d_inode)->data; - - if (count == 0) return 0; - page = get_zeroed_page(GFP_KERNEL); - if (!page) return -ENOMEM; - length = (*info)(*pos,(char *) page); - if (length > count) length = -EINVAL; - if (length >= 0) { - if (copy_to_user(buf,(char *) page,length)) length = -EFAULT; - (*pos)++; - } - free_page(page); - return length; -} - - struct proc_dir_entry *atm_proc_root; EXPORT_SYMBOL(atm_proc_root); - int atm_proc_dev_register(struct atm_dev *dev) { int digits,num; @@ -982,72 +943,71 @@ fail1: return error; } - void atm_proc_dev_deregister(struct atm_dev *dev) { remove_proc_entry(dev->proc_name, atm_proc_root); kfree(dev->proc_name); } -#define CREATE_SEQ_ENTRY(name) \ - do { \ - name = create_proc_entry(#name, S_IRUGO, atm_proc_root); \ - if (!name) \ - goto cleanup; \ - name->proc_fops = &atm_seq_##name##_fops; \ - name->owner = THIS_MODULE; \ - } while (0) - -#define CREATE_ENTRY(name) \ - name = create_proc_entry(#name,0,atm_proc_root); \ - if (!name) goto cleanup; \ - name->data = atm_##name##_info; \ - name->proc_fops = &proc_spec_atm_operations; \ - name->owner = THIS_MODULE - -static struct proc_dir_entry *devices = NULL, *pvc = NULL, - *svc = NULL, *arp = NULL, *lec = NULL, *vc = NULL; - -static void atm_proc_cleanup(void) -{ - if (devices) - remove_proc_entry("devices",atm_proc_root); - if (pvc) - remove_proc_entry("pvc",atm_proc_root); - if (svc) - remove_proc_entry("svc",atm_proc_root); - if (arp) - remove_proc_entry("arp",atm_proc_root); - if (lec) - remove_proc_entry("lec",atm_proc_root); - if (vc) - remove_proc_entry("vc",atm_proc_root); - remove_proc_entry("net/atm",NULL); +static struct atm_proc_entry { + char *name; + struct file_operations *proc_fops; + struct proc_dir_entry *dirent; +} atm_proc_ents[] = { + { .name = "devices", .proc_fops = &atm_seq_devices_fops }, + { .name = "pvc", .proc_fops = &atm_seq_pvc_fops }, + { .name = "svc", .proc_fops = &atm_seq_svc_fops }, + { .name = "vc", .proc_fops = &atm_seq_vc_fops }, +#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) + { .name = "arp", .proc_fops = &atm_seq_arp_fops }, +#endif +#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) + { .name = "lec", .proc_fops = &atm_seq_lec_fops }, +#endif + { .name = NULL, .proc_fops = NULL } +}; + +static void atm_proc_dirs_remove(void) +{ + static struct atm_proc_entry *e; + + for (e = atm_proc_ents; e->name; e++) { + if (e->dirent) + remove_proc_entry(e->name, atm_proc_root); + } + remove_proc_entry("net/atm", NULL); } int __init atm_proc_init(void) { + static struct atm_proc_entry *e; + int ret; + atm_proc_root = proc_mkdir("net/atm",NULL); if (!atm_proc_root) - return -ENOMEM; - CREATE_SEQ_ENTRY(devices); - CREATE_SEQ_ENTRY(pvc); - CREATE_SEQ_ENTRY(svc); - CREATE_SEQ_ENTRY(vc); -#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - CREATE_SEQ_ENTRY(arp); -#endif -#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) - CREATE_SEQ_ENTRY(lec); -#endif - return 0; + goto err_out; + for (e = atm_proc_ents; e->name; e++) { + struct proc_dir_entry *dirent; + + dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root); + if (!dirent) + goto err_out_remove; + dirent->proc_fops = e->proc_fops; + dirent->owner = THIS_MODULE; + e->dirent = dirent; + } + ret = 0; +out: + return ret; -cleanup: - atm_proc_cleanup(); - return -ENOMEM; +err_out_remove: + atm_proc_dirs_remove(); +err_out: + ret = -ENOMEM; + goto out; } -void atm_proc_exit(void) +void __exit atm_proc_exit(void) { - atm_proc_cleanup(); + atm_proc_dirs_remove(); } _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) 2003-08-08 22:10 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) Francois Romieu 2003-08-08 22:11 ` [PATCH 4/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (svc) Francois Romieu @ 2003-08-22 19:34 ` chas williams 1 sibling, 0 replies; 13+ messages in thread From: chas williams @ 2003-08-22 19:34 UTC (permalink / raw) To: Francois Romieu; +Cc: linux-kernel, davem In message <20030809001013.D2699@electric-eye.fr.zoreil.com>,Francois Romieu wr ites: >seq_file support for /proc/net/atm/pvc: >- pvc_info(): seq_printf/seq_putc replaces sprintf; >- atm_pvc_info() removal; >- the vc helpers (atm_vc_common_seq_xxx) do the remaining work. again, suggest renaming atm_pvc_XXXX to just pvc_XXXX atm_seq_pvc_fops should probably be pvc_seq_fops. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm 2003-08-08 22:03 [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm Francois Romieu 2003-08-08 22:06 ` [PATCH 1/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (devices) Francois Romieu @ 2003-08-09 9:05 ` David S. Miller 2003-08-11 14:56 ` chas williams 2003-08-09 10:11 ` Francois Romieu 2 siblings, 1 reply; 13+ messages in thread From: David S. Miller @ 2003-08-09 9:05 UTC (permalink / raw) To: Francois Romieu; +Cc: chas, linux-kernel On Sat, 9 Aug 2003 00:03:03 +0200 Francois Romieu <romieu@fr.zoreil.com> wrote: > followup to the posting of 2003/07/09. Patchkit is still divided in 8 parts: Chas, I trust you'll look at these? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm 2003-08-09 9:05 ` [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm David S. Miller @ 2003-08-11 14:56 ` chas williams 0 siblings, 0 replies; 13+ messages in thread From: chas williams @ 2003-08-11 14:56 UTC (permalink / raw) To: David S. Miller; +Cc: Francois Romieu, linux-kernel In message <20030809020527.7b242e0b.davem@redhat.com>,"David S. Miller" writes: >Chas, I trust you'll look at these? yes -- i should have some comments this week. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm 2003-08-08 22:03 [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm Francois Romieu 2003-08-08 22:06 ` [PATCH 1/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (devices) Francois Romieu 2003-08-09 9:05 ` [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm David S. Miller @ 2003-08-09 10:11 ` Francois Romieu 2 siblings, 0 replies; 13+ messages in thread From: Francois Romieu @ 2003-08-09 10:11 UTC (permalink / raw) To: chas; +Cc: linux-atm-general, linux-kernel, davem Re, Assuming some people are willing to test but don't want to play with a stack of patches, there is a single patch including the whole serie of changes at: <URL:http://www.fr.zoreil.com/linux/kernel/2.6.x/2.6.0-test3/extra/atm-seq_file.patch> Patch should be 2.6.0-test2-xxx agnostic. Please test and send full content of /proc/net/atm before/after the patch if things change. -- Ueimor ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2003-08-22 19:34 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-08-08 22:03 [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm Francois Romieu 2003-08-08 22:06 ` [PATCH 1/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (devices) Francois Romieu 2003-08-08 22:08 ` [PATCH 2/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc helpers) Francois Romieu 2003-08-08 22:10 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) Francois Romieu 2003-08-08 22:11 ` [PATCH 4/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (svc) Francois Romieu 2003-08-08 22:13 ` [PATCH 5/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (vc) Francois Romieu 2003-08-08 22:15 ` [PATCH 6/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (arp) Francois Romieu 2003-08-08 22:19 ` [PATCH 7/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (lec) Francois Romieu 2003-08-08 22:22 ` [PATCH 8/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (cleanup) Francois Romieu 2003-08-22 19:34 ` [PATCH 3/8] 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm (pvc) chas williams 2003-08-09 9:05 ` [PATCH] TRY #2 - 2.6.0-test2-bk8 - seq_file conversion of /proc/net/atm David S. Miller 2003-08-11 14:56 ` chas williams 2003-08-09 10:11 ` Francois Romieu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox