Commit d184b31c0e403580aafb3f8955ecc185a3d04801
Committed by
Steven Rostedt
1 parent
a63ce5b306
Exists in
master
and in
4 other branches
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>
Showing 2 changed files with 52 additions and 11 deletions Side-by-side Diff
include/linux/trace_seq.h
kernel/trace/trace_output.c
... | ... | @@ -93,7 +93,7 @@ |
93 | 93 | va_list ap; |
94 | 94 | int ret; |
95 | 95 | |
96 | - if (!len) | |
96 | + if (s->full || !len) | |
97 | 97 | return 0; |
98 | 98 | |
99 | 99 | va_start(ap, fmt); |
100 | 100 | |
... | ... | @@ -101,8 +101,10 @@ |
101 | 101 | va_end(ap); |
102 | 102 | |
103 | 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 | 106 | return 0; |
107 | + } | |
106 | 108 | |
107 | 109 | s->len += ret; |
108 | 110 | |
109 | 111 | |
110 | 112 | |
... | ... | @@ -127,14 +129,16 @@ |
127 | 129 | int len = (PAGE_SIZE - 1) - s->len; |
128 | 130 | int ret; |
129 | 131 | |
130 | - if (!len) | |
132 | + if (s->full || !len) | |
131 | 133 | return 0; |
132 | 134 | |
133 | 135 | ret = vsnprintf(s->buffer + s->len, len, fmt, args); |
134 | 136 | |
135 | 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 | 140 | return 0; |
141 | + } | |
138 | 142 | |
139 | 143 | s->len += ret; |
140 | 144 | |
141 | 145 | |
142 | 146 | |
... | ... | @@ -147,14 +151,16 @@ |
147 | 151 | int len = (PAGE_SIZE - 1) - s->len; |
148 | 152 | int ret; |
149 | 153 | |
150 | - if (!len) | |
154 | + if (s->full || !len) | |
151 | 155 | return 0; |
152 | 156 | |
153 | 157 | ret = bstr_printf(s->buffer + s->len, len, fmt, binary); |
154 | 158 | |
155 | 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 | 162 | return 0; |
163 | + } | |
158 | 164 | |
159 | 165 | s->len += ret; |
160 | 166 | |
161 | 167 | |
... | ... | @@ -175,9 +181,14 @@ |
175 | 181 | { |
176 | 182 | int len = strlen(str); |
177 | 183 | |
178 | - if (len > ((PAGE_SIZE - 1) - s->len)) | |
184 | + if (s->full) | |
179 | 185 | return 0; |
180 | 186 | |
187 | + if (len > ((PAGE_SIZE - 1) - s->len)) { | |
188 | + s->full = 1; | |
189 | + return 0; | |
190 | + } | |
191 | + | |
181 | 192 | memcpy(s->buffer + s->len, str, len); |
182 | 193 | s->len += len; |
183 | 194 | |
184 | 195 | |
... | ... | @@ -186,9 +197,14 @@ |
186 | 197 | |
187 | 198 | int trace_seq_putc(struct trace_seq *s, unsigned char c) |
188 | 199 | { |
189 | - if (s->len >= (PAGE_SIZE - 1)) | |
200 | + if (s->full) | |
190 | 201 | return 0; |
191 | 202 | |
203 | + if (s->len >= (PAGE_SIZE - 1)) { | |
204 | + s->full = 1; | |
205 | + return 0; | |
206 | + } | |
207 | + | |
192 | 208 | s->buffer[s->len++] = c; |
193 | 209 | |
194 | 210 | return 1; |
195 | 211 | |
... | ... | @@ -196,9 +212,14 @@ |
196 | 212 | |
197 | 213 | int 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 | 216 | return 0; |
201 | 217 | |
218 | + if (len > ((PAGE_SIZE - 1) - s->len)) { | |
219 | + s->full = 1; | |
220 | + return 0; | |
221 | + } | |
222 | + | |
202 | 223 | memcpy(s->buffer + s->len, mem, len); |
203 | 224 | s->len += len; |
204 | 225 | |
... | ... | @@ -211,6 +232,9 @@ |
211 | 232 | const unsigned char *data = mem; |
212 | 233 | int i, j; |
213 | 234 | |
235 | + if (s->full) | |
236 | + return 0; | |
237 | + | |
214 | 238 | #ifdef __BIG_ENDIAN |
215 | 239 | for (i = 0, j = 0; i < len; i++) { |
216 | 240 | #else |
217 | 241 | |
... | ... | @@ -228,8 +252,13 @@ |
228 | 252 | { |
229 | 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 | 260 | return NULL; |
261 | + } | |
233 | 262 | |
234 | 263 | ret = s->buffer + s->len; |
235 | 264 | s->len += len; |
236 | 265 | |
... | ... | @@ -241,8 +270,14 @@ |
241 | 270 | { |
242 | 271 | unsigned char *p; |
243 | 272 | |
244 | - if (s->len >= (PAGE_SIZE - 1)) | |
273 | + if (s->full) | |
245 | 274 | return 0; |
275 | + | |
276 | + if (s->len >= (PAGE_SIZE - 1)) { | |
277 | + s->full = 1; | |
278 | + return 0; | |
279 | + } | |
280 | + | |
246 | 281 | p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len); |
247 | 282 | if (!IS_ERR(p)) { |
248 | 283 | p = mangle_path(s->buffer + s->len, p, "\n"); |
... | ... | @@ -255,6 +290,7 @@ |
255 | 290 | return 1; |
256 | 291 | } |
257 | 292 | |
293 | + s->full = 1; | |
258 | 294 | return 0; |
259 | 295 | } |
260 | 296 | |
... | ... | @@ -380,6 +416,9 @@ |
380 | 416 | struct file *file = NULL; |
381 | 417 | unsigned long vmstart = 0; |
382 | 418 | int ret = 1; |
419 | + | |
420 | + if (s->full) | |
421 | + return 0; | |
383 | 422 | |
384 | 423 | if (mm) { |
385 | 424 | const struct vm_area_struct *vma; |