diff options
| author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2012-03-23 18:02:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:42 -0400 |
| commit | e075f59152890ffd7e3d704afc997dd686c8a781 (patch) | |
| tree | 94dbf5eda32d7dea9821ca308c4317e75756f7bd | |
| parent | 1b26c9b334044cff6d1d2698f2be41bc7d9a0864 (diff) | |
seq_file: add seq_set_overflow(), seq_overflow()
It is undocumented but a seq_file's overflow state is indicated by
m->count == m->size. Add seq_set_overflow() and seq_overflow() to
set/check overflow status explicitly.
Based on an idea from Eric Dumazet.
[akpm@linux-foundation.org: tweak code comment]
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | fs/seq_file.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/seq_file.c b/fs/seq_file.c index 55c293f7024d..46cfb067fc3a 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -13,6 +13,22 @@ | |||
| 13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
| 14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
| 15 | 15 | ||
| 16 | |||
| 17 | /* | ||
| 18 | * seq_files have a buffer which can may overflow. When this happens a larger | ||
| 19 | * buffer is reallocated and all the data will be printed again. | ||
| 20 | * The overflow state is true when m->count == m->size. | ||
| 21 | */ | ||
| 22 | static bool seq_overflow(struct seq_file *m) | ||
| 23 | { | ||
| 24 | return m->count == m->size; | ||
| 25 | } | ||
| 26 | |||
| 27 | static void seq_set_overflow(struct seq_file *m) | ||
| 28 | { | ||
| 29 | m->count = m->size; | ||
| 30 | } | ||
| 31 | |||
| 16 | /** | 32 | /** |
| 17 | * seq_open - initialize sequential file | 33 | * seq_open - initialize sequential file |
| 18 | * @file: file we initialize | 34 | * @file: file we initialize |
| @@ -92,7 +108,7 @@ static int traverse(struct seq_file *m, loff_t offset) | |||
| 92 | error = 0; | 108 | error = 0; |
| 93 | m->count = 0; | 109 | m->count = 0; |
| 94 | } | 110 | } |
| 95 | if (m->count == m->size) | 111 | if (seq_overflow(m)) |
| 96 | goto Eoverflow; | 112 | goto Eoverflow; |
| 97 | if (pos + m->count > offset) { | 113 | if (pos + m->count > offset) { |
| 98 | m->from = offset - pos; | 114 | m->from = offset - pos; |
| @@ -234,7 +250,7 @@ Fill: | |||
| 234 | break; | 250 | break; |
| 235 | } | 251 | } |
| 236 | err = m->op->show(m, p); | 252 | err = m->op->show(m, p); |
| 237 | if (m->count == m->size || err) { | 253 | if (seq_overflow(m) || err) { |
| 238 | m->count = offs; | 254 | m->count = offs; |
| 239 | if (likely(err <= 0)) | 255 | if (likely(err <= 0)) |
| 240 | break; | 256 | break; |
| @@ -361,7 +377,7 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc) | |||
| 361 | *p++ = '0' + (c & 07); | 377 | *p++ = '0' + (c & 07); |
| 362 | continue; | 378 | continue; |
| 363 | } | 379 | } |
| 364 | m->count = m->size; | 380 | seq_set_overflow(m); |
| 365 | return -1; | 381 | return -1; |
| 366 | } | 382 | } |
| 367 | m->count = p - m->buf; | 383 | m->count = p - m->buf; |
| @@ -383,7 +399,7 @@ int seq_printf(struct seq_file *m, const char *f, ...) | |||
| 383 | return 0; | 399 | return 0; |
| 384 | } | 400 | } |
| 385 | } | 401 | } |
| 386 | m->count = m->size; | 402 | seq_set_overflow(m); |
| 387 | return -1; | 403 | return -1; |
| 388 | } | 404 | } |
| 389 | EXPORT_SYMBOL(seq_printf); | 405 | EXPORT_SYMBOL(seq_printf); |
| @@ -512,7 +528,7 @@ int seq_bitmap(struct seq_file *m, const unsigned long *bits, | |||
| 512 | return 0; | 528 | return 0; |
| 513 | } | 529 | } |
| 514 | } | 530 | } |
| 515 | m->count = m->size; | 531 | seq_set_overflow(m); |
| 516 | return -1; | 532 | return -1; |
| 517 | } | 533 | } |
| 518 | EXPORT_SYMBOL(seq_bitmap); | 534 | EXPORT_SYMBOL(seq_bitmap); |
| @@ -528,7 +544,7 @@ int seq_bitmap_list(struct seq_file *m, const unsigned long *bits, | |||
| 528 | return 0; | 544 | return 0; |
| 529 | } | 545 | } |
| 530 | } | 546 | } |
| 531 | m->count = m->size; | 547 | seq_set_overflow(m); |
| 532 | return -1; | 548 | return -1; |
| 533 | } | 549 | } |
| 534 | EXPORT_SYMBOL(seq_bitmap_list); | 550 | EXPORT_SYMBOL(seq_bitmap_list); |
| @@ -639,7 +655,7 @@ int seq_puts(struct seq_file *m, const char *s) | |||
| 639 | m->count += len; | 655 | m->count += len; |
| 640 | return 0; | 656 | return 0; |
| 641 | } | 657 | } |
| 642 | m->count = m->size; | 658 | seq_set_overflow(m); |
| 643 | return -1; | 659 | return -1; |
| 644 | } | 660 | } |
| 645 | EXPORT_SYMBOL(seq_puts); | 661 | EXPORT_SYMBOL(seq_puts); |
| @@ -673,7 +689,7 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, | |||
| 673 | m->count += len; | 689 | m->count += len; |
| 674 | return 0; | 690 | return 0; |
| 675 | overflow: | 691 | overflow: |
| 676 | m->count = m->size; | 692 | seq_set_overflow(m); |
| 677 | return -1; | 693 | return -1; |
| 678 | } | 694 | } |
| 679 | EXPORT_SYMBOL(seq_put_decimal_ull); | 695 | EXPORT_SYMBOL(seq_put_decimal_ull); |
| @@ -683,7 +699,7 @@ int seq_put_decimal_ll(struct seq_file *m, char delimiter, | |||
| 683 | { | 699 | { |
| 684 | if (num < 0) { | 700 | if (num < 0) { |
| 685 | if (m->count + 3 >= m->size) { | 701 | if (m->count + 3 >= m->size) { |
| 686 | m->count = m->size; | 702 | seq_set_overflow(m); |
| 687 | return -1; | 703 | return -1; |
| 688 | } | 704 | } |
| 689 | if (delimiter) | 705 | if (delimiter) |
| @@ -711,7 +727,7 @@ int seq_write(struct seq_file *seq, const void *data, size_t len) | |||
| 711 | seq->count += len; | 727 | seq->count += len; |
| 712 | return 0; | 728 | return 0; |
| 713 | } | 729 | } |
| 714 | seq->count = seq->size; | 730 | seq_set_overflow(seq); |
| 715 | return -1; | 731 | return -1; |
| 716 | } | 732 | } |
| 717 | EXPORT_SYMBOL(seq_write); | 733 | EXPORT_SYMBOL(seq_write); |
