diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2009-11-25 18:40:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-25 18:40:35 -0500 |
commit | a661c4199b300503dae694efa21f1354f763b97c (patch) | |
tree | 706be22bf44642cd1109041f52fa9456cfdc77fe /net/ipv4/route.c | |
parent | 09ad9bc752519cc167d0a573e1acf69b5c707c67 (diff) |
net: convert /proc/net/rt_acct to seq_file
Rewrite statistics accumulation to be in terms of structure fields,
not raw u32 additions. Keep them in same order, though.
This is the last user of create_proc_read_entry() in net/,
please NAK all new ones as well as all new ->write_proc, ->read_proc and
create_proc_entry() users. Cc me if there are problems. :-)
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 68 |
1 files changed, 33 insertions, 35 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index aea7bb369cfa..9889fbd96487 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -513,43 +513,42 @@ static const struct file_operations rt_cpu_seq_fops = { | |||
513 | }; | 513 | }; |
514 | 514 | ||
515 | #ifdef CONFIG_NET_CLS_ROUTE | 515 | #ifdef CONFIG_NET_CLS_ROUTE |
516 | static int ip_rt_acct_read(char *buffer, char **start, off_t offset, | 516 | static int rt_acct_proc_show(struct seq_file *m, void *v) |
517 | int length, int *eof, void *data) | 517 | { |
518 | { | 518 | struct ip_rt_acct *dst, *src; |
519 | unsigned int i; | 519 | unsigned int i, j; |
520 | 520 | ||
521 | if ((offset & 3) || (length & 3)) | 521 | dst = kcalloc(256, sizeof(struct ip_rt_acct), GFP_KERNEL); |
522 | return -EIO; | 522 | if (!dst) |
523 | 523 | return -ENOMEM; | |
524 | if (offset >= sizeof(struct ip_rt_acct) * 256) { | 524 | |
525 | *eof = 1; | 525 | for_each_possible_cpu(i) { |
526 | return 0; | 526 | src = (struct ip_rt_acct *)per_cpu_ptr(ip_rt_acct, i); |
527 | } | 527 | for (j = 0; j < 256; j++) { |
528 | 528 | dst[j].o_bytes += src[j].o_bytes; | |
529 | if (offset + length >= sizeof(struct ip_rt_acct) * 256) { | 529 | dst[j].o_packets += src[j].o_packets; |
530 | length = sizeof(struct ip_rt_acct) * 256 - offset; | 530 | dst[j].i_bytes += src[j].i_bytes; |
531 | *eof = 1; | 531 | dst[j].i_packets += src[j].i_packets; |
532 | } | ||
532 | } | 533 | } |
533 | 534 | ||
534 | offset /= sizeof(u32); | 535 | seq_write(m, dst, 256 * sizeof(struct ip_rt_acct)); |
535 | 536 | kfree(dst); | |
536 | if (length > 0) { | 537 | return 0; |
537 | u32 *dst = (u32 *) buffer; | 538 | } |
538 | |||
539 | *start = buffer; | ||
540 | memset(dst, 0, length); | ||
541 | |||
542 | for_each_possible_cpu(i) { | ||
543 | unsigned int j; | ||
544 | u32 *src; | ||
545 | 539 | ||
546 | src = ((u32 *) per_cpu_ptr(ip_rt_acct, i)) + offset; | 540 | static int rt_acct_proc_open(struct inode *inode, struct file *file) |
547 | for (j = 0; j < length/4; j++) | 541 | { |
548 | dst[j] += src[j]; | 542 | return single_open(file, rt_acct_proc_show, NULL); |
549 | } | ||
550 | } | ||
551 | return length; | ||
552 | } | 543 | } |
544 | |||
545 | static const struct file_operations rt_acct_proc_fops = { | ||
546 | .owner = THIS_MODULE, | ||
547 | .open = rt_acct_proc_open, | ||
548 | .read = seq_read, | ||
549 | .llseek = seq_lseek, | ||
550 | .release = single_release, | ||
551 | }; | ||
553 | #endif | 552 | #endif |
554 | 553 | ||
555 | static int __net_init ip_rt_do_proc_init(struct net *net) | 554 | static int __net_init ip_rt_do_proc_init(struct net *net) |
@@ -567,8 +566,7 @@ static int __net_init ip_rt_do_proc_init(struct net *net) | |||
567 | goto err2; | 566 | goto err2; |
568 | 567 | ||
569 | #ifdef CONFIG_NET_CLS_ROUTE | 568 | #ifdef CONFIG_NET_CLS_ROUTE |
570 | pde = create_proc_read_entry("rt_acct", 0, net->proc_net, | 569 | pde = proc_create("rt_acct", 0, net->proc_net, &rt_acct_proc_fops); |
571 | ip_rt_acct_read, NULL); | ||
572 | if (!pde) | 570 | if (!pde) |
573 | goto err3; | 571 | goto err3; |
574 | #endif | 572 | #endif |