diff options
author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2014-06-20 17:38:01 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2014-07-01 07:13:36 -0400 |
commit | 36aabfff50b6a03bcfd2c3cfbd7b83eb0a9ce0c1 (patch) | |
tree | a8e9df6eb61e93288596fcd3e60ba138214118a2 | |
parent | 12306276fabcb746a14979e96f43a13c724dec49 (diff) |
tracing: Clean up trace_seq.c
For using trace_seq_*() functions in NMI context, I posted a patch to move
it to the lib/ directory. This caused Andrew Morton to take a look at the code.
He went through and gave a lot of comments about missing kernel doc,
inconsistent types for the save variable, mix match of EXPORT_SYMBOL_GPL()
and EXPORT_SYMBOL() as well as missing EXPORT_SYMBOL*()s. There were
a few comments about the way variables were being compared (int vs uint).
All these were good review comments and should be implemented regardless of
if trace_seq.c should be moved to lib/ or not.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | include/linux/trace_seq.h | 20 | ||||
-rw-r--r-- | kernel/trace/trace_seq.c | 207 |
2 files changed, 185 insertions, 42 deletions
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 66ea365acf01..1f05317f51c4 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h | |||
@@ -38,14 +38,14 @@ int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args); | |||
38 | extern int | 38 | extern int |
39 | trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); | 39 | trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); |
40 | extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); | 40 | extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); |
41 | extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, | 41 | extern int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, |
42 | size_t cnt); | 42 | int cnt); |
43 | extern int trace_seq_puts(struct trace_seq *s, const char *str); | 43 | extern int trace_seq_puts(struct trace_seq *s, const char *str); |
44 | extern int trace_seq_putc(struct trace_seq *s, unsigned char c); | 44 | extern int trace_seq_putc(struct trace_seq *s, unsigned char c); |
45 | extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len); | 45 | extern int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len); |
46 | extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, | 46 | extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, |
47 | size_t len); | 47 | unsigned int len); |
48 | extern void *trace_seq_reserve(struct trace_seq *s, size_t len); | 48 | extern void *trace_seq_reserve(struct trace_seq *s, unsigned int len); |
49 | extern int trace_seq_path(struct trace_seq *s, const struct path *path); | 49 | extern int trace_seq_path(struct trace_seq *s, const struct path *path); |
50 | 50 | ||
51 | extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, | 51 | extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, |
@@ -73,8 +73,8 @@ static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s) | |||
73 | { | 73 | { |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, | 76 | static inline int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, |
77 | size_t cnt) | 77 | int cnt) |
78 | { | 78 | { |
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
@@ -87,16 +87,16 @@ static inline int trace_seq_putc(struct trace_seq *s, unsigned char c) | |||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | static inline int | 89 | static inline int |
90 | trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) | 90 | trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) |
91 | { | 91 | { |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, | 94 | static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, |
95 | size_t len) | 95 | unsigned int len) |
96 | { | 96 | { |
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | static inline void *trace_seq_reserve(struct trace_seq *s, size_t len) | 99 | static inline void *trace_seq_reserve(struct trace_seq *s, unsigned int len) |
100 | { | 100 | { |
101 | return NULL; | 101 | return NULL; |
102 | } | 102 | } |
diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index 5ba99c6cf834..0fabca773e51 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c | |||
@@ -3,21 +3,55 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> | 4 | * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> |
5 | * | 5 | * |
6 | * The trace_seq is a handy tool that allows you to pass a descriptor around | ||
7 | * to a buffer that other functions can write to. It is similar to the | ||
8 | * seq_file functionality but has some differences. | ||
9 | * | ||
10 | * To use it, the trace_seq must be initialized with trace_seq_init(). | ||
11 | * This will set up the counters within the descriptor. You can call | ||
12 | * trace_seq_init() more than once to reset the trace_seq to start | ||
13 | * from scratch. | ||
14 | * | ||
15 | * The buffer size is currently PAGE_SIZE, although it may become dynamic | ||
16 | * in the future. | ||
17 | * | ||
18 | * A write to the buffer will either succed or fail. That is, unlike | ||
19 | * sprintf() there will not be a partial write (well it may write into | ||
20 | * the buffer but it wont update the pointers). This allows users to | ||
21 | * try to write something into the trace_seq buffer and if it fails | ||
22 | * they can flush it and try again. | ||
23 | * | ||
6 | */ | 24 | */ |
7 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
8 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
9 | #include <linux/trace_seq.h> | 27 | #include <linux/trace_seq.h> |
10 | 28 | ||
29 | /* How much buffer is left on the trace_seq? */ | ||
30 | #define TRACE_SEQ_BUF_LEFT(s) ((PAGE_SIZE - 1) - (s)->len) | ||
31 | |||
32 | /* How much buffer is written? */ | ||
33 | #define TRACE_SEQ_BUF_USED(s) min((s)->len, (unsigned int)(PAGE_SIZE - 1)) | ||
34 | |||
35 | /** | ||
36 | * trace_print_seq - move the contents of trace_seq into a seq_file | ||
37 | * @m: the seq_file descriptor that is the destination | ||
38 | * @s: the trace_seq descriptor that is the source. | ||
39 | * | ||
40 | * Returns 0 on success and non zero on error. If it succeeds to | ||
41 | * write to the seq_file it will reset the trace_seq, otherwise | ||
42 | * it does not modify the trace_seq to let the caller try again. | ||
43 | */ | ||
11 | int trace_print_seq(struct seq_file *m, struct trace_seq *s) | 44 | int trace_print_seq(struct seq_file *m, struct trace_seq *s) |
12 | { | 45 | { |
13 | int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; | 46 | unsigned int len = TRACE_SEQ_BUF_USED(s); |
14 | int ret; | 47 | int ret; |
15 | 48 | ||
16 | ret = seq_write(m, s->buffer, len); | 49 | ret = seq_write(m, s->buffer, len); |
17 | 50 | ||
18 | /* | 51 | /* |
19 | * Only reset this buffer if we successfully wrote to the | 52 | * Only reset this buffer if we successfully wrote to the |
20 | * seq_file buffer. | 53 | * seq_file buffer. This lets the caller try again or |
54 | * do something else with the contents. | ||
21 | */ | 55 | */ |
22 | if (!ret) | 56 | if (!ret) |
23 | trace_seq_init(s); | 57 | trace_seq_init(s); |
@@ -30,19 +64,20 @@ int trace_print_seq(struct seq_file *m, struct trace_seq *s) | |||
30 | * @s: trace sequence descriptor | 64 | * @s: trace sequence descriptor |
31 | * @fmt: printf format string | 65 | * @fmt: printf format string |
32 | * | 66 | * |
33 | * It returns 0 if the trace oversizes the buffer's free | ||
34 | * space, 1 otherwise. | ||
35 | * | ||
36 | * The tracer may use either sequence operations or its own | 67 | * The tracer may use either sequence operations or its own |
37 | * copy to user routines. To simplify formating of a trace | 68 | * copy to user routines. To simplify formating of a trace |
38 | * trace_seq_printf is used to store strings into a special | 69 | * trace_seq_printf() is used to store strings into a special |
39 | * buffer (@s). Then the output may be either used by | 70 | * buffer (@s). Then the output may be either used by |
40 | * the sequencer or pulled into another buffer. | 71 | * the sequencer or pulled into another buffer. |
72 | * | ||
73 | * Returns 1 if we successfully written all the contents to | ||
74 | * the buffer. | ||
75 | * Returns 0 if we the length to write is bigger than the | ||
76 | * reserved buffer space. In this case, nothing gets written. | ||
41 | */ | 77 | */ |
42 | int | 78 | int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) |
43 | trace_seq_printf(struct trace_seq *s, const char *fmt, ...) | ||
44 | { | 79 | { |
45 | int len = (PAGE_SIZE - 1) - s->len; | 80 | unsigned int len = TRACE_SEQ_BUF_LEFT(s); |
46 | va_list ap; | 81 | va_list ap; |
47 | int ret; | 82 | int ret; |
48 | 83 | ||
@@ -66,21 +101,22 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) | |||
66 | EXPORT_SYMBOL_GPL(trace_seq_printf); | 101 | EXPORT_SYMBOL_GPL(trace_seq_printf); |
67 | 102 | ||
68 | /** | 103 | /** |
69 | * trace_seq_bitmask - put a list of longs as a bitmask print output | 104 | * trace_seq_bitmask - write a bitmask array in its ASCII representation |
70 | * @s: trace sequence descriptor | 105 | * @s: trace sequence descriptor |
71 | * @maskp: points to an array of unsigned longs that represent a bitmask | 106 | * @maskp: points to an array of unsigned longs that represent a bitmask |
72 | * @nmaskbits: The number of bits that are valid in @maskp | 107 | * @nmaskbits: The number of bits that are valid in @maskp |
73 | * | 108 | * |
74 | * It returns 0 if the trace oversizes the buffer's free | ||
75 | * space, 1 otherwise. | ||
76 | * | ||
77 | * Writes a ASCII representation of a bitmask string into @s. | 109 | * Writes a ASCII representation of a bitmask string into @s. |
110 | * | ||
111 | * Returns 1 if we successfully written all the contents to | ||
112 | * the buffer. | ||
113 | * Returns 0 if we the length to write is bigger than the | ||
114 | * reserved buffer space. In this case, nothing gets written. | ||
78 | */ | 115 | */ |
79 | int | 116 | int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, |
80 | trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, | 117 | int nmaskbits) |
81 | int nmaskbits) | ||
82 | { | 118 | { |
83 | int len = (PAGE_SIZE - 1) - s->len; | 119 | unsigned int len = TRACE_SEQ_BUF_LEFT(s); |
84 | int ret; | 120 | int ret; |
85 | 121 | ||
86 | if (s->full || !len) | 122 | if (s->full || !len) |
@@ -103,11 +139,12 @@ EXPORT_SYMBOL_GPL(trace_seq_bitmask); | |||
103 | * trace_seq_printf is used to store strings into a special | 139 | * trace_seq_printf is used to store strings into a special |
104 | * buffer (@s). Then the output may be either used by | 140 | * buffer (@s). Then the output may be either used by |
105 | * the sequencer or pulled into another buffer. | 141 | * the sequencer or pulled into another buffer. |
142 | * | ||
143 | * Returns how much it wrote to the buffer. | ||
106 | */ | 144 | */ |
107 | int | 145 | int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) |
108 | trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) | ||
109 | { | 146 | { |
110 | int len = (PAGE_SIZE - 1) - s->len; | 147 | unsigned int len = TRACE_SEQ_BUF_LEFT(s); |
111 | int ret; | 148 | int ret; |
112 | 149 | ||
113 | if (s->full || !len) | 150 | if (s->full || !len) |
@@ -127,9 +164,26 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) | |||
127 | } | 164 | } |
128 | EXPORT_SYMBOL_GPL(trace_seq_vprintf); | 165 | EXPORT_SYMBOL_GPL(trace_seq_vprintf); |
129 | 166 | ||
167 | /** | ||
168 | * trace_seq_bprintf - Write the printf string from binary arguments | ||
169 | * @s: trace sequence descriptor | ||
170 | * @fmt: The format string for the @binary arguments | ||
171 | * @binary: The binary arguments for @fmt. | ||
172 | * | ||
173 | * When recording in a fast path, a printf may be recorded with just | ||
174 | * saving the format and the arguments as they were passed to the | ||
175 | * function, instead of wasting cycles converting the arguments into | ||
176 | * ASCII characters. Instead, the arguments are saved in a 32 bit | ||
177 | * word array that is defined by the format string constraints. | ||
178 | * | ||
179 | * This function will take the format and the binary array and finish | ||
180 | * the conversion into the ASCII string within the buffer. | ||
181 | * | ||
182 | * Returns how much it wrote to the buffer. | ||
183 | */ | ||
130 | int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) | 184 | int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) |
131 | { | 185 | { |
132 | int len = (PAGE_SIZE - 1) - s->len; | 186 | unsigned int len = TRACE_SEQ_BUF_LEFT(s); |
133 | int ret; | 187 | int ret; |
134 | 188 | ||
135 | if (s->full || !len) | 189 | if (s->full || !len) |
@@ -147,6 +201,7 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) | |||
147 | 201 | ||
148 | return len; | 202 | return len; |
149 | } | 203 | } |
204 | EXPORT_SYMBOL_GPL(trace_seq_bprintf); | ||
150 | 205 | ||
151 | /** | 206 | /** |
152 | * trace_seq_puts - trace sequence printing of simple string | 207 | * trace_seq_puts - trace sequence printing of simple string |
@@ -157,15 +212,17 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) | |||
157 | * copy to user routines. This function records a simple string | 212 | * copy to user routines. This function records a simple string |
158 | * into a special buffer (@s) for later retrieval by a sequencer | 213 | * into a special buffer (@s) for later retrieval by a sequencer |
159 | * or other mechanism. | 214 | * or other mechanism. |
215 | * | ||
216 | * Returns how much it wrote to the buffer. | ||
160 | */ | 217 | */ |
161 | int trace_seq_puts(struct trace_seq *s, const char *str) | 218 | int trace_seq_puts(struct trace_seq *s, const char *str) |
162 | { | 219 | { |
163 | int len = strlen(str); | 220 | unsigned int len = strlen(str); |
164 | 221 | ||
165 | if (s->full) | 222 | if (s->full) |
166 | return 0; | 223 | return 0; |
167 | 224 | ||
168 | if (len > ((PAGE_SIZE - 1) - s->len)) { | 225 | if (len > TRACE_SEQ_BUF_LEFT(s)) { |
169 | s->full = 1; | 226 | s->full = 1; |
170 | return 0; | 227 | return 0; |
171 | } | 228 | } |
@@ -175,13 +232,26 @@ int trace_seq_puts(struct trace_seq *s, const char *str) | |||
175 | 232 | ||
176 | return len; | 233 | return len; |
177 | } | 234 | } |
235 | EXPORT_SYMBOL_GPL(trace_seq_puts); | ||
178 | 236 | ||
237 | /** | ||
238 | * trace_seq_putc - trace sequence printing of simple character | ||
239 | * @s: trace sequence descriptor | ||
240 | * @c: simple character to record | ||
241 | * | ||
242 | * The tracer may use either the sequence operations or its own | ||
243 | * copy to user routines. This function records a simple charater | ||
244 | * into a special buffer (@s) for later retrieval by a sequencer | ||
245 | * or other mechanism. | ||
246 | * | ||
247 | * Returns how much it wrote to the buffer. | ||
248 | */ | ||
179 | int trace_seq_putc(struct trace_seq *s, unsigned char c) | 249 | int trace_seq_putc(struct trace_seq *s, unsigned char c) |
180 | { | 250 | { |
181 | if (s->full) | 251 | if (s->full) |
182 | return 0; | 252 | return 0; |
183 | 253 | ||
184 | if (s->len >= (PAGE_SIZE - 1)) { | 254 | if (TRACE_SEQ_BUF_LEFT(s) < 1) { |
185 | s->full = 1; | 255 | s->full = 1; |
186 | return 0; | 256 | return 0; |
187 | } | 257 | } |
@@ -190,14 +260,26 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c) | |||
190 | 260 | ||
191 | return 1; | 261 | return 1; |
192 | } | 262 | } |
193 | EXPORT_SYMBOL(trace_seq_putc); | 263 | EXPORT_SYMBOL_GPL(trace_seq_putc); |
194 | 264 | ||
195 | int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) | 265 | /** |
266 | * trace_seq_putmem - write raw data into the trace_seq buffer | ||
267 | * @s: trace sequence descriptor | ||
268 | * @mem: The raw memory to copy into the buffer | ||
269 | * @len: The length of the raw memory to copy (in bytes) | ||
270 | * | ||
271 | * There may be cases where raw memory needs to be written into the | ||
272 | * buffer and a strcpy() would not work. Using this function allows | ||
273 | * for such cases. | ||
274 | * | ||
275 | * Returns how much it wrote to the buffer. | ||
276 | */ | ||
277 | int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) | ||
196 | { | 278 | { |
197 | if (s->full) | 279 | if (s->full) |
198 | return 0; | 280 | return 0; |
199 | 281 | ||
200 | if (len > ((PAGE_SIZE - 1) - s->len)) { | 282 | if (len > TRACE_SEQ_BUF_LEFT(s)) { |
201 | s->full = 1; | 283 | s->full = 1; |
202 | return 0; | 284 | return 0; |
203 | } | 285 | } |
@@ -207,10 +289,24 @@ int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) | |||
207 | 289 | ||
208 | return len; | 290 | return len; |
209 | } | 291 | } |
292 | EXPORT_SYMBOL_GPL(trace_seq_putmem); | ||
210 | 293 | ||
211 | #define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) | 294 | #define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) |
212 | 295 | ||
213 | int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len) | 296 | /** |
297 | * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex | ||
298 | * @s: trace sequence descriptor | ||
299 | * @mem: The raw memory to write its hex ASCII representation of | ||
300 | * @len: The length of the raw memory to copy (in bytes) | ||
301 | * | ||
302 | * This is similar to trace_seq_putmem() except instead of just copying the | ||
303 | * raw memory into the buffer it writes its ASCII representation of it | ||
304 | * in hex characters. | ||
305 | * | ||
306 | * Returns how much it wrote to the buffer. | ||
307 | */ | ||
308 | int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, | ||
309 | unsigned int len) | ||
214 | { | 310 | { |
215 | unsigned char hex[HEX_CHARS]; | 311 | unsigned char hex[HEX_CHARS]; |
216 | const unsigned char *data = mem; | 312 | const unsigned char *data = mem; |
@@ -231,15 +327,27 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len) | |||
231 | 327 | ||
232 | return trace_seq_putmem(s, hex, j); | 328 | return trace_seq_putmem(s, hex, j); |
233 | } | 329 | } |
330 | EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); | ||
234 | 331 | ||
235 | void *trace_seq_reserve(struct trace_seq *s, size_t len) | 332 | /** |
333 | * trace_seq_reserve - reserve space on the sequence buffer | ||
334 | * @s: trace sequence descriptor | ||
335 | * @len: The amount to reserver. | ||
336 | * | ||
337 | * If for some reason there is a need to save some space on the | ||
338 | * buffer to fill in later, this function is used for that purpose. | ||
339 | * The given length will be reserved and the pointer to that | ||
340 | * location on the buffer is returned, unless there is not enough | ||
341 | * buffer left to hold the given length then NULL is returned. | ||
342 | */ | ||
343 | void *trace_seq_reserve(struct trace_seq *s, unsigned int len) | ||
236 | { | 344 | { |
237 | void *ret; | 345 | void *ret; |
238 | 346 | ||
239 | if (s->full) | 347 | if (s->full) |
240 | return NULL; | 348 | return NULL; |
241 | 349 | ||
242 | if (len > ((PAGE_SIZE - 1) - s->len)) { | 350 | if (len > TRACE_SEQ_BUF_LEFT(s)) { |
243 | s->full = 1; | 351 | s->full = 1; |
244 | return NULL; | 352 | return NULL; |
245 | } | 353 | } |
@@ -249,7 +357,20 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len) | |||
249 | 357 | ||
250 | return ret; | 358 | return ret; |
251 | } | 359 | } |
360 | EXPORT_SYMBOL_GPL(trace_seq_reserve); | ||
252 | 361 | ||
362 | /** | ||
363 | * trace_seq_path - copy a path into the sequence buffer | ||
364 | * @s: trace sequence descriptor | ||
365 | * @path: path to write into the sequence buffer. | ||
366 | * | ||
367 | * Write a path name into the sequence buffer. | ||
368 | * | ||
369 | * Returns 1 if we successfully written all the contents to | ||
370 | * the buffer. | ||
371 | * Returns 0 if we the length to write is bigger than the | ||
372 | * reserved buffer space. In this case, nothing gets written. | ||
373 | */ | ||
253 | int trace_seq_path(struct trace_seq *s, const struct path *path) | 374 | int trace_seq_path(struct trace_seq *s, const struct path *path) |
254 | { | 375 | { |
255 | unsigned char *p; | 376 | unsigned char *p; |
@@ -257,7 +378,7 @@ int trace_seq_path(struct trace_seq *s, const struct path *path) | |||
257 | if (s->full) | 378 | if (s->full) |
258 | return 0; | 379 | return 0; |
259 | 380 | ||
260 | if (s->len >= (PAGE_SIZE - 1)) { | 381 | if (TRACE_SEQ_BUF_LEFT(s) < 1) { |
261 | s->full = 1; | 382 | s->full = 1; |
262 | return 0; | 383 | return 0; |
263 | } | 384 | } |
@@ -277,8 +398,29 @@ int trace_seq_path(struct trace_seq *s, const struct path *path) | |||
277 | s->full = 1; | 398 | s->full = 1; |
278 | return 0; | 399 | return 0; |
279 | } | 400 | } |
401 | EXPORT_SYMBOL_GPL(trace_seq_path); | ||
280 | 402 | ||
281 | ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) | 403 | /** |
404 | * trace_seq_to_user - copy the squence buffer to user space | ||
405 | * @s: trace sequence descriptor | ||
406 | * @ubuf: The userspace memory location to copy to | ||
407 | * @cnt: The amount to copy | ||
408 | * | ||
409 | * Copies the sequence buffer into the userspace memory pointed to | ||
410 | * by @ubuf. It starts from the last read position (@s->readpos) | ||
411 | * and writes up to @cnt characters or till it reaches the end of | ||
412 | * the content in the buffer (@s->len), which ever comes first. | ||
413 | * | ||
414 | * On success, it returns a positive number of the number of bytes | ||
415 | * it copied. | ||
416 | * | ||
417 | * On failure it returns -EBUSY if all of the content in the | ||
418 | * sequence has been already read, which includes nothing in the | ||
419 | * sequenc (@s->len == @s->readpos). | ||
420 | * | ||
421 | * Returns -EFAULT if the copy to userspace fails. | ||
422 | */ | ||
423 | int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt) | ||
282 | { | 424 | { |
283 | int len; | 425 | int len; |
284 | int ret; | 426 | int ret; |
@@ -301,3 +443,4 @@ ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) | |||
301 | s->readpos += cnt; | 443 | s->readpos += cnt; |
302 | return cnt; | 444 | return cnt; |
303 | } | 445 | } |
446 | EXPORT_SYMBOL_GPL(trace_seq_to_user); | ||