Commit 8d58e99af5980d444948720977b0976455885391

Authored by Steven Rostedt (Red Hat)
Committed by Steven Rostedt
1 parent 2448913ed2

seq_buf: Move the seq_buf code to lib/

The seq_buf functions are rather useful outside of tracing. Instead
of having it be dependent on CONFIG_TRACING, move the code into lib/
and allow other users to have access to it even when tracing is not
configured.

The seq_buf utility is similar to the seq_file utility, but instead of
writing sending data back up to userland, it writes it into a buffer
defined at seq_buf_init(). This allows us to send a descriptor around
that writes printf() formatted strings into it that can be retrieved
later.

It is currently used by the tracing facility for such things like trace
events to convert its binary saved data in the ring buffer into an
ASCII human readable context to be displayed in /sys/kernel/debug/trace.

It can also be used for doing NMI prints safely from NMI context into
the seq_buf and retrieved later and dumped to printk() safely. Doing
printk() from an NMI context is dangerous because an NMI can preempt
a current printk() and deadlock on it.

Link: http://lkml.kernel.org/p/20140619213952.058255809@goodmis.org

Tested-by: Jiri Kosina <jkosina@suse.cz>
Acked-by: Jiri Kosina <jkosina@suse.cz>
Reviewed-by: Petr Mladek <pmladek@suse.cz>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

Showing 4 changed files with 360 additions and 361 deletions Side-by-side Diff

kernel/trace/Makefile
... ... @@ -29,7 +29,6 @@
29 29 obj-$(CONFIG_TRACING) += trace.o
30 30 obj-$(CONFIG_TRACING) += trace_output.o
31 31 obj-$(CONFIG_TRACING) += trace_seq.o
32   -obj-$(CONFIG_TRACING) += seq_buf.o
33 32 obj-$(CONFIG_TRACING) += trace_stat.o
34 33 obj-$(CONFIG_TRACING) += trace_printk.o
35 34 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
kernel/trace/seq_buf.c
1   -/*
2   - * seq_buf.c
3   - *
4   - * Copyright (C) 2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5   - *
6   - * The seq_buf 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 seq_buf must be initialized with seq_buf_init().
11   - * This will set up the counters within the descriptor. You can call
12   - * seq_buf_init() more than once to reset the seq_buf to start
13   - * from scratch.
14   - */
15   -#include <linux/uaccess.h>
16   -#include <linux/seq_file.h>
17   -#include <linux/seq_buf.h>
18   -
19   -/**
20   - * seq_buf_can_fit - can the new data fit in the current buffer?
21   - * @s: the seq_buf descriptor
22   - * @len: The length to see if it can fit in the current buffer
23   - *
24   - * Returns true if there's enough unused space in the seq_buf buffer
25   - * to fit the amount of new data according to @len.
26   - */
27   -static bool seq_buf_can_fit(struct seq_buf *s, size_t len)
28   -{
29   - return s->len + len <= s->size;
30   -}
31   -
32   -/**
33   - * seq_buf_print_seq - move the contents of seq_buf into a seq_file
34   - * @m: the seq_file descriptor that is the destination
35   - * @s: the seq_buf descriptor that is the source.
36   - *
37   - * Returns zero on success, non zero otherwise
38   - */
39   -int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s)
40   -{
41   - unsigned int len = seq_buf_used(s);
42   -
43   - return seq_write(m, s->buffer, len);
44   -}
45   -
46   -/**
47   - * seq_buf_vprintf - sequence printing of information.
48   - * @s: seq_buf descriptor
49   - * @fmt: printf format string
50   - * @args: va_list of arguments from a printf() type function
51   - *
52   - * Writes a vnprintf() format into the sequencce buffer.
53   - *
54   - * Returns zero on success, -1 on overflow.
55   - */
56   -int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args)
57   -{
58   - int len;
59   -
60   - WARN_ON(s->size == 0);
61   -
62   - if (s->len < s->size) {
63   - len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args);
64   - if (seq_buf_can_fit(s, len)) {
65   - s->len += len;
66   - return 0;
67   - }
68   - }
69   - seq_buf_set_overflow(s);
70   - return -1;
71   -}
72   -
73   -/**
74   - * seq_buf_printf - sequence printing of information
75   - * @s: seq_buf descriptor
76   - * @fmt: printf format string
77   - *
78   - * Writes a printf() format into the sequence buffer.
79   - *
80   - * Returns zero on success, -1 on overflow.
81   - */
82   -int seq_buf_printf(struct seq_buf *s, const char *fmt, ...)
83   -{
84   - va_list ap;
85   - int ret;
86   -
87   - va_start(ap, fmt);
88   - ret = seq_buf_vprintf(s, fmt, ap);
89   - va_end(ap);
90   -
91   - return ret;
92   -}
93   -
94   -/**
95   - * seq_buf_bitmask - write a bitmask array in its ASCII representation
96   - * @s: seq_buf descriptor
97   - * @maskp: points to an array of unsigned longs that represent a bitmask
98   - * @nmaskbits: The number of bits that are valid in @maskp
99   - *
100   - * Writes a ASCII representation of a bitmask string into @s.
101   - *
102   - * Returns zero on success, -1 on overflow.
103   - */
104   -int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp,
105   - int nmaskbits)
106   -{
107   - unsigned int len = seq_buf_buffer_left(s);
108   - int ret;
109   -
110   - WARN_ON(s->size == 0);
111   -
112   - /*
113   - * Note, because bitmap_scnprintf() only returns the number of bytes
114   - * written and not the number that would be written, we use the last
115   - * byte of the buffer to let us know if we overflowed. There's a small
116   - * chance that the bitmap could have fit exactly inside the buffer, but
117   - * it's not that critical if that does happen.
118   - */
119   - if (len > 1) {
120   - ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits);
121   - if (ret < len) {
122   - s->len += ret;
123   - return 0;
124   - }
125   - }
126   - seq_buf_set_overflow(s);
127   - return -1;
128   -}
129   -
130   -#ifdef CONFIG_BINARY_PRINTF
131   -/**
132   - * seq_buf_bprintf - Write the printf string from binary arguments
133   - * @s: seq_buf descriptor
134   - * @fmt: The format string for the @binary arguments
135   - * @binary: The binary arguments for @fmt.
136   - *
137   - * When recording in a fast path, a printf may be recorded with just
138   - * saving the format and the arguments as they were passed to the
139   - * function, instead of wasting cycles converting the arguments into
140   - * ASCII characters. Instead, the arguments are saved in a 32 bit
141   - * word array that is defined by the format string constraints.
142   - *
143   - * This function will take the format and the binary array and finish
144   - * the conversion into the ASCII string within the buffer.
145   - *
146   - * Returns zero on success, -1 on overflow.
147   - */
148   -int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary)
149   -{
150   - unsigned int len = seq_buf_buffer_left(s);
151   - int ret;
152   -
153   - WARN_ON(s->size == 0);
154   -
155   - if (s->len < s->size) {
156   - ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
157   - if (seq_buf_can_fit(s, ret)) {
158   - s->len += ret;
159   - return 0;
160   - }
161   - }
162   - seq_buf_set_overflow(s);
163   - return -1;
164   -}
165   -#endif /* CONFIG_BINARY_PRINTF */
166   -
167   -/**
168   - * seq_buf_puts - sequence printing of simple string
169   - * @s: seq_buf descriptor
170   - * @str: simple string to record
171   - *
172   - * Copy a simple string into the sequence buffer.
173   - *
174   - * Returns zero on success, -1 on overflow
175   - */
176   -int seq_buf_puts(struct seq_buf *s, const char *str)
177   -{
178   - unsigned int len = strlen(str);
179   -
180   - WARN_ON(s->size == 0);
181   -
182   - if (seq_buf_can_fit(s, len)) {
183   - memcpy(s->buffer + s->len, str, len);
184   - s->len += len;
185   - return 0;
186   - }
187   - seq_buf_set_overflow(s);
188   - return -1;
189   -}
190   -
191   -/**
192   - * seq_buf_putc - sequence printing of simple character
193   - * @s: seq_buf descriptor
194   - * @c: simple character to record
195   - *
196   - * Copy a single character into the sequence buffer.
197   - *
198   - * Returns zero on success, -1 on overflow
199   - */
200   -int seq_buf_putc(struct seq_buf *s, unsigned char c)
201   -{
202   - WARN_ON(s->size == 0);
203   -
204   - if (seq_buf_can_fit(s, 1)) {
205   - s->buffer[s->len++] = c;
206   - return 0;
207   - }
208   - seq_buf_set_overflow(s);
209   - return -1;
210   -}
211   -
212   -/**
213   - * seq_buf_putmem - write raw data into the sequenc buffer
214   - * @s: seq_buf descriptor
215   - * @mem: The raw memory to copy into the buffer
216   - * @len: The length of the raw memory to copy (in bytes)
217   - *
218   - * There may be cases where raw memory needs to be written into the
219   - * buffer and a strcpy() would not work. Using this function allows
220   - * for such cases.
221   - *
222   - * Returns zero on success, -1 on overflow
223   - */
224   -int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len)
225   -{
226   - WARN_ON(s->size == 0);
227   -
228   - if (seq_buf_can_fit(s, len)) {
229   - memcpy(s->buffer + s->len, mem, len);
230   - s->len += len;
231   - return 0;
232   - }
233   - seq_buf_set_overflow(s);
234   - return -1;
235   -}
236   -
237   -#define MAX_MEMHEX_BYTES 8U
238   -#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
239   -
240   -/**
241   - * seq_buf_putmem_hex - write raw memory into the buffer in ASCII hex
242   - * @s: seq_buf descriptor
243   - * @mem: The raw memory to write its hex ASCII representation of
244   - * @len: The length of the raw memory to copy (in bytes)
245   - *
246   - * This is similar to seq_buf_putmem() except instead of just copying the
247   - * raw memory into the buffer it writes its ASCII representation of it
248   - * in hex characters.
249   - *
250   - * Returns zero on success, -1 on overflow
251   - */
252   -int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
253   - unsigned int len)
254   -{
255   - unsigned char hex[HEX_CHARS];
256   - const unsigned char *data = mem;
257   - unsigned int start_len;
258   - int i, j;
259   -
260   - WARN_ON(s->size == 0);
261   -
262   - while (len) {
263   - start_len = min(len, HEX_CHARS - 1);
264   -#ifdef __BIG_ENDIAN
265   - for (i = 0, j = 0; i < start_len; i++) {
266   -#else
267   - for (i = start_len-1, j = 0; i >= 0; i--) {
268   -#endif
269   - hex[j++] = hex_asc_hi(data[i]);
270   - hex[j++] = hex_asc_lo(data[i]);
271   - }
272   - if (WARN_ON_ONCE(j == 0 || j/2 > len))
273   - break;
274   -
275   - /* j increments twice per loop */
276   - len -= j / 2;
277   - hex[j++] = ' ';
278   -
279   - seq_buf_putmem(s, hex, j);
280   - if (seq_buf_has_overflowed(s))
281   - return -1;
282   - }
283   - return 0;
284   -}
285   -
286   -/**
287   - * seq_buf_path - copy a path into the sequence buffer
288   - * @s: seq_buf descriptor
289   - * @path: path to write into the sequence buffer.
290   - * @esc: set of characters to escape in the output
291   - *
292   - * Write a path name into the sequence buffer.
293   - *
294   - * Returns the number of written bytes on success, -1 on overflow
295   - */
296   -int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc)
297   -{
298   - char *buf;
299   - size_t size = seq_buf_get_buf(s, &buf);
300   - int res = -1;
301   -
302   - WARN_ON(s->size == 0);
303   -
304   - if (size) {
305   - char *p = d_path(path, buf, size);
306   - if (!IS_ERR(p)) {
307   - char *end = mangle_path(buf, p, esc);
308   - if (end)
309   - res = end - buf;
310   - }
311   - }
312   - seq_buf_commit(s, res);
313   -
314   - return res;
315   -}
316   -
317   -/**
318   - * seq_buf_to_user - copy the squence buffer to user space
319   - * @s: seq_buf descriptor
320   - * @ubuf: The userspace memory location to copy to
321   - * @cnt: The amount to copy
322   - *
323   - * Copies the sequence buffer into the userspace memory pointed to
324   - * by @ubuf. It starts from the last read position (@s->readpos)
325   - * and writes up to @cnt characters or till it reaches the end of
326   - * the content in the buffer (@s->len), which ever comes first.
327   - *
328   - * On success, it returns a positive number of the number of bytes
329   - * it copied.
330   - *
331   - * On failure it returns -EBUSY if all of the content in the
332   - * sequence has been already read, which includes nothing in the
333   - * sequence (@s->len == @s->readpos).
334   - *
335   - * Returns -EFAULT if the copy to userspace fails.
336   - */
337   -int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt)
338   -{
339   - int len;
340   - int ret;
341   -
342   - if (!cnt)
343   - return 0;
344   -
345   - if (s->len <= s->readpos)
346   - return -EBUSY;
347   -
348   - len = seq_buf_used(s) - s->readpos;
349   - if (cnt > len)
350   - cnt = len;
351   - ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
352   - if (ret == cnt)
353   - return -EFAULT;
354   -
355   - cnt -= ret;
356   -
357   - s->readpos += cnt;
358   - return cnt;
359   -}
... ... @@ -13,7 +13,7 @@
13 13 sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
14 14 proportions.o flex_proportions.o ratelimit.o show_mem.o \
15 15 is_single_threaded.o plist.o decompress.o kobject_uevent.o \
16   - earlycpio.o
  16 + earlycpio.o seq_buf.o
17 17  
18 18 obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
19 19 lib-$(CONFIG_MMU) += ioremap.o
  1 +/*
  2 + * seq_buf.c
  3 + *
  4 + * Copyright (C) 2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  5 + *
  6 + * The seq_buf 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 seq_buf must be initialized with seq_buf_init().
  11 + * This will set up the counters within the descriptor. You can call
  12 + * seq_buf_init() more than once to reset the seq_buf to start
  13 + * from scratch.
  14 + */
  15 +#include <linux/uaccess.h>
  16 +#include <linux/seq_file.h>
  17 +#include <linux/seq_buf.h>
  18 +
  19 +/**
  20 + * seq_buf_can_fit - can the new data fit in the current buffer?
  21 + * @s: the seq_buf descriptor
  22 + * @len: The length to see if it can fit in the current buffer
  23 + *
  24 + * Returns true if there's enough unused space in the seq_buf buffer
  25 + * to fit the amount of new data according to @len.
  26 + */
  27 +static bool seq_buf_can_fit(struct seq_buf *s, size_t len)
  28 +{
  29 + return s->len + len <= s->size;
  30 +}
  31 +
  32 +/**
  33 + * seq_buf_print_seq - move the contents of seq_buf into a seq_file
  34 + * @m: the seq_file descriptor that is the destination
  35 + * @s: the seq_buf descriptor that is the source.
  36 + *
  37 + * Returns zero on success, non zero otherwise
  38 + */
  39 +int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s)
  40 +{
  41 + unsigned int len = seq_buf_used(s);
  42 +
  43 + return seq_write(m, s->buffer, len);
  44 +}
  45 +
  46 +/**
  47 + * seq_buf_vprintf - sequence printing of information.
  48 + * @s: seq_buf descriptor
  49 + * @fmt: printf format string
  50 + * @args: va_list of arguments from a printf() type function
  51 + *
  52 + * Writes a vnprintf() format into the sequencce buffer.
  53 + *
  54 + * Returns zero on success, -1 on overflow.
  55 + */
  56 +int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args)
  57 +{
  58 + int len;
  59 +
  60 + WARN_ON(s->size == 0);
  61 +
  62 + if (s->len < s->size) {
  63 + len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args);
  64 + if (seq_buf_can_fit(s, len)) {
  65 + s->len += len;
  66 + return 0;
  67 + }
  68 + }
  69 + seq_buf_set_overflow(s);
  70 + return -1;
  71 +}
  72 +
  73 +/**
  74 + * seq_buf_printf - sequence printing of information
  75 + * @s: seq_buf descriptor
  76 + * @fmt: printf format string
  77 + *
  78 + * Writes a printf() format into the sequence buffer.
  79 + *
  80 + * Returns zero on success, -1 on overflow.
  81 + */
  82 +int seq_buf_printf(struct seq_buf *s, const char *fmt, ...)
  83 +{
  84 + va_list ap;
  85 + int ret;
  86 +
  87 + va_start(ap, fmt);
  88 + ret = seq_buf_vprintf(s, fmt, ap);
  89 + va_end(ap);
  90 +
  91 + return ret;
  92 +}
  93 +
  94 +/**
  95 + * seq_buf_bitmask - write a bitmask array in its ASCII representation
  96 + * @s: seq_buf descriptor
  97 + * @maskp: points to an array of unsigned longs that represent a bitmask
  98 + * @nmaskbits: The number of bits that are valid in @maskp
  99 + *
  100 + * Writes a ASCII representation of a bitmask string into @s.
  101 + *
  102 + * Returns zero on success, -1 on overflow.
  103 + */
  104 +int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp,
  105 + int nmaskbits)
  106 +{
  107 + unsigned int len = seq_buf_buffer_left(s);
  108 + int ret;
  109 +
  110 + WARN_ON(s->size == 0);
  111 +
  112 + /*
  113 + * Note, because bitmap_scnprintf() only returns the number of bytes
  114 + * written and not the number that would be written, we use the last
  115 + * byte of the buffer to let us know if we overflowed. There's a small
  116 + * chance that the bitmap could have fit exactly inside the buffer, but
  117 + * it's not that critical if that does happen.
  118 + */
  119 + if (len > 1) {
  120 + ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits);
  121 + if (ret < len) {
  122 + s->len += ret;
  123 + return 0;
  124 + }
  125 + }
  126 + seq_buf_set_overflow(s);
  127 + return -1;
  128 +}
  129 +
  130 +#ifdef CONFIG_BINARY_PRINTF
  131 +/**
  132 + * seq_buf_bprintf - Write the printf string from binary arguments
  133 + * @s: seq_buf descriptor
  134 + * @fmt: The format string for the @binary arguments
  135 + * @binary: The binary arguments for @fmt.
  136 + *
  137 + * When recording in a fast path, a printf may be recorded with just
  138 + * saving the format and the arguments as they were passed to the
  139 + * function, instead of wasting cycles converting the arguments into
  140 + * ASCII characters. Instead, the arguments are saved in a 32 bit
  141 + * word array that is defined by the format string constraints.
  142 + *
  143 + * This function will take the format and the binary array and finish
  144 + * the conversion into the ASCII string within the buffer.
  145 + *
  146 + * Returns zero on success, -1 on overflow.
  147 + */
  148 +int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary)
  149 +{
  150 + unsigned int len = seq_buf_buffer_left(s);
  151 + int ret;
  152 +
  153 + WARN_ON(s->size == 0);
  154 +
  155 + if (s->len < s->size) {
  156 + ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
  157 + if (seq_buf_can_fit(s, ret)) {
  158 + s->len += ret;
  159 + return 0;
  160 + }
  161 + }
  162 + seq_buf_set_overflow(s);
  163 + return -1;
  164 +}
  165 +#endif /* CONFIG_BINARY_PRINTF */
  166 +
  167 +/**
  168 + * seq_buf_puts - sequence printing of simple string
  169 + * @s: seq_buf descriptor
  170 + * @str: simple string to record
  171 + *
  172 + * Copy a simple string into the sequence buffer.
  173 + *
  174 + * Returns zero on success, -1 on overflow
  175 + */
  176 +int seq_buf_puts(struct seq_buf *s, const char *str)
  177 +{
  178 + unsigned int len = strlen(str);
  179 +
  180 + WARN_ON(s->size == 0);
  181 +
  182 + if (seq_buf_can_fit(s, len)) {
  183 + memcpy(s->buffer + s->len, str, len);
  184 + s->len += len;
  185 + return 0;
  186 + }
  187 + seq_buf_set_overflow(s);
  188 + return -1;
  189 +}
  190 +
  191 +/**
  192 + * seq_buf_putc - sequence printing of simple character
  193 + * @s: seq_buf descriptor
  194 + * @c: simple character to record
  195 + *
  196 + * Copy a single character into the sequence buffer.
  197 + *
  198 + * Returns zero on success, -1 on overflow
  199 + */
  200 +int seq_buf_putc(struct seq_buf *s, unsigned char c)
  201 +{
  202 + WARN_ON(s->size == 0);
  203 +
  204 + if (seq_buf_can_fit(s, 1)) {
  205 + s->buffer[s->len++] = c;
  206 + return 0;
  207 + }
  208 + seq_buf_set_overflow(s);
  209 + return -1;
  210 +}
  211 +
  212 +/**
  213 + * seq_buf_putmem - write raw data into the sequenc buffer
  214 + * @s: seq_buf descriptor
  215 + * @mem: The raw memory to copy into the buffer
  216 + * @len: The length of the raw memory to copy (in bytes)
  217 + *
  218 + * There may be cases where raw memory needs to be written into the
  219 + * buffer and a strcpy() would not work. Using this function allows
  220 + * for such cases.
  221 + *
  222 + * Returns zero on success, -1 on overflow
  223 + */
  224 +int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len)
  225 +{
  226 + WARN_ON(s->size == 0);
  227 +
  228 + if (seq_buf_can_fit(s, len)) {
  229 + memcpy(s->buffer + s->len, mem, len);
  230 + s->len += len;
  231 + return 0;
  232 + }
  233 + seq_buf_set_overflow(s);
  234 + return -1;
  235 +}
  236 +
  237 +#define MAX_MEMHEX_BYTES 8U
  238 +#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
  239 +
  240 +/**
  241 + * seq_buf_putmem_hex - write raw memory into the buffer in ASCII hex
  242 + * @s: seq_buf descriptor
  243 + * @mem: The raw memory to write its hex ASCII representation of
  244 + * @len: The length of the raw memory to copy (in bytes)
  245 + *
  246 + * This is similar to seq_buf_putmem() except instead of just copying the
  247 + * raw memory into the buffer it writes its ASCII representation of it
  248 + * in hex characters.
  249 + *
  250 + * Returns zero on success, -1 on overflow
  251 + */
  252 +int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
  253 + unsigned int len)
  254 +{
  255 + unsigned char hex[HEX_CHARS];
  256 + const unsigned char *data = mem;
  257 + unsigned int start_len;
  258 + int i, j;
  259 +
  260 + WARN_ON(s->size == 0);
  261 +
  262 + while (len) {
  263 + start_len = min(len, HEX_CHARS - 1);
  264 +#ifdef __BIG_ENDIAN
  265 + for (i = 0, j = 0; i < start_len; i++) {
  266 +#else
  267 + for (i = start_len-1, j = 0; i >= 0; i--) {
  268 +#endif
  269 + hex[j++] = hex_asc_hi(data[i]);
  270 + hex[j++] = hex_asc_lo(data[i]);
  271 + }
  272 + if (WARN_ON_ONCE(j == 0 || j/2 > len))
  273 + break;
  274 +
  275 + /* j increments twice per loop */
  276 + len -= j / 2;
  277 + hex[j++] = ' ';
  278 +
  279 + seq_buf_putmem(s, hex, j);
  280 + if (seq_buf_has_overflowed(s))
  281 + return -1;
  282 + }
  283 + return 0;
  284 +}
  285 +
  286 +/**
  287 + * seq_buf_path - copy a path into the sequence buffer
  288 + * @s: seq_buf descriptor
  289 + * @path: path to write into the sequence buffer.
  290 + * @esc: set of characters to escape in the output
  291 + *
  292 + * Write a path name into the sequence buffer.
  293 + *
  294 + * Returns the number of written bytes on success, -1 on overflow
  295 + */
  296 +int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc)
  297 +{
  298 + char *buf;
  299 + size_t size = seq_buf_get_buf(s, &buf);
  300 + int res = -1;
  301 +
  302 + WARN_ON(s->size == 0);
  303 +
  304 + if (size) {
  305 + char *p = d_path(path, buf, size);
  306 + if (!IS_ERR(p)) {
  307 + char *end = mangle_path(buf, p, esc);
  308 + if (end)
  309 + res = end - buf;
  310 + }
  311 + }
  312 + seq_buf_commit(s, res);
  313 +
  314 + return res;
  315 +}
  316 +
  317 +/**
  318 + * seq_buf_to_user - copy the squence buffer to user space
  319 + * @s: seq_buf descriptor
  320 + * @ubuf: The userspace memory location to copy to
  321 + * @cnt: The amount to copy
  322 + *
  323 + * Copies the sequence buffer into the userspace memory pointed to
  324 + * by @ubuf. It starts from the last read position (@s->readpos)
  325 + * and writes up to @cnt characters or till it reaches the end of
  326 + * the content in the buffer (@s->len), which ever comes first.
  327 + *
  328 + * On success, it returns a positive number of the number of bytes
  329 + * it copied.
  330 + *
  331 + * On failure it returns -EBUSY if all of the content in the
  332 + * sequence has been already read, which includes nothing in the
  333 + * sequence (@s->len == @s->readpos).
  334 + *
  335 + * Returns -EFAULT if the copy to userspace fails.
  336 + */
  337 +int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt)
  338 +{
  339 + int len;
  340 + int ret;
  341 +
  342 + if (!cnt)
  343 + return 0;
  344 +
  345 + if (s->len <= s->readpos)
  346 + return -EBUSY;
  347 +
  348 + len = seq_buf_used(s) - s->readpos;
  349 + if (cnt > len)
  350 + cnt = len;
  351 + ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
  352 + if (ret == cnt)
  353 + return -EFAULT;
  354 +
  355 + cnt -= ret;
  356 +
  357 + s->readpos += cnt;
  358 + return cnt;
  359 +}