Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * linux/fs/seq_file.c
4 : *
5 : * helper functions for making synthetic files from sequences of records.
6 : * initial implementation -- AV, Oct 2001.
7 : */
8 :
9 : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 :
11 : #include <linux/cache.h>
12 : #include <linux/fs.h>
13 : #include <linux/export.h>
14 : #include <linux/seq_file.h>
15 : #include <linux/vmalloc.h>
16 : #include <linux/slab.h>
17 : #include <linux/cred.h>
18 : #include <linux/mm.h>
19 : #include <linux/printk.h>
20 : #include <linux/string_helpers.h>
21 : #include <linux/uio.h>
22 :
23 : #include <linux/uaccess.h>
24 : #include <asm/page.h>
25 :
26 : static struct kmem_cache *seq_file_cache __ro_after_init;
27 :
28 213 : static void seq_set_overflow(struct seq_file *m)
29 : {
30 213 : m->count = m->size;
31 0 : }
32 :
33 2243 : static void *seq_buf_alloc(unsigned long size)
34 : {
35 4487 : return kvmalloc(size, GFP_KERNEL_ACCOUNT);
36 : }
37 :
38 : /**
39 : * seq_open - initialize sequential file
40 : * @file: file we initialize
41 : * @op: method table describing the sequence
42 : *
43 : * seq_open() sets @file, associating it with a sequence described
44 : * by @op. @op->start() sets the iterator up and returns the first
45 : * element of sequence. @op->stop() shuts it down. @op->next()
46 : * returns the next element of sequence. @op->show() prints element
47 : * into the buffer. In case of error ->start() and ->next() return
48 : * ERR_PTR(error). In the end of sequence they return %NULL. ->show()
49 : * returns 0 in case of success and negative number in case of error.
50 : * Returning SEQ_SKIP means "discard this element and move on".
51 : * Note: seq_open() will allocate a struct seq_file and store its
52 : * pointer in @file->private_data. This pointer should not be modified.
53 : */
54 2529 : int seq_open(struct file *file, const struct seq_operations *op)
55 : {
56 2529 : struct seq_file *p;
57 :
58 2529 : WARN_ON(file->private_data);
59 :
60 2529 : p = kmem_cache_zalloc(seq_file_cache, GFP_KERNEL);
61 2530 : if (!p)
62 : return -ENOMEM;
63 :
64 2530 : file->private_data = p;
65 :
66 2530 : mutex_init(&p->lock);
67 2530 : p->op = op;
68 :
69 : // No refcounting: the lifetime of 'p' is constrained
70 : // to the lifetime of the file.
71 2530 : p->file = file;
72 :
73 : /*
74 : * seq_files support lseek() and pread(). They do not implement
75 : * write() at all, but we clear FMODE_PWRITE here for historical
76 : * reasons.
77 : *
78 : * If a client of seq_files a) implements file.write() and b) wishes to
79 : * support pwrite() then that client will need to implement its own
80 : * file.open() which calls seq_open() and then sets FMODE_PWRITE.
81 : */
82 2530 : file->f_mode &= ~FMODE_PWRITE;
83 2530 : return 0;
84 : }
85 : EXPORT_SYMBOL(seq_open);
86 :
87 59 : static int traverse(struct seq_file *m, loff_t offset)
88 : {
89 59 : loff_t pos = 0;
90 59 : int error = 0;
91 59 : void *p;
92 :
93 59 : m->index = 0;
94 59 : m->count = m->from = 0;
95 59 : if (!offset)
96 : return 0;
97 :
98 0 : if (!m->buf) {
99 0 : m->buf = seq_buf_alloc(m->size = PAGE_SIZE);
100 0 : if (!m->buf)
101 : return -ENOMEM;
102 : }
103 0 : p = m->op->start(m, &m->index);
104 0 : while (p) {
105 0 : error = PTR_ERR(p);
106 0 : if (IS_ERR(p))
107 : break;
108 0 : error = m->op->show(m, p);
109 0 : if (error < 0)
110 : break;
111 0 : if (unlikely(error)) {
112 0 : error = 0;
113 0 : m->count = 0;
114 : }
115 0 : if (seq_has_overflowed(m))
116 0 : goto Eoverflow;
117 0 : p = m->op->next(m, p, &m->index);
118 0 : if (pos + m->count > offset) {
119 0 : m->from = offset - pos;
120 0 : m->count -= m->from;
121 0 : break;
122 : }
123 0 : pos += m->count;
124 0 : m->count = 0;
125 0 : if (pos == offset)
126 : break;
127 : }
128 0 : m->op->stop(m, p);
129 0 : return error;
130 :
131 0 : Eoverflow:
132 0 : m->op->stop(m, p);
133 0 : kvfree(m->buf);
134 0 : m->count = 0;
135 0 : m->buf = seq_buf_alloc(m->size <<= 1);
136 0 : return !m->buf ? -ENOMEM : -EAGAIN;
137 : }
138 :
139 : /**
140 : * seq_read - ->read() method for sequential files.
141 : * @file: the file to read from
142 : * @buf: the buffer to read to
143 : * @size: the maximum number of bytes to read
144 : * @ppos: the current position in the file
145 : *
146 : * Ready-made ->f_op->read()
147 : */
148 1875 : ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
149 : {
150 1875 : struct iovec iov = { .iov_base = buf, .iov_len = size};
151 1875 : struct kiocb kiocb;
152 1875 : struct iov_iter iter;
153 1875 : ssize_t ret;
154 :
155 1875 : init_sync_kiocb(&kiocb, file);
156 1875 : iov_iter_init(&iter, READ, &iov, 1, size);
157 :
158 1875 : kiocb.ki_pos = *ppos;
159 1875 : ret = seq_read_iter(&kiocb, &iter);
160 1875 : *ppos = kiocb.ki_pos;
161 1875 : return ret;
162 : }
163 : EXPORT_SYMBOL(seq_read);
164 :
165 : /*
166 : * Ready-made ->f_op->read_iter()
167 : */
168 4814 : ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter)
169 : {
170 4814 : struct seq_file *m = iocb->ki_filp->private_data;
171 4814 : size_t copied = 0;
172 4814 : size_t n;
173 4814 : void *p;
174 4814 : int err = 0;
175 :
176 4814 : if (!iov_iter_count(iter))
177 : return 0;
178 :
179 4815 : mutex_lock(&m->lock);
180 :
181 : /*
182 : * if request is to read from zero offset, reset iterator to first
183 : * record as it might have been already advanced by previous requests
184 : */
185 4814 : if (iocb->ki_pos == 0) {
186 2214 : m->index = 0;
187 2214 : m->count = 0;
188 : }
189 :
190 : /* Don't assume ki_pos is where we left it */
191 4814 : if (unlikely(iocb->ki_pos != m->read_pos)) {
192 0 : while ((err = traverse(m, iocb->ki_pos)) == -EAGAIN)
193 0 : ;
194 0 : if (err) {
195 : /* With prejudice... */
196 0 : m->read_pos = 0;
197 0 : m->index = 0;
198 0 : m->count = 0;
199 0 : goto Done;
200 : } else {
201 0 : m->read_pos = iocb->ki_pos;
202 : }
203 : }
204 :
205 : /* grab buffer if we didn't have one */
206 4814 : if (!m->buf) {
207 2154 : m->buf = seq_buf_alloc(m->size = PAGE_SIZE);
208 2155 : if (!m->buf)
209 0 : goto Enomem;
210 : }
211 : // something left in the buffer - copy it out first
212 4815 : if (m->count) {
213 390 : n = copy_to_iter(m->buf + m->from, m->count, iter);
214 390 : m->count -= n;
215 390 : m->from += n;
216 390 : copied += n;
217 390 : if (m->count) // hadn't managed to copy everything
218 0 : goto Done;
219 : }
220 : // get a non-empty record in the buffer
221 4815 : m->from = 0;
222 4815 : p = m->op->start(m, &m->index);
223 5178 : while (1) {
224 5178 : err = PTR_ERR(p);
225 5178 : if (!p || IS_ERR(p)) // EOF or an error
226 : break;
227 2993 : err = m->op->show(m, p);
228 2992 : if (err < 0) // hard error
229 : break;
230 2990 : if (unlikely(err)) // ->show() says "skip it"
231 208 : m->count = 0;
232 2990 : if (unlikely(!m->count)) { // empty record
233 274 : p = m->op->next(m, p, &m->index);
234 274 : continue;
235 : }
236 2716 : if (!seq_has_overflowed(m)) // got it
237 2627 : goto Fill;
238 : // need a bigger buffer
239 89 : m->op->stop(m, p);
240 89 : kvfree(m->buf);
241 89 : m->count = 0;
242 89 : m->buf = seq_buf_alloc(m->size <<= 1);
243 89 : if (!m->buf)
244 0 : goto Enomem;
245 89 : p = m->op->start(m, &m->index);
246 : }
247 : // EOF or an error
248 2187 : m->op->stop(m, p);
249 2187 : m->count = 0;
250 2187 : goto Done;
251 2627 : Fill:
252 : // one non-empty record is in the buffer; if they want more,
253 : // try to fit more in, but in any case we need to advance
254 : // the iterator once for every record shown.
255 7017 : while (1) {
256 7017 : size_t offs = m->count;
257 7017 : loff_t pos = m->index;
258 :
259 7017 : p = m->op->next(m, p, &m->index);
260 7019 : if (pos == m->index) {
261 0 : pr_info_ratelimited("buggy .next function %ps did not update position index\n",
262 : m->op->next);
263 0 : m->index++;
264 : }
265 7019 : if (!p || IS_ERR(p)) // no next record for us
266 : break;
267 4905 : if (m->count >= iov_iter_count(iter))
268 : break;
269 4515 : err = m->op->show(m, p);
270 4514 : if (err > 0) { // ->show() says "skip it"
271 0 : m->count = offs;
272 4514 : } else if (err || seq_has_overflowed(m)) {
273 124 : m->count = offs;
274 124 : break;
275 : }
276 : }
277 2628 : m->op->stop(m, p);
278 2628 : n = copy_to_iter(m->buf, m->count, iter);
279 2628 : copied += n;
280 2628 : m->count -= n;
281 2628 : m->from = n;
282 4815 : Done:
283 4815 : if (unlikely(!copied)) {
284 2179 : copied = m->count ? -EFAULT : err;
285 : } else {
286 2636 : iocb->ki_pos += copied;
287 2636 : m->read_pos += copied;
288 : }
289 4815 : mutex_unlock(&m->lock);
290 4815 : return copied;
291 0 : Enomem:
292 0 : err = -ENOMEM;
293 0 : goto Done;
294 : }
295 : EXPORT_SYMBOL(seq_read_iter);
296 :
297 : /**
298 : * seq_lseek - ->llseek() method for sequential files.
299 : * @file: the file in question
300 : * @offset: new position
301 : * @whence: 0 for absolute, 1 for relative position
302 : *
303 : * Ready-made ->f_op->llseek()
304 : */
305 61 : loff_t seq_lseek(struct file *file, loff_t offset, int whence)
306 : {
307 61 : struct seq_file *m = file->private_data;
308 61 : loff_t retval = -EINVAL;
309 :
310 61 : mutex_lock(&m->lock);
311 61 : switch (whence) {
312 0 : case SEEK_CUR:
313 0 : offset += file->f_pos;
314 61 : fallthrough;
315 61 : case SEEK_SET:
316 61 : if (offset < 0)
317 : break;
318 61 : retval = offset;
319 61 : if (offset != m->read_pos) {
320 59 : while ((retval = traverse(m, offset)) == -EAGAIN)
321 59 : ;
322 59 : if (retval) {
323 : /* with extreme prejudice... */
324 0 : file->f_pos = 0;
325 0 : m->read_pos = 0;
326 0 : m->index = 0;
327 0 : m->count = 0;
328 : } else {
329 59 : m->read_pos = offset;
330 59 : retval = file->f_pos = offset;
331 : }
332 : } else {
333 2 : file->f_pos = offset;
334 : }
335 : }
336 61 : mutex_unlock(&m->lock);
337 61 : return retval;
338 : }
339 : EXPORT_SYMBOL(seq_lseek);
340 :
341 : /**
342 : * seq_release - free the structures associated with sequential file.
343 : * @file: file in question
344 : * @inode: its inode
345 : *
346 : * Frees the structures associated with sequential file; can be used
347 : * as ->f_op->release() if you don't have private data to destroy.
348 : */
349 2527 : int seq_release(struct inode *inode, struct file *file)
350 : {
351 2527 : struct seq_file *m = file->private_data;
352 2527 : kvfree(m->buf);
353 2527 : kmem_cache_free(seq_file_cache, m);
354 2527 : return 0;
355 : }
356 : EXPORT_SYMBOL(seq_release);
357 :
358 : /**
359 : * seq_escape - print string into buffer, escaping some characters
360 : * @m: target buffer
361 : * @s: string
362 : * @esc: set of characters that need escaping
363 : *
364 : * Puts string into buffer, replacing each occurrence of character from
365 : * @esc with usual octal escape.
366 : * Use seq_has_overflowed() to check for errors.
367 : */
368 10824 : void seq_escape(struct seq_file *m, const char *s, const char *esc)
369 : {
370 10824 : char *buf;
371 10824 : size_t size = seq_get_buf(m, &buf);
372 10832 : int ret;
373 :
374 10832 : ret = string_escape_str(s, buf, size, ESCAPE_OCTAL, esc);
375 10835 : seq_commit(m, ret < size ? ret : -1);
376 10835 : }
377 : EXPORT_SYMBOL(seq_escape);
378 :
379 0 : void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz)
380 : {
381 0 : char *buf;
382 0 : size_t size = seq_get_buf(m, &buf);
383 0 : int ret;
384 :
385 0 : ret = string_escape_mem_ascii(src, isz, buf, size);
386 0 : seq_commit(m, ret < size ? ret : -1);
387 0 : }
388 : EXPORT_SYMBOL(seq_escape_mem_ascii);
389 :
390 19411 : void seq_vprintf(struct seq_file *m, const char *f, va_list args)
391 : {
392 19411 : int len;
393 :
394 19411 : if (m->count < m->size) {
395 19409 : len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
396 19409 : if (m->count + len < m->size) {
397 19411 : m->count += len;
398 19411 : return;
399 : }
400 : }
401 0 : seq_set_overflow(m);
402 : }
403 : EXPORT_SYMBOL(seq_vprintf);
404 :
405 19409 : void seq_printf(struct seq_file *m, const char *f, ...)
406 : {
407 19409 : va_list args;
408 :
409 19409 : va_start(args, f);
410 19409 : seq_vprintf(m, f, args);
411 19412 : va_end(args);
412 19412 : }
413 : EXPORT_SYMBOL(seq_printf);
414 :
415 : /**
416 : * mangle_path - mangle and copy path to buffer beginning
417 : * @s: buffer start
418 : * @p: beginning of path in above buffer
419 : * @esc: set of characters that need escaping
420 : *
421 : * Copy the path from @p to @s, replacing each occurrence of character from
422 : * @esc with usual octal escape.
423 : * Returns pointer past last written character in @s, or NULL in case of
424 : * failure.
425 : */
426 9289 : char *mangle_path(char *s, const char *p, const char *esc)
427 : {
428 126746 : while (s <= p) {
429 126746 : char c = *p++;
430 126746 : if (!c) {
431 9289 : return s;
432 117457 : } else if (!strchr(esc, c)) {
433 117457 : *s++ = c;
434 0 : } else if (s + 4 > p) {
435 : break;
436 : } else {
437 0 : *s++ = '\\';
438 0 : *s++ = '0' + ((c & 0300) >> 6);
439 0 : *s++ = '0' + ((c & 070) >> 3);
440 0 : *s++ = '0' + (c & 07);
441 : }
442 : }
443 : return NULL;
444 : }
445 : EXPORT_SYMBOL(mangle_path);
446 :
447 : /**
448 : * seq_path - seq_file interface to print a pathname
449 : * @m: the seq_file handle
450 : * @path: the struct path to print
451 : * @esc: set of characters to escape in the output
452 : *
453 : * return the absolute path of 'path', as represented by the
454 : * dentry / mnt pair in the path parameter.
455 : */
456 0 : int seq_path(struct seq_file *m, const struct path *path, const char *esc)
457 : {
458 0 : char *buf;
459 0 : size_t size = seq_get_buf(m, &buf);
460 0 : int res = -1;
461 :
462 0 : if (size) {
463 0 : char *p = d_path(path, buf, size);
464 0 : if (!IS_ERR(p)) {
465 0 : char *end = mangle_path(buf, p, esc);
466 0 : if (end)
467 0 : res = end - buf;
468 : }
469 : }
470 0 : seq_commit(m, res);
471 :
472 0 : return res;
473 : }
474 : EXPORT_SYMBOL(seq_path);
475 :
476 : /**
477 : * seq_file_path - seq_file interface to print a pathname of a file
478 : * @m: the seq_file handle
479 : * @file: the struct file to print
480 : * @esc: set of characters to escape in the output
481 : *
482 : * return the absolute path to the file.
483 : */
484 0 : int seq_file_path(struct seq_file *m, struct file *file, const char *esc)
485 : {
486 0 : return seq_path(m, &file->f_path, esc);
487 : }
488 : EXPORT_SYMBOL(seq_file_path);
489 :
490 : /*
491 : * Same as seq_path, but relative to supplied root.
492 : */
493 5048 : int seq_path_root(struct seq_file *m, const struct path *path,
494 : const struct path *root, const char *esc)
495 : {
496 5048 : char *buf;
497 5048 : size_t size = seq_get_buf(m, &buf);
498 5048 : int res = -ENAMETOOLONG;
499 :
500 5048 : if (size) {
501 5048 : char *p;
502 :
503 5048 : p = __d_path(path, root, buf, size);
504 5048 : if (!p)
505 : return SEQ_SKIP;
506 4840 : res = PTR_ERR(p);
507 4840 : if (!IS_ERR(p)) {
508 4840 : char *end = mangle_path(buf, p, esc);
509 4841 : if (end)
510 4841 : res = end - buf;
511 : else
512 : res = -ENAMETOOLONG;
513 : }
514 : }
515 4841 : seq_commit(m, res);
516 :
517 4841 : return res < 0 && res != -ENAMETOOLONG ? res : 0;
518 : }
519 :
520 : /*
521 : * returns the path of the 'dentry' from the root of its filesystem.
522 : */
523 4447 : int seq_dentry(struct seq_file *m, struct dentry *dentry, const char *esc)
524 : {
525 4447 : char *buf;
526 4447 : size_t size = seq_get_buf(m, &buf);
527 4448 : int res = -1;
528 :
529 4448 : if (size) {
530 4448 : char *p = dentry_path(dentry, buf, size);
531 4448 : if (!IS_ERR(p)) {
532 4448 : char *end = mangle_path(buf, p, esc);
533 4445 : if (end)
534 4445 : res = end - buf;
535 : }
536 : }
537 4445 : seq_commit(m, res);
538 :
539 4446 : return res;
540 : }
541 : EXPORT_SYMBOL(seq_dentry);
542 :
543 2283 : static void *single_start(struct seq_file *p, loff_t *pos)
544 : {
545 2283 : return NULL + (*pos == 0);
546 : }
547 :
548 1146 : static void *single_next(struct seq_file *p, void *v, loff_t *pos)
549 : {
550 1146 : ++*pos;
551 1146 : return NULL;
552 : }
553 :
554 2283 : static void single_stop(struct seq_file *p, void *v)
555 : {
556 2283 : }
557 :
558 1146 : int single_open(struct file *file, int (*show)(struct seq_file *, void *),
559 : void *data)
560 : {
561 1146 : struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL_ACCOUNT);
562 1146 : int res = -ENOMEM;
563 :
564 1146 : if (op) {
565 1146 : op->start = single_start;
566 1146 : op->next = single_next;
567 1146 : op->stop = single_stop;
568 1146 : op->show = show;
569 1146 : res = seq_open(file, op);
570 1146 : if (!res)
571 1146 : ((struct seq_file *)file->private_data)->private = data;
572 : else
573 0 : kfree(op);
574 : }
575 1146 : return res;
576 : }
577 : EXPORT_SYMBOL(single_open);
578 :
579 0 : int single_open_size(struct file *file, int (*show)(struct seq_file *, void *),
580 : void *data, size_t size)
581 : {
582 0 : char *buf = seq_buf_alloc(size);
583 0 : int ret;
584 0 : if (!buf)
585 : return -ENOMEM;
586 0 : ret = single_open(file, show, data);
587 0 : if (ret) {
588 0 : kvfree(buf);
589 0 : return ret;
590 : }
591 0 : ((struct seq_file *)file->private_data)->buf = buf;
592 0 : ((struct seq_file *)file->private_data)->size = size;
593 0 : return 0;
594 : }
595 : EXPORT_SYMBOL(single_open_size);
596 :
597 1146 : int single_release(struct inode *inode, struct file *file)
598 : {
599 1146 : const struct seq_operations *op = ((struct seq_file *)file->private_data)->op;
600 1146 : int res = seq_release(inode, file);
601 1146 : kfree(op);
602 1146 : return res;
603 : }
604 : EXPORT_SYMBOL(single_release);
605 :
606 150 : int seq_release_private(struct inode *inode, struct file *file)
607 : {
608 150 : struct seq_file *seq = file->private_data;
609 :
610 150 : kfree(seq->private);
611 150 : seq->private = NULL;
612 150 : return seq_release(inode, file);
613 : }
614 : EXPORT_SYMBOL(seq_release_private);
615 :
616 152 : void *__seq_open_private(struct file *f, const struct seq_operations *ops,
617 : int psize)
618 : {
619 152 : int rc;
620 152 : void *private;
621 152 : struct seq_file *seq;
622 :
623 152 : private = kzalloc(psize, GFP_KERNEL_ACCOUNT);
624 151 : if (private == NULL)
625 0 : goto out;
626 :
627 151 : rc = seq_open(f, ops);
628 152 : if (rc < 0)
629 0 : goto out_free;
630 :
631 152 : seq = f->private_data;
632 152 : seq->private = private;
633 152 : return private;
634 :
635 0 : out_free:
636 0 : kfree(private);
637 : out:
638 : return NULL;
639 : }
640 : EXPORT_SYMBOL(__seq_open_private);
641 :
642 152 : int seq_open_private(struct file *filp, const struct seq_operations *ops,
643 : int psize)
644 : {
645 152 : return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM;
646 : }
647 : EXPORT_SYMBOL(seq_open_private);
648 :
649 28869 : void seq_putc(struct seq_file *m, char c)
650 : {
651 22024 : if (m->count >= m->size)
652 : return;
653 :
654 28869 : m->buf[m->count++] = c;
655 : }
656 : EXPORT_SYMBOL(seq_putc);
657 :
658 31265 : void seq_puts(struct seq_file *m, const char *s)
659 : {
660 31265 : int len = strlen(s);
661 :
662 31265 : if (m->count + len >= m->size) {
663 0 : seq_set_overflow(m);
664 0 : return;
665 : }
666 31265 : memcpy(m->buf + m->count, s, len);
667 31265 : m->count += len;
668 : }
669 : EXPORT_SYMBOL(seq_puts);
670 :
671 : /**
672 : * seq_put_decimal_ull_width - A helper routine for putting decimal numbers
673 : * without rich format of printf().
674 : * only 'unsigned long long' is supported.
675 : * @m: seq_file identifying the buffer to which data should be written
676 : * @delimiter: a string which is printed before the number
677 : * @num: the number
678 : * @width: a minimum field width
679 : *
680 : * This routine will put strlen(delimiter) + number into seq_filed.
681 : * This routine is very quick when you show lots of numbers.
682 : * In usual cases, it will be better to use seq_printf(). It's easier to read.
683 : */
684 6659 : void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter,
685 : unsigned long long num, unsigned int width)
686 : {
687 6659 : int len;
688 :
689 6659 : if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */
690 0 : goto overflow;
691 :
692 6659 : if (delimiter && delimiter[0]) {
693 6518 : if (delimiter[1] == 0)
694 4871 : seq_putc(m, delimiter[0]);
695 : else
696 1647 : seq_puts(m, delimiter);
697 : }
698 :
699 6659 : if (!width)
700 : width = 1;
701 :
702 6659 : if (m->count + width >= m->size)
703 0 : goto overflow;
704 :
705 6659 : len = num_to_str(m->buf + m->count, m->size - m->count, num, width);
706 6659 : if (!len)
707 0 : goto overflow;
708 :
709 6659 : m->count += len;
710 6659 : return;
711 :
712 0 : overflow:
713 0 : seq_set_overflow(m);
714 : }
715 :
716 5795 : void seq_put_decimal_ull(struct seq_file *m, const char *delimiter,
717 : unsigned long long num)
718 : {
719 5795 : return seq_put_decimal_ull_width(m, delimiter, num, 0);
720 : }
721 : EXPORT_SYMBOL(seq_put_decimal_ull);
722 :
723 : /**
724 : * seq_put_hex_ll - put a number in hexadecimal notation
725 : * @m: seq_file identifying the buffer to which data should be written
726 : * @delimiter: a string which is printed before the number
727 : * @v: the number
728 : * @width: a minimum field width
729 : *
730 : * seq_put_hex_ll(m, "", v, 8) is equal to seq_printf(m, "%08llx", v)
731 : *
732 : * This routine is very quick when you show lots of numbers.
733 : * In usual cases, it will be better to use seq_printf(). It's easier to read.
734 : */
735 560 : void seq_put_hex_ll(struct seq_file *m, const char *delimiter,
736 : unsigned long long v, unsigned int width)
737 : {
738 560 : unsigned int len;
739 560 : int i;
740 :
741 560 : if (delimiter && delimiter[0]) {
742 0 : if (delimiter[1] == 0)
743 0 : seq_putc(m, delimiter[0]);
744 : else
745 0 : seq_puts(m, delimiter);
746 : }
747 :
748 : /* If x is 0, the result of __builtin_clzll is undefined */
749 560 : if (v == 0)
750 : len = 1;
751 : else
752 328 : len = (sizeof(v) * 8 - __builtin_clzll(v) + 3) / 4;
753 :
754 560 : if (len < width)
755 : len = width;
756 :
757 560 : if (m->count + len > m->size) {
758 0 : seq_set_overflow(m);
759 0 : return;
760 : }
761 :
762 5040 : for (i = len - 1; i >= 0; i--) {
763 4480 : m->buf[m->count + i] = hex_asc[0xf & v];
764 4480 : v = v >> 4;
765 : }
766 560 : m->count += len;
767 : }
768 :
769 1974 : void seq_put_decimal_ll(struct seq_file *m, const char *delimiter, long long num)
770 : {
771 1974 : int len;
772 :
773 1974 : if (m->count + 3 >= m->size) /* we'll write 2 bytes at least */
774 0 : goto overflow;
775 :
776 1974 : if (delimiter && delimiter[0]) {
777 1974 : if (delimiter[1] == 0)
778 1974 : seq_putc(m, delimiter[0]);
779 : else
780 0 : seq_puts(m, delimiter);
781 : }
782 :
783 1974 : if (m->count + 2 >= m->size)
784 0 : goto overflow;
785 :
786 1974 : if (num < 0) {
787 158 : m->buf[m->count++] = '-';
788 158 : num = -num;
789 : }
790 :
791 1974 : if (num < 10) {
792 1561 : m->buf[m->count++] = num + '0';
793 1561 : return;
794 : }
795 :
796 413 : len = num_to_str(m->buf + m->count, m->size - m->count, num, 0);
797 413 : if (!len)
798 0 : goto overflow;
799 :
800 413 : m->count += len;
801 413 : return;
802 :
803 0 : overflow:
804 0 : seq_set_overflow(m);
805 : }
806 : EXPORT_SYMBOL(seq_put_decimal_ll);
807 :
808 : /**
809 : * seq_write - write arbitrary data to buffer
810 : * @seq: seq_file identifying the buffer to which data should be written
811 : * @data: data address
812 : * @len: number of bytes
813 : *
814 : * Return 0 on success, non-zero otherwise.
815 : */
816 717 : int seq_write(struct seq_file *seq, const void *data, size_t len)
817 : {
818 717 : if (seq->count + len < seq->size) {
819 504 : memcpy(seq->buf + seq->count, data, len);
820 504 : seq->count += len;
821 504 : return 0;
822 : }
823 213 : seq_set_overflow(seq);
824 213 : return -1;
825 : }
826 : EXPORT_SYMBOL(seq_write);
827 :
828 : /**
829 : * seq_pad - write padding spaces to buffer
830 : * @m: seq_file identifying the buffer to which data should be written
831 : * @c: the byte to append after padding if non-zero
832 : */
833 0 : void seq_pad(struct seq_file *m, char c)
834 : {
835 0 : int size = m->pad_until - m->count;
836 0 : if (size > 0) {
837 0 : if (size + m->count > m->size) {
838 0 : seq_set_overflow(m);
839 0 : return;
840 : }
841 0 : memset(m->buf + m->count, ' ', size);
842 0 : m->count += size;
843 : }
844 0 : if (c)
845 0 : seq_putc(m, c);
846 : }
847 : EXPORT_SYMBOL(seq_pad);
848 :
849 : /* A complete analogue of print_hex_dump() */
850 0 : void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
851 : int rowsize, int groupsize, const void *buf, size_t len,
852 : bool ascii)
853 : {
854 0 : const u8 *ptr = buf;
855 0 : int i, linelen, remaining = len;
856 0 : char *buffer;
857 0 : size_t size;
858 0 : int ret;
859 :
860 0 : if (rowsize != 16 && rowsize != 32)
861 0 : rowsize = 16;
862 :
863 0 : for (i = 0; i < len && !seq_has_overflowed(m); i += rowsize) {
864 0 : linelen = min(remaining, rowsize);
865 0 : remaining -= rowsize;
866 :
867 0 : switch (prefix_type) {
868 0 : case DUMP_PREFIX_ADDRESS:
869 0 : seq_printf(m, "%s%p: ", prefix_str, ptr + i);
870 0 : break;
871 0 : case DUMP_PREFIX_OFFSET:
872 0 : seq_printf(m, "%s%.8x: ", prefix_str, i);
873 0 : break;
874 0 : default:
875 0 : seq_printf(m, "%s", prefix_str);
876 0 : break;
877 : }
878 :
879 0 : size = seq_get_buf(m, &buffer);
880 0 : ret = hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
881 : buffer, size, ascii);
882 0 : seq_commit(m, ret < size ? ret : -1);
883 :
884 0 : seq_putc(m, '\n');
885 : }
886 0 : }
887 : EXPORT_SYMBOL(seq_hex_dump);
888 :
889 0 : struct list_head *seq_list_start(struct list_head *head, loff_t pos)
890 : {
891 0 : struct list_head *lh;
892 :
893 0 : list_for_each(lh, head)
894 0 : if (pos-- == 0)
895 0 : return lh;
896 :
897 : return NULL;
898 : }
899 : EXPORT_SYMBOL(seq_list_start);
900 :
901 0 : struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
902 : {
903 0 : if (!pos)
904 : return head;
905 :
906 0 : return seq_list_start(head, pos - 1);
907 : }
908 : EXPORT_SYMBOL(seq_list_start_head);
909 :
910 0 : struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
911 : {
912 0 : struct list_head *lh;
913 :
914 0 : lh = ((struct list_head *)v)->next;
915 0 : ++*ppos;
916 0 : return lh == head ? NULL : lh;
917 : }
918 : EXPORT_SYMBOL(seq_list_next);
919 :
920 : /**
921 : * seq_hlist_start - start an iteration of a hlist
922 : * @head: the head of the hlist
923 : * @pos: the start position of the sequence
924 : *
925 : * Called at seq_file->op->start().
926 : */
927 0 : struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
928 : {
929 0 : struct hlist_node *node;
930 :
931 0 : hlist_for_each(node, head)
932 0 : if (pos-- == 0)
933 0 : return node;
934 : return NULL;
935 : }
936 : EXPORT_SYMBOL(seq_hlist_start);
937 :
938 : /**
939 : * seq_hlist_start_head - start an iteration of a hlist
940 : * @head: the head of the hlist
941 : * @pos: the start position of the sequence
942 : *
943 : * Called at seq_file->op->start(). Call this function if you want to
944 : * print a header at the top of the output.
945 : */
946 0 : struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
947 : {
948 0 : if (!pos)
949 : return SEQ_START_TOKEN;
950 :
951 0 : return seq_hlist_start(head, pos - 1);
952 : }
953 : EXPORT_SYMBOL(seq_hlist_start_head);
954 :
955 : /**
956 : * seq_hlist_next - move to the next position of the hlist
957 : * @v: the current iterator
958 : * @head: the head of the hlist
959 : * @ppos: the current position
960 : *
961 : * Called at seq_file->op->next().
962 : */
963 0 : struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
964 : loff_t *ppos)
965 : {
966 0 : struct hlist_node *node = v;
967 :
968 0 : ++*ppos;
969 0 : if (v == SEQ_START_TOKEN)
970 0 : return head->first;
971 : else
972 0 : return node->next;
973 : }
974 : EXPORT_SYMBOL(seq_hlist_next);
975 :
976 : /**
977 : * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
978 : * @head: the head of the hlist
979 : * @pos: the start position of the sequence
980 : *
981 : * Called at seq_file->op->start().
982 : *
983 : * This list-traversal primitive may safely run concurrently with
984 : * the _rcu list-mutation primitives such as hlist_add_head_rcu()
985 : * as long as the traversal is guarded by rcu_read_lock().
986 : */
987 0 : struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
988 : loff_t pos)
989 : {
990 0 : struct hlist_node *node;
991 :
992 0 : __hlist_for_each_rcu(node, head)
993 0 : if (pos-- == 0)
994 0 : return node;
995 : return NULL;
996 : }
997 : EXPORT_SYMBOL(seq_hlist_start_rcu);
998 :
999 : /**
1000 : * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
1001 : * @head: the head of the hlist
1002 : * @pos: the start position of the sequence
1003 : *
1004 : * Called at seq_file->op->start(). Call this function if you want to
1005 : * print a header at the top of the output.
1006 : *
1007 : * This list-traversal primitive may safely run concurrently with
1008 : * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1009 : * as long as the traversal is guarded by rcu_read_lock().
1010 : */
1011 0 : struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
1012 : loff_t pos)
1013 : {
1014 0 : if (!pos)
1015 : return SEQ_START_TOKEN;
1016 :
1017 0 : return seq_hlist_start_rcu(head, pos - 1);
1018 : }
1019 : EXPORT_SYMBOL(seq_hlist_start_head_rcu);
1020 :
1021 : /**
1022 : * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
1023 : * @v: the current iterator
1024 : * @head: the head of the hlist
1025 : * @ppos: the current position
1026 : *
1027 : * Called at seq_file->op->next().
1028 : *
1029 : * This list-traversal primitive may safely run concurrently with
1030 : * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1031 : * as long as the traversal is guarded by rcu_read_lock().
1032 : */
1033 0 : struct hlist_node *seq_hlist_next_rcu(void *v,
1034 : struct hlist_head *head,
1035 : loff_t *ppos)
1036 : {
1037 0 : struct hlist_node *node = v;
1038 :
1039 0 : ++*ppos;
1040 0 : if (v == SEQ_START_TOKEN)
1041 0 : return rcu_dereference(head->first);
1042 : else
1043 0 : return rcu_dereference(node->next);
1044 : }
1045 : EXPORT_SYMBOL(seq_hlist_next_rcu);
1046 :
1047 : /**
1048 : * seq_hlist_start_percpu - start an iteration of a percpu hlist array
1049 : * @head: pointer to percpu array of struct hlist_heads
1050 : * @cpu: pointer to cpu "cursor"
1051 : * @pos: start position of sequence
1052 : *
1053 : * Called at seq_file->op->start().
1054 : */
1055 : struct hlist_node *
1056 0 : seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos)
1057 : {
1058 0 : struct hlist_node *node;
1059 :
1060 0 : for_each_possible_cpu(*cpu) {
1061 0 : hlist_for_each(node, per_cpu_ptr(head, *cpu)) {
1062 0 : if (pos-- == 0)
1063 0 : return node;
1064 : }
1065 : }
1066 : return NULL;
1067 : }
1068 : EXPORT_SYMBOL(seq_hlist_start_percpu);
1069 :
1070 : /**
1071 : * seq_hlist_next_percpu - move to the next position of the percpu hlist array
1072 : * @v: pointer to current hlist_node
1073 : * @head: pointer to percpu array of struct hlist_heads
1074 : * @cpu: pointer to cpu "cursor"
1075 : * @pos: start position of sequence
1076 : *
1077 : * Called at seq_file->op->next().
1078 : */
1079 : struct hlist_node *
1080 0 : seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head,
1081 : int *cpu, loff_t *pos)
1082 : {
1083 0 : struct hlist_node *node = v;
1084 :
1085 0 : ++*pos;
1086 :
1087 0 : if (node->next)
1088 : return node->next;
1089 :
1090 0 : for (*cpu = cpumask_next(*cpu, cpu_possible_mask); *cpu < nr_cpu_ids;
1091 0 : *cpu = cpumask_next(*cpu, cpu_possible_mask)) {
1092 0 : struct hlist_head *bucket = per_cpu_ptr(head, *cpu);
1093 :
1094 0 : if (!hlist_empty(bucket))
1095 0 : return bucket->first;
1096 : }
1097 : return NULL;
1098 : }
1099 : EXPORT_SYMBOL(seq_hlist_next_percpu);
1100 :
1101 1 : void __init seq_file_init(void)
1102 : {
1103 1 : seq_file_cache = KMEM_CACHE(seq_file, SLAB_ACCOUNT|SLAB_PANIC);
1104 1 : }
|