2010-02-05 01:44:18

by Li Zefan

[permalink] [raw]
Subject: [PATCH 00/13] net: simplify seq_file code

This patchset introduces seq_hlist_foo() helpers, and convert
net/* to seq_hlist_foo() and seq_list_foo().

---
fs/seq_file.c | 37 ++++++++++++-
include/linux/seq_file.h | 11 ++++
include/net/sock.h | 5 ++
net/appletalk/atalk_proc.c | 30 +----------
net/atm/proc.c | 2 +-
net/atm/resources.c | 28 +++--------
net/ax25/af_ax25.c | 18 +-----
net/ax25/ax25_uid.c | 25 ++--------
net/ipx/ipx_proc.c | 89 ++++---------------------------
net/irda/irlan/irlan_common.c | 26 ++--------
net/key/af_key.c | 20 +------
net/netrom/af_netrom.c | 21 +-------
net/netrom/nr_route.c | 53 +++----------------
net/packet/af_packet.c | 20 +------
net/rose/af_rose.c | 22 +-------
net/x25/x25_proc.c | 114 ++++-------------------------------------
16 files changed, 116 insertions(+), 405 deletions(-)


2010-02-05 01:44:33

by Li Zefan

[permalink] [raw]
Subject: Re: [PATCH 00/13] net: simplify seq_file code

[PATCH 01/13] seq_file: Add helpers for iteration over a hlist

Some places in kernel need to iterate over a hlist in seq_file,
so provide some common helpers.

Signed-off-by: Li Zefan <[email protected]>
---
fs/seq_file.c | 37 ++++++++++++++++++++++++++++++++++---
include/linux/seq_file.h | 11 +++++++++++
2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index eae7d9d..e833076 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -674,7 +674,6 @@ struct list_head *seq_list_start(struct list_head *head, loff_t pos)

return NULL;
}
-
EXPORT_SYMBOL(seq_list_start);

struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
@@ -684,7 +683,6 @@ struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)

return seq_list_start(head, pos - 1);
}
-
EXPORT_SYMBOL(seq_list_start_head);

struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
@@ -695,5 +693,38 @@ struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
++*ppos;
return lh == head ? NULL : lh;
}
-
EXPORT_SYMBOL(seq_list_next);
+
+struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
+{
+ struct hlist_node *node;
+
+ hlist_for_each(node, head)
+ if (pos-- == 0)
+ return node;
+ return NULL;
+}
+EXPORT_SYMBOL(seq_hlist_start);
+
+struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
+{
+ if (!pos)
+ return SEQ_START_TOKEN;
+
+ return seq_hlist_start(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_hlist_start_head);
+
+struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
+ loff_t *ppos)
+{
+ struct hlist_node *node = v;
+
+ ++*ppos;
+ if (v == SEQ_START_TOKEN)
+ return head->first;
+ else
+ return node->next;
+}
+EXPORT_SYMBOL(seq_hlist_next);
+
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 8366d8f..c95bcdc 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -135,4 +135,15 @@ extern struct list_head *seq_list_start_head(struct list_head *head,
extern struct list_head *seq_list_next(void *v, struct list_head *head,
loff_t *ppos);

+/*
+ * Helpers for iteration over hlist_head-s in seq_files
+ */
+
+extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
+ loff_t pos);
+extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
+ loff_t pos);
+extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
+ loff_t *ppos);
+
#endif
--
1.6.3

2010-02-05 01:44:57

by Li Zefan

[permalink] [raw]
Subject: [PATCH 02/13] net: add a wrapper sk_entry()


Signed-off-by: Li Zefan <[email protected]>
---
include/net/sock.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 3f1a480..c8d4000 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -317,6 +317,11 @@ struct sock {
/*
* Hashed lists helper routines
*/
+static inline struct sock *sk_entry(const struct hlist_node *node)
+{
+ return hlist_entry(node, struct sock, sk_node);
+}
+
static inline struct sock *__sk_head(const struct hlist_head *head)
{
return hlist_entry(head->first, struct sock, sk_node);
--
1.6.3

2010-02-05 01:45:15

by Li Zefan

[permalink] [raw]
Subject: [PATCH 03/13] net: x25: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/x25/x25_proc.c | 30 +++---------------------------
1 files changed, 3 insertions(+), 27 deletions(-)

diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
index 0a04e62..c4cd322 100644
--- a/net/x25/x25_proc.c
+++ b/net/x25/x25_proc.c
@@ -93,40 +93,16 @@ out:
return 0;
}

-static __inline__ struct sock *x25_get_socket_idx(loff_t pos)
-{
- struct sock *s;
- struct hlist_node *node;
-
- sk_for_each(s, node, &x25_list)
- if (!pos--)
- goto found;
- s = NULL;
-found:
- return s;
-}
-
static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
__acquires(x25_list_lock)
{
- loff_t l = *pos;
-
read_lock_bh(&x25_list_lock);
- return l ? x25_get_socket_idx(--l) : SEQ_START_TOKEN;
+ return seq_hlist_start_head(&x25_list, *pos);
}

static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct sock *s;
-
- ++*pos;
- if (v == SEQ_START_TOKEN) {
- s = sk_head(&x25_list);
- goto out;
- }
- s = sk_next(v);
-out:
- return s;
+ return seq_hlist_next(v, &x25_list, pos);
}

static void x25_seq_socket_stop(struct seq_file *seq, void *v)
@@ -148,7 +124,7 @@ static int x25_seq_socket_show(struct seq_file *seq, void *v)
goto out;
}

- s = v;
+ s = sk_entry(v);
x25 = x25_sk(s);

if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
--
1.6.3

2010-02-05 01:45:29

by Li Zefan

[permalink] [raw]
Subject: [PATCH 04/13] net: rose: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/rose/af_rose.c | 22 +++-------------------
1 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 8feb9e5..e90b9b6 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1404,29 +1404,13 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
static void *rose_info_start(struct seq_file *seq, loff_t *pos)
__acquires(rose_list_lock)
{
- int i;
- struct sock *s;
- struct hlist_node *node;
-
spin_lock_bh(&rose_list_lock);
- if (*pos == 0)
- return SEQ_START_TOKEN;
-
- i = 1;
- sk_for_each(s, node, &rose_list) {
- if (i == *pos)
- return s;
- ++i;
- }
- return NULL;
+ return seq_hlist_start_head(&rose_list, *pos);
}

static void *rose_info_next(struct seq_file *seq, void *v, loff_t *pos)
{
- ++*pos;
-
- return (v == SEQ_START_TOKEN) ? sk_head(&rose_list)
- : sk_next((struct sock *)v);
+ return seq_hlist_next(v, &rose_list, pos);
}

static void rose_info_stop(struct seq_file *seq, void *v)
@@ -1444,7 +1428,7 @@ static int rose_info_show(struct seq_file *seq, void *v)
"dest_addr dest_call src_addr src_call dev lci neigh st vs vr va t t1 t2 t3 hb idle Snd-Q Rcv-Q inode\n");

else {
- struct sock *s = v;
+ struct sock *s = sk_entry(v);
struct rose_sock *rose = rose_sk(s);
const char *devname, *callsign;
const struct net_device *dev = rose->device;
--
1.6.3

2010-02-05 01:45:45

by Li Zefan

[permalink] [raw]
Subject: [PATCH 05/13] net: packet: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/packet/af_packet.c | 20 +++-----------------
1 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 0f6bf59..256de26 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2374,33 +2374,19 @@ static struct notifier_block packet_netdev_notifier = {
};

#ifdef CONFIG_PROC_FS
-static inline struct sock *packet_seq_idx(struct net *net, loff_t off)
-{
- struct sock *s;
- struct hlist_node *node;
-
- sk_for_each(s, node, &net->packet.sklist) {
- if (!off--)
- return s;
- }
- return NULL;
-}

static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(seq_file_net(seq)->packet.sklist_lock)
{
struct net *net = seq_file_net(seq);
read_lock(&net->packet.sklist_lock);
- return *pos ? packet_seq_idx(net, *pos - 1) : SEQ_START_TOKEN;
+ return seq_hlist_start_head(&net->packet.sklist, *pos);
}

static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net *net = seq_file_net(seq);
- ++*pos;
- return (v == SEQ_START_TOKEN)
- ? sk_head(&net->packet.sklist)
- : sk_next((struct sock *)v) ;
+ return seq_hlist_next(v, &net->packet.sklist, pos);
}

static void packet_seq_stop(struct seq_file *seq, void *v)
@@ -2415,7 +2401,7 @@ static int packet_seq_show(struct seq_file *seq, void *v)
if (v == SEQ_START_TOKEN)
seq_puts(seq, "sk RefCnt Type Proto Iface R Rmem User Inode\n");
else {
- struct sock *s = v;
+ struct sock *s = sk_entry(v);
const struct packet_sock *po = pkt_sk(s);

seq_printf(seq,
--
1.6.3

2010-02-05 01:45:58

by Li Zefan

[permalink] [raw]
Subject: [PATCH 06/13] net: netrom: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/netrom/af_netrom.c | 21 ++----------------
net/netrom/nr_route.c | 53 ++++++++---------------------------------------
2 files changed, 12 insertions(+), 62 deletions(-)

diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 71604c6..a249127 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1267,28 +1267,13 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)

static void *nr_info_start(struct seq_file *seq, loff_t *pos)
{
- struct sock *s;
- struct hlist_node *node;
- int i = 1;
-
spin_lock_bh(&nr_list_lock);
- if (*pos == 0)
- return SEQ_START_TOKEN;
-
- sk_for_each(s, node, &nr_list) {
- if (i == *pos)
- return s;
- ++i;
- }
- return NULL;
+ return seq_hlist_start_head(&nr_list, *pos);
}

static void *nr_info_next(struct seq_file *seq, void *v, loff_t *pos)
{
- ++*pos;
-
- return (v == SEQ_START_TOKEN) ? sk_head(&nr_list)
- : sk_next((struct sock *)v);
+ return seq_hlist_next(v, &nr_list, pos);
}

static void nr_info_stop(struct seq_file *seq, void *v)
@@ -1298,7 +1283,7 @@ static void nr_info_stop(struct seq_file *seq, void *v)

static int nr_info_show(struct seq_file *seq, void *v)
{
- struct sock *s = v;
+ struct sock *s = sk_entry(v);
struct net_device *dev;
struct nr_sock *nr;
const char *devname;
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index e2e2d33..5cc6480 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -863,33 +863,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)

static void *nr_node_start(struct seq_file *seq, loff_t *pos)
{
- struct nr_node *nr_node;
- struct hlist_node *node;
- int i = 1;
-
spin_lock_bh(&nr_node_list_lock);
- if (*pos == 0)
- return SEQ_START_TOKEN;
-
- nr_node_for_each(nr_node, node, &nr_node_list) {
- if (i == *pos)
- return nr_node;
- ++i;
- }
-
- return NULL;
+ return seq_hlist_start_head(&nr_node_list, *pos);
}

static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct hlist_node *node;
- ++*pos;
-
- node = (v == SEQ_START_TOKEN)
- ? nr_node_list.first
- : ((struct nr_node *)v)->node_node.next;
-
- return hlist_entry(node, struct nr_node, node_node);
+ return seq_hlist_next(v, &nr_node_list, pos);
}

static void nr_node_stop(struct seq_file *seq, void *v)
@@ -906,7 +886,9 @@ static int nr_node_show(struct seq_file *seq, void *v)
seq_puts(seq,
"callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
else {
- struct nr_node *nr_node = v;
+ struct nr_node *nr_node = hlist_entry(v, struct nr_node,
+ node_node);
+
nr_node_lock(nr_node);
seq_printf(seq, "%-9s %-7s %d %d",
ax2asc(buf, &nr_node->callsign),
@@ -949,31 +931,13 @@ const struct file_operations nr_nodes_fops = {

static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
{
- struct nr_neigh *nr_neigh;
- struct hlist_node *node;
- int i = 1;
-
spin_lock_bh(&nr_neigh_list_lock);
- if (*pos == 0)
- return SEQ_START_TOKEN;
-
- nr_neigh_for_each(nr_neigh, node, &nr_neigh_list) {
- if (i == *pos)
- return nr_neigh;
- }
- return NULL;
+ return seq_hlist_start_head(&nr_neigh_list, *pos);
}

static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct hlist_node *node;
- ++*pos;
-
- node = (v == SEQ_START_TOKEN)
- ? nr_neigh_list.first
- : ((struct nr_neigh *)v)->neigh_node.next;
-
- return hlist_entry(node, struct nr_neigh, neigh_node);
+ return seq_hlist_next(v, &nr_neigh_list, pos);
}

static void nr_neigh_stop(struct seq_file *seq, void *v)
@@ -989,8 +953,9 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
if (v == SEQ_START_TOKEN)
seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n");
else {
- struct nr_neigh *nr_neigh = v;
+ struct nr_neigh *nr_neigh;

+ nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d",
nr_neigh->number,
ax2asc(buf, &nr_neigh->callsign),
--
1.6.3

2010-02-05 01:46:17

by Li Zefan

[permalink] [raw]
Subject: [PATCH 07/13] net: ax25: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/ax25/af_ax25.c | 18 +++---------------
net/ax25/ax25_uid.c | 25 ++++---------------------
2 files changed, 7 insertions(+), 36 deletions(-)

diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 5588ba6..a5beedf 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1863,25 +1863,13 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
static void *ax25_info_start(struct seq_file *seq, loff_t *pos)
__acquires(ax25_list_lock)
{
- 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;
+ return seq_hlist_start(&ax25_list, *pos);
}

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);
+ return seq_hlist_next(v, &ax25_list, pos);
}

static void ax25_info_stop(struct seq_file *seq, void *v)
@@ -1892,7 +1880,7 @@ static void ax25_info_stop(struct seq_file *seq, void *v)

static int ax25_info_show(struct seq_file *seq, void *v)
{
- ax25_cb *ax25 = v;
+ ax25_cb *ax25 = hlist_entry(v, struct ax25_cb, ax25_node);
char buf[11];
int k;

diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index 832bcf0..9f13f6e 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -146,31 +146,13 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(ax25_uid_lock)
{
- struct ax25_uid_assoc *pt;
- struct hlist_node *node;
- int i = 1;
-
read_lock(&ax25_uid_lock);
-
- if (*pos == 0)
- return SEQ_START_TOKEN;
-
- ax25_uid_for_each(pt, node, &ax25_uid_list) {
- if (i == *pos)
- return pt;
- ++i;
- }
- return NULL;
+ return seq_hlist_start_head(&ax25_uid_list, *pos);
}

static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- ++*pos;
- if (v == SEQ_START_TOKEN)
- return ax25_uid_list.first;
- else
- return hlist_entry(((ax25_uid_assoc *)v)->uid_node.next,
- ax25_uid_assoc, uid_node);
+ return seq_hlist_next(v, &ax25_uid_list, pos);
}

static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
@@ -186,8 +168,9 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v)
if (v == SEQ_START_TOKEN)
seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
else {
- struct ax25_uid_assoc *pt = v;
+ struct ax25_uid_assoc *pt;

+ pt = hlist_entry(v, struct ax25_uid_assoc, uid_node);
seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call));
}
return 0;
--
1.6.3

2010-02-05 01:46:30

by Li Zefan

[permalink] [raw]
Subject: [PATCH 08/13] net: appletalk: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/appletalk/atalk_proc.c | 30 +++---------------------------
1 files changed, 3 insertions(+), 27 deletions(-)

diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c
index 80caad1..6ef0e76 100644
--- a/net/appletalk/atalk_proc.c
+++ b/net/appletalk/atalk_proc.c
@@ -144,40 +144,16 @@ out:
return 0;
}

-static __inline__ struct sock *atalk_get_socket_idx(loff_t pos)
-{
- struct sock *s;
- struct hlist_node *node;
-
- sk_for_each(s, node, &atalk_sockets)
- if (!pos--)
- goto found;
- s = NULL;
-found:
- return s;
-}
-
static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos)
__acquires(atalk_sockets_lock)
{
- loff_t l = *pos;
-
read_lock_bh(&atalk_sockets_lock);
- return l ? atalk_get_socket_idx(--l) : SEQ_START_TOKEN;
+ return seq_hlist_start_head(&atalk_sockets, *pos);
}

static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct sock *i;
-
- ++*pos;
- if (v == SEQ_START_TOKEN) {
- i = sk_head(&atalk_sockets);
- goto out;
- }
- i = sk_next(v);
-out:
- return i;
+ return seq_hlist_next(v, &atalk_sockets, pos);
}

static void atalk_seq_socket_stop(struct seq_file *seq, void *v)
@@ -197,7 +173,7 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v)
goto out;
}

- s = v;
+ s = sk_entry(v);
at = at_sk(s);

seq_printf(seq, "%02X %04X:%02X:%02X %04X:%02X:%02X %08X:%08X "
--
1.6.3

2010-02-05 01:46:52

by Li Zefan

[permalink] [raw]
Subject: [PATCH 09/13] net: af_key: use seq_hlist_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/key/af_key.c | 20 +++-----------------
1 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index 76fa6fe..cb006b6 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3655,9 +3655,8 @@ static const struct net_proto_family pfkey_family_ops = {
#ifdef CONFIG_PROC_FS
static int pfkey_seq_show(struct seq_file *f, void *v)
{
- struct sock *s;
+ struct sock *s = sk_entry(v);

- s = (struct sock *)v;
if (v == SEQ_START_TOKEN)
seq_printf(f ,"sk RefCnt Rmem Wmem User Inode\n");
else
@@ -3676,19 +3675,9 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
{
struct net *net = seq_file_net(f);
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
- struct sock *s;
- struct hlist_node *node;
- loff_t pos = *ppos;

read_lock(&pfkey_table_lock);
- if (pos == 0)
- return SEQ_START_TOKEN;
-
- sk_for_each(s, node, &net_pfkey->table)
- if (pos-- == 1)
- return s;
-
- return NULL;
+ return seq_hlist_start_head(&net_pfkey->table, *ppos);
}

static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
@@ -3696,10 +3685,7 @@ static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
struct net *net = seq_file_net(f);
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);

- ++*ppos;
- return (v == SEQ_START_TOKEN) ?
- sk_head(&net_pfkey->table) :
- sk_next((struct sock *)v);
+ return seq_hlist_next(v, &net_pfkey->table, ppos);
}

static void pfkey_seq_stop(struct seq_file *f, void *v)
--
1.6.3

2010-02-05 01:47:00

by Li Zefan

[permalink] [raw]
Subject: [PATCH 10/13] net: x25: use seq_list_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/x25/x25_proc.c | 84 +++++-----------------------------------------------
1 files changed, 8 insertions(+), 76 deletions(-)

diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
index c4cd322..7ff3737 100644
--- a/net/x25/x25_proc.c
+++ b/net/x25/x25_proc.c
@@ -25,49 +25,17 @@
#include <net/x25.h>

#ifdef CONFIG_PROC_FS
-static __inline__ struct x25_route *x25_get_route_idx(loff_t pos)
-{
- struct list_head *route_entry;
- struct x25_route *rt = NULL;
-
- list_for_each(route_entry, &x25_route_list) {
- rt = list_entry(route_entry, struct x25_route, node);
- if (!pos--)
- goto found;
- }
- rt = NULL;
-found:
- return rt;
-}

static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
__acquires(x25_route_list_lock)
{
- loff_t l = *pos;
-
read_lock_bh(&x25_route_list_lock);
- return l ? x25_get_route_idx(--l) : SEQ_START_TOKEN;
+ return seq_list_start_head(&x25_route_list, *pos);
}

static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct x25_route *rt;
-
- ++*pos;
- if (v == SEQ_START_TOKEN) {
- rt = NULL;
- if (!list_empty(&x25_route_list))
- rt = list_entry(x25_route_list.next,
- struct x25_route, node);
- goto out;
- }
- rt = v;
- if (rt->node.next != &x25_route_list)
- rt = list_entry(rt->node.next, struct x25_route, node);
- else
- rt = NULL;
-out:
- return rt;
+ return seq_list_next(v, &x25_route_list, pos);
}

static void x25_seq_route_stop(struct seq_file *seq, void *v)
@@ -78,9 +46,9 @@ static void x25_seq_route_stop(struct seq_file *seq, void *v)

static int x25_seq_route_show(struct seq_file *seq, void *v)
{
- struct x25_route *rt;
+ struct x25_route *rt = list_entry(v, struct x25_route, node);

- if (v == SEQ_START_TOKEN) {
+ if (v == &x25_route_list) {
seq_puts(seq, "Address Digits Device\n");
goto out;
}
@@ -146,51 +114,16 @@ out:
return 0;
}

-static __inline__ struct x25_forward *x25_get_forward_idx(loff_t pos)
-{
- struct x25_forward *f;
- struct list_head *entry;
-
- list_for_each(entry, &x25_forward_list) {
- f = list_entry(entry, struct x25_forward, node);
- if (!pos--)
- goto found;
- }
-
- f = NULL;
-found:
- return f;
-}
-
static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos)
__acquires(x25_forward_list_lock)
{
- loff_t l = *pos;
-
read_lock_bh(&x25_forward_list_lock);
- return l ? x25_get_forward_idx(--l) : SEQ_START_TOKEN;
+ return seq_list_start_head(&x25_forward_list, *pos);
}

static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct x25_forward *f;
-
- ++*pos;
- if (v == SEQ_START_TOKEN) {
- f = NULL;
- if (!list_empty(&x25_forward_list))
- f = list_entry(x25_forward_list.next,
- struct x25_forward, node);
- goto out;
- }
- f = v;
- if (f->node.next != &x25_forward_list)
- f = list_entry(f->node.next, struct x25_forward, node);
- else
- f = NULL;
-out:
- return f;
-
+ return seq_list_next(v, &x25_forward_list, pos);
}

static void x25_seq_forward_stop(struct seq_file *seq, void *v)
@@ -201,9 +134,9 @@ static void x25_seq_forward_stop(struct seq_file *seq, void *v)

static int x25_seq_forward_show(struct seq_file *seq, void *v)
{
- struct x25_forward *f;
+ struct x25_forward *f = list_entry(v, struct x25_forward, node);

- if (v == SEQ_START_TOKEN) {
+ if (v == &x25_forward_list) {
seq_printf(seq, "lci dev1 dev2\n");
goto out;
}
@@ -212,7 +145,6 @@ static int x25_seq_forward_show(struct seq_file *seq, void *v)

seq_printf(seq, "%d %-10s %-10s\n",
f->lci, f->dev1->name, f->dev2->name);
-
out:
return 0;
}
--
1.6.3

2010-02-05 01:47:43

by Li Zefan

[permalink] [raw]
Subject: [PATCH 13/13] net: atm: use seq_list_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/atm/proc.c | 2 +-
net/atm/resources.c | 18 ++----------------
2 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/net/atm/proc.c b/net/atm/proc.c
index ab8419a..c0c3a79 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -236,7 +236,7 @@ static int atm_dev_seq_show(struct seq_file *seq, void *v)
"Itf Type ESI/\"MAC\"addr "
"AAL(TX,err,RX,err,drop) ... [refcnt]\n";

- if (v == SEQ_START_TOKEN)
+ if (v == &atm_devs)
seq_puts(seq, atm_dev_banner);
else {
struct atm_dev *dev = list_entry(v, struct atm_dev, dev_list);
diff --git a/net/atm/resources.c b/net/atm/resources.c
index f4091d6..bbd01b0 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -454,21 +454,10 @@ done:
return error;
}

-static inline void *dev_get_idx(loff_t left)
-{
- struct list_head *p;
-
- list_for_each(p, &atm_devs) {
- if (!--left)
- break;
- }
- return (p != &atm_devs) ? p : NULL;
-}
-
void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
{
mutex_lock(&atm_dev_mutex);
- return *pos ? dev_get_idx(*pos) : SEQ_START_TOKEN;
+ return seq_list_start_head(&atm_devs, *pos);
}

void atm_dev_seq_stop(struct seq_file *seq, void *v)
@@ -478,8 +467,5 @@ void atm_dev_seq_stop(struct seq_file *seq, void *v)

void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- ++*pos;
- v = (v == SEQ_START_TOKEN)
- ? atm_devs.next : ((struct list_head *)v)->next;
- return (v == &atm_devs) ? NULL : v;
+ return seq_list_next(v, &atm_devs, pos);
}
--
1.6.3

2010-02-05 01:47:15

by Li Zefan

[permalink] [raw]
Subject: [PATCH 11/13] net: irda: use seq_list_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/irda/irlan/irlan_common.c | 26 ++++----------------------
1 files changed, 4 insertions(+), 22 deletions(-)

diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index 315ead3..2141593 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -1128,19 +1128,8 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
*/
static void *irlan_seq_start(struct seq_file *seq, loff_t *pos)
{
- int i = 1;
- struct irlan_cb *self;
-
rcu_read_lock();
- if (*pos == 0)
- return SEQ_START_TOKEN;
-
- list_for_each_entry(self, &irlans, dev_list) {
- if (*pos == i)
- return self;
- ++i;
- }
- return NULL;
+ return seq_list_start_head(&irlans, *pos);
}

/* Return entry after v, and increment pos */
@@ -1148,14 +1137,7 @@ static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct list_head *nxt;

- ++*pos;
- if (v == SEQ_START_TOKEN)
- nxt = irlans.next;
- else
- nxt = ((struct irlan_cb *)v)->dev_list.next;
-
- return (nxt == &irlans) ? NULL
- : list_entry(nxt, struct irlan_cb, dev_list);
+ return seq_list_next(v, &irlans, pos);
}

/* End of reading /proc file */
@@ -1170,10 +1152,10 @@ static void irlan_seq_stop(struct seq_file *seq, void *v)
*/
static int irlan_seq_show(struct seq_file *seq, void *v)
{
- if (v == SEQ_START_TOKEN)
+ if (v == &irlans)
seq_puts(seq, "IrLAN instances:\n");
else {
- struct irlan_cb *self = v;
+ struct irlan_cb *self = list_entry(v, struct irlan_cb, list);

IRDA_ASSERT(self != NULL, return -1;);
IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
--
1.6.3

2010-02-05 01:47:31

by Li Zefan

[permalink] [raw]
Subject: [PATCH 12/13] net: ipx: use seq_list_foo() helpers

Simplify seq_file code.

Signed-off-by: Li Zefan <[email protected]>
---
net/ipx/ipx_proc.c | 89 +++++++---------------------------------------------
1 files changed, 12 insertions(+), 77 deletions(-)

diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index 5761784..cd44358 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -13,45 +13,15 @@
#include <net/tcp_states.h>
#include <net/ipx.h>

-static __inline__ struct ipx_interface *ipx_get_interface_idx(loff_t pos)
-{
- struct ipx_interface *i;
-
- list_for_each_entry(i, &ipx_interfaces, node)
- if (!pos--)
- goto out;
- i = NULL;
-out:
- return i;
-}
-
-static struct ipx_interface *ipx_interfaces_next(struct ipx_interface *i)
-{
- struct ipx_interface *rc = NULL;
-
- if (i->node.next != &ipx_interfaces)
- rc = list_entry(i->node.next, struct ipx_interface, node);
- return rc;
-}
-
static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
{
- loff_t l = *pos;
-
spin_lock_bh(&ipx_interfaces_lock);
- return l ? ipx_get_interface_idx(--l) : SEQ_START_TOKEN;
+ return seq_list_start_head(&ipx_interfaces, *pos);
}

static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct ipx_interface *i;
-
- ++*pos;
- if (v == SEQ_START_TOKEN)
- i = ipx_interfaces_head();
- else
- i = ipx_interfaces_next(v);
- return i;
+ return seq_list_next(v, &ipx_interfaces, pos);
}

static void ipx_seq_interface_stop(struct seq_file *seq, void *v)
@@ -63,7 +33,7 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v)
{
struct ipx_interface *i;

- if (v == SEQ_START_TOKEN) {
+ if (v == &ipx_interfaces) {
seq_puts(seq, "Network Node_Address Primary Device "
"Frame_Type");
#ifdef IPX_REFCNT_DEBUG
@@ -73,7 +43,7 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v)
goto out;
}

- i = v;
+ i = list_entry(v, struct ipx_interface, node);
seq_printf(seq, "%08lX ", (unsigned long int)ntohl(i->if_netnum));
seq_printf(seq, "%02X%02X%02X%02X%02X%02X ",
i->if_node[0], i->if_node[1], i->if_node[2],
@@ -89,53 +59,16 @@ out:
return 0;
}

-static struct ipx_route *ipx_routes_head(void)
-{
- struct ipx_route *rc = NULL;
-
- if (!list_empty(&ipx_routes))
- rc = list_entry(ipx_routes.next, struct ipx_route, node);
- return rc;
-}
-
-static struct ipx_route *ipx_routes_next(struct ipx_route *r)
-{
- struct ipx_route *rc = NULL;
-
- if (r->node.next != &ipx_routes)
- rc = list_entry(r->node.next, struct ipx_route, node);
- return rc;
-}
-
-static __inline__ struct ipx_route *ipx_get_route_idx(loff_t pos)
-{
- struct ipx_route *r;
-
- list_for_each_entry(r, &ipx_routes, node)
- if (!pos--)
- goto out;
- r = NULL;
-out:
- return r;
-}
-
static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos)
{
- loff_t l = *pos;
read_lock_bh(&ipx_routes_lock);
- return l ? ipx_get_route_idx(--l) : SEQ_START_TOKEN;
+ return seq_list_start_head(&ipx_routes, *pos);
}

static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct ipx_route *r;
-
++*pos;
- if (v == SEQ_START_TOKEN)
- r = ipx_routes_head();
- else
- r = ipx_routes_next(v);
- return r;
+ return seq_list_next(v, &ipx_routes, pos);
}

static void ipx_seq_route_stop(struct seq_file *seq, void *v)
@@ -147,11 +80,13 @@ static int ipx_seq_route_show(struct seq_file *seq, void *v)
{
struct ipx_route *rt;

- if (v == SEQ_START_TOKEN) {
+ if (v == &ipx_routes) {
seq_puts(seq, "Network Router_Net Router_Node\n");
goto out;
}
- rt = v;
+
+ rt = list_entry(v, struct ipx_route, node);
+
seq_printf(seq, "%08lX ", (unsigned long int)ntohl(rt->ir_net));
if (rt->ir_routed)
seq_printf(seq, "%08lX %02X%02X%02X%02X%02X%02X\n",
@@ -226,9 +161,9 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
spin_unlock_bh(&i->if_sklist_lock);
sk = NULL;
for (;;) {
- i = ipx_interfaces_next(i);
- if (!i)
+ if (i->node.next == &ipx_interfaces)
break;
+ i = list_entry(i->node.next, struct ipx_interface, node);
spin_lock_bh(&i->if_sklist_lock);
if (!hlist_empty(&i->if_sklist)) {
sk = sk_head(&i->if_sklist);
--
1.6.3

2010-02-05 01:59:05

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 00/13] net: simplify seq_file code

On Fri, 05 Feb 2010 09:44:45 +0800 Li Zefan <[email protected]> wrote:

> +struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
> +{
> + struct hlist_node *node;
> +
> + hlist_for_each(node, head)
> + if (pos-- == 0)
> + return node;
> + return NULL;
> +}
> +EXPORT_SYMBOL(seq_hlist_start);
> +
> +struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
> +{
> + if (!pos)
> + return SEQ_START_TOKEN;
> +
> + return seq_hlist_start(head, pos - 1);
> +}
> +EXPORT_SYMBOL(seq_hlist_start_head);
> +
> +struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
> + loff_t *ppos)
> +{
> + struct hlist_node *node = v;
> +
> + ++*ppos;
> + if (v == SEQ_START_TOKEN)
> + return head->first;
> + else
> + return node->next;
> +}
> +EXPORT_SYMBOL(seq_hlist_next);

Oy. Most of the global functions in seq_file.c are kerneldocumented,
as they should be!

Shouldn't seq_hlist_start_head() have been called seq_hlist_prev()?

Should seq_hlist_start() be passed *ppos, and update *ppos so the
caller can then call seq_hlist_next() and seq_hlist_prev()?

2010-02-05 02:12:42

by Li Zefan

[permalink] [raw]
Subject: Re: [PATCH 00/13] net: simplify seq_file code

Andrew Morton wrote:
> On Fri, 05 Feb 2010 09:44:45 +0800 Li Zefan <[email protected]> wrote:
>
>> +struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
>> +{
>> + struct hlist_node *node;
>> +
>> + hlist_for_each(node, head)
>> + if (pos-- == 0)
>> + return node;
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(seq_hlist_start);
>> +
>> +struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
>> +{
>> + if (!pos)
>> + return SEQ_START_TOKEN;
>> +
>> + return seq_hlist_start(head, pos - 1);
>> +}
>> +EXPORT_SYMBOL(seq_hlist_start_head);
>> +
>> +struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
>> + loff_t *ppos)
>> +{
>> + struct hlist_node *node = v;
>> +
>> + ++*ppos;
>> + if (v == SEQ_START_TOKEN)
>> + return head->first;
>> + else
>> + return node->next;
>> +}
>> +EXPORT_SYMBOL(seq_hlist_next);
>
> Oy. Most of the global functions in seq_file.c are kerneldocumented,
> as they should be!
>

I'll add kerneldoc in v2 patchset if I have to resend, otherwise I'll
send a delta patch for this.

> Shouldn't seq_hlist_start_head() have been called seq_hlist_prev()?
>

The list_head version has the name seq_list_start_head().

If you need to print a title in a seq_file, call seq_list_start_head()
in ->start() handler, otherwise call seq_list_start().

Those functions really need kerneldoc. ;)

> Should seq_hlist_start() be passed *ppos, and update *ppos so the
> caller can then call seq_hlist_next() and seq_hlist_prev()?
>

No, the ->start() callback of seq_operations shouldn't update *ppos.
I fixed some bugs in ftrace debugfs files which were caused by
updating *ppos in start().

2010-02-05 04:32:06

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 00/13] net: simplify seq_file code

From: Li Zefan <[email protected]>
Date: Fri, 05 Feb 2010 10:12:56 +0800

> I'll add kerneldoc in v2 patchset if I have to resend, otherwise I'll
> send a delta patch for this.

I want you to, at a minimum, resend the first patch because you
messed up the subject line for it.

Thanks.

2010-02-05 05:03:49

by Li Zefan

[permalink] [raw]
Subject: [PATCH 01/13] seq_file: Add helpers for iteration over a hlist

Some places in kernel need to iterate over a hlist in seq_file,
so provide some common helpers.

Signed-off-by: Li Zefan <[email protected]>
---

Here's the resend of the first patch.

I'll send another patch to add some kerneldoc for seq_list_xxx()
and seq_hlist_xxx().

---
fs/seq_file.c | 37 ++++++++++++++++++++++++++++++++++---
include/linux/seq_file.h | 11 +++++++++++
2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index eae7d9d..e833076 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -674,7 +674,6 @@ struct list_head *seq_list_start(struct list_head *head, loff_t pos)

return NULL;
}
-
EXPORT_SYMBOL(seq_list_start);

struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
@@ -684,7 +683,6 @@ struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)

return seq_list_start(head, pos - 1);
}
-
EXPORT_SYMBOL(seq_list_start_head);

struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
@@ -695,5 +693,38 @@ struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
++*ppos;
return lh == head ? NULL : lh;
}
-
EXPORT_SYMBOL(seq_list_next);
+
+struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
+{
+ struct hlist_node *node;
+
+ hlist_for_each(node, head)
+ if (pos-- == 0)
+ return node;
+ return NULL;
+}
+EXPORT_SYMBOL(seq_hlist_start);
+
+struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
+{
+ if (!pos)
+ return SEQ_START_TOKEN;
+
+ return seq_hlist_start(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_hlist_start_head);
+
+struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
+ loff_t *ppos)
+{
+ struct hlist_node *node = v;
+
+ ++*ppos;
+ if (v == SEQ_START_TOKEN)
+ return head->first;
+ else
+ return node->next;
+}
+EXPORT_SYMBOL(seq_hlist_next);
+
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 8366d8f..c95bcdc 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -135,4 +135,15 @@ extern struct list_head *seq_list_start_head(struct list_head *head,
extern struct list_head *seq_list_next(void *v, struct list_head *head,
loff_t *ppos);

+/*
+ * Helpers for iteration over hlist_head-s in seq_files
+ */
+
+extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
+ loff_t pos);
+extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
+ loff_t pos);
+extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
+ loff_t *ppos);
+
#endif
-- 1.6.3

2010-02-05 11:46:45

by Paulius Zaleckas

[permalink] [raw]
Subject: Re: [PATCH 11/13] net: irda: use seq_list_foo() helpers

On 02/05/2010 03:47 AM, Li Zefan wrote:
[...]
> /* Return entry after v, and increment pos */
> @@ -1148,14 +1137,7 @@ static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
> {
> struct list_head *nxt;

you should remove nxt declaration.

> - ++*pos;
> - if (v == SEQ_START_TOKEN)
> - nxt = irlans.next;
> - else
> - nxt = ((struct irlan_cb *)v)->dev_list.next;
> -
> - return (nxt ==&irlans) ? NULL
> - : list_entry(nxt, struct irlan_cb, dev_list);
> + return seq_list_next(v,&irlans, pos);
> }
[...]

2010-02-09 06:57:45

by Li Zefan

[permalink] [raw]
Subject: Re: [PATCH 11/13] net: irda: use seq_list_foo() helpers

Paulius Zaleckas wrote:
> On 02/05/2010 03:47 AM, Li Zefan wrote:
> [...]
>> /* Return entry after v, and increment pos */
>> @@ -1148,14 +1137,7 @@ static void *irlan_seq_next(struct seq_file
>> *seq, void *v, loff_t *pos)
>> {
>> struct list_head *nxt;
>
> you should remove nxt declaration.
>

Thanks! Will fix.