diff options
| author | Li Zefan <lizf@cn.fujitsu.com> | 2009-06-23 21:53:44 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-06-24 05:02:51 -0400 |
| commit | f129e965bef40c6153e4fe505f1e408286213424 (patch) | |
| tree | bd198daa61a79a52e1a6e06ff338c815b1516405 | |
| parent | 2961bf345fd1b736c3db46cad0f69855f67fbe9c (diff) | |
tracing: Reset iterator in t_start()
The iterator is m->private, but it's not reset to trace_types in
t_start(). If the output is larger than PAGE_SIZE and t_start()
is called the 2nd time, things will go wrong.
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A418728.5020506@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/trace/trace.c | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 076fa6f0ee48..3bb31006b5cc 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -2053,25 +2053,23 @@ static int tracing_open(struct inode *inode, struct file *file) | |||
| 2053 | static void * | 2053 | static void * |
| 2054 | t_next(struct seq_file *m, void *v, loff_t *pos) | 2054 | t_next(struct seq_file *m, void *v, loff_t *pos) |
| 2055 | { | 2055 | { |
| 2056 | struct tracer *t = m->private; | 2056 | struct tracer *t = v; |
| 2057 | 2057 | ||
| 2058 | (*pos)++; | 2058 | (*pos)++; |
| 2059 | 2059 | ||
| 2060 | if (t) | 2060 | if (t) |
| 2061 | t = t->next; | 2061 | t = t->next; |
| 2062 | 2062 | ||
| 2063 | m->private = t; | ||
| 2064 | |||
| 2065 | return t; | 2063 | return t; |
| 2066 | } | 2064 | } |
| 2067 | 2065 | ||
| 2068 | static void *t_start(struct seq_file *m, loff_t *pos) | 2066 | static void *t_start(struct seq_file *m, loff_t *pos) |
| 2069 | { | 2067 | { |
| 2070 | struct tracer *t = m->private; | 2068 | struct tracer *t; |
| 2071 | loff_t l = 0; | 2069 | loff_t l = 0; |
| 2072 | 2070 | ||
| 2073 | mutex_lock(&trace_types_lock); | 2071 | mutex_lock(&trace_types_lock); |
| 2074 | for (; t && l < *pos; t = t_next(m, t, &l)) | 2072 | for (t = trace_types; t && l < *pos; t = t_next(m, t, &l)) |
| 2075 | ; | 2073 | ; |
| 2076 | 2074 | ||
| 2077 | return t; | 2075 | return t; |
| @@ -2107,18 +2105,10 @@ static struct seq_operations show_traces_seq_ops = { | |||
| 2107 | 2105 | ||
| 2108 | static int show_traces_open(struct inode *inode, struct file *file) | 2106 | static int show_traces_open(struct inode *inode, struct file *file) |
| 2109 | { | 2107 | { |
| 2110 | int ret; | ||
| 2111 | |||
| 2112 | if (tracing_disabled) | 2108 | if (tracing_disabled) |
| 2113 | return -ENODEV; | 2109 | return -ENODEV; |
| 2114 | 2110 | ||
| 2115 | ret = seq_open(file, &show_traces_seq_ops); | 2111 | return seq_open(file, &show_traces_seq_ops); |
| 2116 | if (!ret) { | ||
| 2117 | struct seq_file *m = file->private_data; | ||
| 2118 | m->private = trace_types; | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | return ret; | ||
| 2122 | } | 2112 | } |
| 2123 | 2113 | ||
| 2124 | static ssize_t | 2114 | static ssize_t |
