Commit b8010c34 authored by David S. Miller's avatar David S. Miller

Merge master.kernel.org:/home/acme/BK/net-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 2fdee16b dfd60588
...@@ -68,44 +68,42 @@ static char *ax2asc2(ax25_address *a, char *buf) ...@@ -68,44 +68,42 @@ static char *ax2asc2(ax25_address *a, char *buf)
#endif /* CONFIG_AX25 */ #endif /* CONFIG_AX25 */
struct arp_iter_state { struct arp_iter_state {
loff_t is_pneigh: 1, int is_pneigh, bucket;
bucket: 6,
pos: sizeof(loff_t) * 8 - 7;
}; };
static __inline__ struct neighbour *neigh_get_bucket(loff_t *pos) static __inline__ struct neighbour *neigh_get_bucket(struct seq_file *seq,
loff_t *pos)
{ {
struct neighbour *n = NULL; struct neighbour *n = NULL;
struct arp_iter_state* state = (struct arp_iter_state *)pos; struct arp_iter_state* state = seq->private;
loff_t l = state->pos; loff_t l = *pos;
int i, bucket = state->bucket; int i;
for (; bucket <= NEIGH_HASHMASK; ++bucket) for (; state->bucket <= NEIGH_HASHMASK; ++state->bucket)
for (i = 0, n = arp_tbl.hash_buckets[bucket]; n; for (i = 0, n = arp_tbl.hash_buckets[state->bucket]; n;
++i, n = n->next) ++i, n = n->next)
/* Do not confuse users "arp -a" with magic entries */ /* Do not confuse users "arp -a" with magic entries */
if ((n->nud_state & ~NUD_NOARP) && !l--) { if ((n->nud_state & ~NUD_NOARP) && !l--) {
state->pos = i; *pos = i;
state->bucket = bucket;
goto out; goto out;
} }
out: out:
return n; return n;
} }
static __inline__ struct pneigh_entry *pneigh_get_bucket(loff_t *pos) static __inline__ struct pneigh_entry *pneigh_get_bucket(struct seq_file *seq,
loff_t *pos)
{ {
struct pneigh_entry *n = NULL; struct pneigh_entry *n = NULL;
struct arp_iter_state* state = (struct arp_iter_state *)pos; struct arp_iter_state* state = seq->private;
loff_t l = state->pos; loff_t l = *pos;
int i, bucket = state->bucket; int i;
for (; bucket <= PNEIGH_HASHMASK; ++bucket) for (; state->bucket <= PNEIGH_HASHMASK; ++state->bucket)
for (i = 0, n = arp_tbl.phash_buckets[bucket]; n; for (i = 0, n = arp_tbl.phash_buckets[state->bucket]; n;
++i, n = n->next) ++i, n = n->next)
if (!l--) { if (!l--) {
state->pos = i; *pos = i;
state->bucket = bucket;
goto out; goto out;
} }
out: out:
...@@ -114,18 +112,16 @@ static __inline__ struct pneigh_entry *pneigh_get_bucket(loff_t *pos) ...@@ -114,18 +112,16 @@ static __inline__ struct pneigh_entry *pneigh_get_bucket(loff_t *pos)
static __inline__ void *arp_get_bucket(struct seq_file *seq, loff_t *pos) static __inline__ void *arp_get_bucket(struct seq_file *seq, loff_t *pos)
{ {
void *rc = neigh_get_bucket(pos); void *rc = neigh_get_bucket(seq, pos);
if (!rc) { if (!rc) {
struct arp_iter_state* state = (struct arp_iter_state *)pos; struct arp_iter_state* state = seq->private;
read_unlock_bh(&arp_tbl.lock); read_unlock_bh(&arp_tbl.lock);
state->is_pneigh = 1; state->is_pneigh = 1;
state->bucket = 0; state->bucket = 0;
state->pos = 0; *pos = 0;
/* HACK: till there is state we can pass to seq_show... */ rc = pneigh_get_bucket(seq, pos);
seq->private = (void *)1;
rc = pneigh_get_bucket(pos);
} }
return rc; return rc;
} }
...@@ -146,33 +142,31 @@ static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -146,33 +142,31 @@ static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
goto out; goto out;
} }
state = (struct arp_iter_state *)pos; state = seq->private;
if (!state->is_pneigh) { if (!state->is_pneigh) {
struct neighbour *n = v; struct neighbour *n = v;
rc = n = n->next; rc = n = n->next;
if (n) if (n)
goto out; goto out;
state->pos = 0; *pos = 0;
++state->bucket; ++state->bucket;
rc = neigh_get_bucket(pos); rc = neigh_get_bucket(seq, pos);
if (rc) if (rc)
goto out; goto out;
read_unlock_bh(&arp_tbl.lock); read_unlock_bh(&arp_tbl.lock);
/* HACK: till there is state we can pass to seq_show... */
seq->private = (void *)1;
state->is_pneigh = 1; state->is_pneigh = 1;
state->bucket = 0; state->bucket = 0;
state->pos = 0; *pos = 0;
rc = pneigh_get_bucket(pos); rc = pneigh_get_bucket(seq, pos);
} else { } else {
struct pneigh_entry *pn = v; struct pneigh_entry *pn = v;
pn = pn->next; pn = pn->next;
if (!pn) { if (!pn) {
++state->bucket; ++state->bucket;
state->pos = 0; *pos = 0;
pn = pneigh_get_bucket(pos); pn = pneigh_get_bucket(seq, pos);
} }
rc = pn; rc = pn;
} }
...@@ -183,7 +177,9 @@ static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -183,7 +177,9 @@ static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void arp_seq_stop(struct seq_file *seq, void *v) static void arp_seq_stop(struct seq_file *seq, void *v)
{ {
if (!seq->private) struct arp_iter_state* state = seq->private;
if (!state->is_pneigh)
read_unlock_bh(&arp_tbl.lock); read_unlock_bh(&arp_tbl.lock);
} }
...@@ -241,7 +237,9 @@ static int arp_seq_show(struct seq_file *seq, void *v) ...@@ -241,7 +237,9 @@ static int arp_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, "IP address HW type Flags " seq_puts(seq, "IP address HW type Flags "
"HW address Mask Device\n"); "HW address Mask Device\n");
else { else {
if (seq->private) struct arp_iter_state* state = seq->private;
if (state->is_pneigh)
arp_format_pneigh_entry(seq, v); arp_format_pneigh_entry(seq, v);
else else
arp_format_neigh_entry(seq, v); arp_format_neigh_entry(seq, v);
...@@ -405,7 +403,35 @@ static struct seq_operations udp_seq_ops = { ...@@ -405,7 +403,35 @@ static struct seq_operations udp_seq_ops = {
static int arp_seq_open(struct inode *inode, struct file *file) static int arp_seq_open(struct inode *inode, struct file *file)
{ {
return seq_open(file, &arp_seq_ops); struct seq_file *seq;
int rc = -ENOMEM;
struct arp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
rc = seq_open(file, &arp_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
kfree(s);
goto out;
}
static int arp_seq_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = (struct seq_file *)file->private_data;
kfree(seq->private);
seq->private = NULL;
return seq_release(inode, file);
} }
static int fib_seq_open(struct inode *inode, struct file *file) static int fib_seq_open(struct inode *inode, struct file *file)
...@@ -422,7 +448,7 @@ static struct file_operations arp_seq_fops = { ...@@ -422,7 +448,7 @@ static struct file_operations arp_seq_fops = {
.open = arp_seq_open, .open = arp_seq_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = arp_seq_release,
}; };
static struct file_operations fib_seq_fops = { static struct file_operations fib_seq_fops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment