aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-25 10:10:14 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-09 14:05:49 -0500
commitd184b31c0e403580aafb3f8955ecc185a3d04801 (patch)
treeca3fc8371382ce8dbe43eb684313847b7555573e /kernel
parenta63ce5b306855bccdacba95c03bfc293316c8ae3 (diff)
tracing: Add full state to trace_seq
The trace_seq buffer might fill up, and right now one needs to check the return value of each printf into the buffer to check for that. Instead, have the buffer keep track of whether it is full or not, and reject more input if it is full or would have overflowed with an input that wasn't added. Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_output.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index e5cf90fef34e..8e46b3323cdc 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -93,7 +93,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
93 va_list ap; 93 va_list ap;
94 int ret; 94 int ret;
95 95
96 if (!len) 96 if (s->full || !len)
97 return 0; 97 return 0;
98 98
99 va_start(ap, fmt); 99 va_start(ap, fmt);
@@ -101,8 +101,10 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
101 va_end(ap); 101 va_end(ap);
102 102
103 /* If we can't write it all, don't bother writing anything */ 103 /* If we can't write it all, don't bother writing anything */
104 if (ret >= len) 104 if (ret >= len) {
105 s->full = 1;
105 return 0; 106 return 0;
107 }
106 108
107 s->len += ret; 109 s->len += ret;
108 110
@@ -127,14 +129,16 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
127 int len = (PAGE_SIZE - 1) - s->len; 129 int len = (PAGE_SIZE - 1) - s->len;
128 int ret; 130 int ret;
129 131
130 if (!len) 132 if (s->full || !len)
131 return 0; 133 return 0;
132 134
133 ret = vsnprintf(s->buffer + s->len, len, fmt, args); 135 ret = vsnprintf(s->buffer + s->len, len, fmt, args);
134 136
135 /* If we can't write it all, don't bother writing anything */ 137 /* If we can't write it all, don't bother writing anything */
136 if (ret >= len) 138 if (ret >= len) {
139 s->full = 1;
137 return 0; 140 return 0;
141 }
138 142
139 s->len += ret; 143 s->len += ret;
140 144
@@ -147,14 +151,16 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
147 int len = (PAGE_SIZE - 1) - s->len; 151 int len = (PAGE_SIZE - 1) - s->len;
148 int ret; 152 int ret;
149 153
150 if (!len) 154 if (s->full || !len)
151 return 0; 155 return 0;
152 156
153 ret = bstr_printf(s->buffer + s->len, len, fmt, binary); 157 ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
154 158
155 /* If we can't write it all, don't bother writing anything */ 159 /* If we can't write it all, don't bother writing anything */
156 if (ret >= len) 160 if (ret >= len) {
161 s->full = 1;
157 return 0; 162 return 0;
163 }
158 164
159 s->len += ret; 165 s->len += ret;
160 166
@@ -175,9 +181,14 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
175{ 181{
176 int len = strlen(str); 182 int len = strlen(str);
177 183
178 if (len > ((PAGE_SIZE - 1) - s->len)) 184 if (s->full)
179 return 0; 185 return 0;
180 186
187 if (len > ((PAGE_SIZE - 1) - s->len)) {
188 s->full = 1;
189 return 0;
190 }
191
181 memcpy(s->buffer + s->len, str, len); 192 memcpy(s->buffer + s->len, str, len);
182 s->len += len; 193 s->len += len;
183 194
@@ -186,9 +197,14 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
186 197
187int trace_seq_putc(struct trace_seq *s, unsigned char c) 198int trace_seq_putc(struct trace_seq *s, unsigned char c)
188{ 199{
189 if (s->len >= (PAGE_SIZE - 1)) 200 if (s->full)
190 return 0; 201 return 0;
191 202
203 if (s->len >= (PAGE_SIZE - 1)) {
204 s->full = 1;
205 return 0;
206 }
207
192 s->buffer[s->len++] = c; 208 s->buffer[s->len++] = c;
193 209
194 return 1; 210 return 1;
@@ -196,9 +212,14 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)
196 212
197int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) 213int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
198{ 214{
199 if (len > ((PAGE_SIZE - 1) - s->len)) 215 if (s->full)
200 return 0; 216 return 0;
201 217
218 if (len > ((PAGE_SIZE - 1) - s->len)) {
219 s->full = 1;
220 return 0;
221 }
222
202 memcpy(s->buffer + s->len, mem, len); 223 memcpy(s->buffer + s->len, mem, len);
203 s->len += len; 224 s->len += len;
204 225
@@ -211,6 +232,9 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
211 const unsigned char *data = mem; 232 const unsigned char *data = mem;
212 int i, j; 233 int i, j;
213 234
235 if (s->full)
236 return 0;
237
214#ifdef __BIG_ENDIAN 238#ifdef __BIG_ENDIAN
215 for (i = 0, j = 0; i < len; i++) { 239 for (i = 0, j = 0; i < len; i++) {
216#else 240#else
@@ -228,8 +252,13 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len)
228{ 252{
229 void *ret; 253 void *ret;
230 254
231 if (len > ((PAGE_SIZE - 1) - s->len)) 255 if (s->full)
256 return 0;
257
258 if (len > ((PAGE_SIZE - 1) - s->len)) {
259 s->full = 1;
232 return NULL; 260 return NULL;
261 }
233 262
234 ret = s->buffer + s->len; 263 ret = s->buffer + s->len;
235 s->len += len; 264 s->len += len;
@@ -241,8 +270,14 @@ int trace_seq_path(struct trace_seq *s, struct path *path)
241{ 270{
242 unsigned char *p; 271 unsigned char *p;
243 272
244 if (s->len >= (PAGE_SIZE - 1)) 273 if (s->full)
245 return 0; 274 return 0;
275
276 if (s->len >= (PAGE_SIZE - 1)) {
277 s->full = 1;
278 return 0;
279 }
280
246 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len); 281 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
247 if (!IS_ERR(p)) { 282 if (!IS_ERR(p)) {
248 p = mangle_path(s->buffer + s->len, p, "\n"); 283 p = mangle_path(s->buffer + s->len, p, "\n");
@@ -255,6 +290,7 @@ int trace_seq_path(struct trace_seq *s, struct path *path)
255 return 1; 290 return 1;
256 } 291 }
257 292
293 s->full = 1;
258 return 0; 294 return 0;
259} 295}
260 296
@@ -381,6 +417,9 @@ int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
381 unsigned long vmstart = 0; 417 unsigned long vmstart = 0;
382 int ret = 1; 418 int ret = 1;
383 419
420 if (s->full)
421 return 0;
422
384 if (mm) { 423 if (mm) {
385 const struct vm_area_struct *vma; 424 const struct vm_area_struct *vma;
386 425