Lines Matching +full:- +full:m
1 // SPDX-License-Identifier: GPL-2.0
6 * initial implementation -- AV, Oct 2001.
28 static void seq_set_overflow(struct seq_file *m) in seq_set_overflow() argument
30 m->count = m->size; in seq_set_overflow()
39 * seq_open - initialize sequential file
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()
52 * pointer in @file->private_data. This pointer should not be modified.
58 WARN_ON(file->private_data); in seq_open()
62 return -ENOMEM; in seq_open()
64 file->private_data = p; in seq_open()
66 mutex_init(&p->lock); in seq_open()
67 p->op = op; in seq_open()
71 p->file = file; in seq_open()
82 file->f_mode &= ~FMODE_PWRITE; in seq_open()
87 static int traverse(struct seq_file *m, loff_t offset) in traverse() argument
93 m->index = 0; in traverse()
94 m->count = m->from = 0; in traverse()
98 if (!m->buf) { in traverse()
99 m->buf = seq_buf_alloc(m->size = PAGE_SIZE); in traverse()
100 if (!m->buf) in traverse()
101 return -ENOMEM; in traverse()
103 p = m->op->start(m, &m->index); in traverse()
108 error = m->op->show(m, p); in traverse()
113 m->count = 0; in traverse()
115 if (seq_has_overflowed(m)) in traverse()
117 p = m->op->next(m, p, &m->index); in traverse()
118 if (pos + m->count > offset) { in traverse()
119 m->from = offset - pos; in traverse()
120 m->count -= m->from; in traverse()
123 pos += m->count; in traverse()
124 m->count = 0; in traverse()
128 m->op->stop(m, p); in traverse()
132 m->op->stop(m, p); in traverse()
133 kvfree(m->buf); in traverse()
134 m->count = 0; in traverse()
135 m->buf = seq_buf_alloc(m->size <<= 1); in traverse()
136 return !m->buf ? -ENOMEM : -EAGAIN; in traverse()
140 * seq_read - ->read() method for sequential files.
146 * Ready-made ->f_op->read()
166 * Ready-made ->f_op->read_iter()
170 struct seq_file *m = iocb->ki_filp->private_data; in seq_read_iter() local
179 mutex_lock(&m->lock); in seq_read_iter()
185 if (iocb->ki_pos == 0) { in seq_read_iter()
186 m->index = 0; in seq_read_iter()
187 m->count = 0; in seq_read_iter()
191 if (unlikely(iocb->ki_pos != m->read_pos)) { in seq_read_iter()
192 while ((err = traverse(m, iocb->ki_pos)) == -EAGAIN) in seq_read_iter()
196 m->read_pos = 0; in seq_read_iter()
197 m->index = 0; in seq_read_iter()
198 m->count = 0; in seq_read_iter()
201 m->read_pos = iocb->ki_pos; in seq_read_iter()
206 if (!m->buf) { in seq_read_iter()
207 m->buf = seq_buf_alloc(m->size = PAGE_SIZE); in seq_read_iter()
208 if (!m->buf) in seq_read_iter()
211 // something left in the buffer - copy it out first in seq_read_iter()
212 if (m->count) { in seq_read_iter()
213 n = copy_to_iter(m->buf + m->from, m->count, iter); in seq_read_iter()
214 m->count -= n; in seq_read_iter()
215 m->from += n; in seq_read_iter()
217 if (m->count) // hadn't managed to copy everything in seq_read_iter()
220 // get a non-empty record in the buffer in seq_read_iter()
221 m->from = 0; in seq_read_iter()
222 p = m->op->start(m, &m->index); in seq_read_iter()
227 err = m->op->show(m, p); in seq_read_iter()
230 if (unlikely(err)) // ->show() says "skip it" in seq_read_iter()
231 m->count = 0; in seq_read_iter()
232 if (unlikely(!m->count)) { // empty record in seq_read_iter()
233 p = m->op->next(m, p, &m->index); in seq_read_iter()
236 if (!seq_has_overflowed(m)) // got it in seq_read_iter()
239 m->op->stop(m, p); in seq_read_iter()
240 kvfree(m->buf); in seq_read_iter()
241 m->count = 0; in seq_read_iter()
242 m->buf = seq_buf_alloc(m->size <<= 1); in seq_read_iter()
243 if (!m->buf) in seq_read_iter()
245 p = m->op->start(m, &m->index); in seq_read_iter()
248 m->op->stop(m, p); in seq_read_iter()
249 m->count = 0; in seq_read_iter()
252 // one non-empty record is in the buffer; if they want more, in seq_read_iter()
256 size_t offs = m->count; in seq_read_iter()
257 loff_t pos = m->index; in seq_read_iter()
259 p = m->op->next(m, p, &m->index); in seq_read_iter()
260 if (pos == m->index) { in seq_read_iter()
262 m->op->next); in seq_read_iter()
263 m->index++; in seq_read_iter()
267 if (m->count >= iov_iter_count(iter)) in seq_read_iter()
269 err = m->op->show(m, p); in seq_read_iter()
270 if (err > 0) { // ->show() says "skip it" in seq_read_iter()
271 m->count = offs; in seq_read_iter()
272 } else if (err || seq_has_overflowed(m)) { in seq_read_iter()
273 m->count = offs; in seq_read_iter()
277 m->op->stop(m, p); in seq_read_iter()
278 n = copy_to_iter(m->buf, m->count, iter); in seq_read_iter()
280 m->count -= n; in seq_read_iter()
281 m->from = n; in seq_read_iter()
284 copied = m->count ? -EFAULT : err; in seq_read_iter()
286 iocb->ki_pos += copied; in seq_read_iter()
287 m->read_pos += copied; in seq_read_iter()
289 mutex_unlock(&m->lock); in seq_read_iter()
292 err = -ENOMEM; in seq_read_iter()
298 * seq_lseek - ->llseek() method for sequential files.
303 * Ready-made ->f_op->llseek()
307 struct seq_file *m = file->private_data; in seq_lseek() local
308 loff_t retval = -EINVAL; in seq_lseek()
310 mutex_lock(&m->lock); in seq_lseek()
313 offset += file->f_pos; in seq_lseek()
319 if (offset != m->read_pos) { in seq_lseek()
320 while ((retval = traverse(m, offset)) == -EAGAIN) in seq_lseek()
324 file->f_pos = 0; in seq_lseek()
325 m->read_pos = 0; in seq_lseek()
326 m->index = 0; in seq_lseek()
327 m->count = 0; in seq_lseek()
329 m->read_pos = offset; in seq_lseek()
330 retval = file->f_pos = offset; in seq_lseek()
333 file->f_pos = offset; in seq_lseek()
336 mutex_unlock(&m->lock); in seq_lseek()
342 * seq_release - free the structures associated with sequential file.
347 * as ->f_op->release() if you don't have private data to destroy.
351 struct seq_file *m = file->private_data; in seq_release() local
352 kvfree(m->buf); in seq_release()
353 kmem_cache_free(seq_file_cache, m); in seq_release()
359 * seq_escape - print string into buffer, escaping some characters
360 * @m: target buffer
368 void seq_escape(struct seq_file *m, const char *s, const char *esc) in seq_escape() argument
371 size_t size = seq_get_buf(m, &buf); in seq_escape()
375 seq_commit(m, ret < size ? ret : -1); in seq_escape()
379 void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz) in seq_escape_mem_ascii() argument
382 size_t size = seq_get_buf(m, &buf); in seq_escape_mem_ascii()
386 seq_commit(m, ret < size ? ret : -1); in seq_escape_mem_ascii()
390 void seq_vprintf(struct seq_file *m, const char *f, va_list args) in seq_vprintf() argument
394 if (m->count < m->size) { in seq_vprintf()
395 len = vsnprintf(m->buf + m->count, m->size - m->count, f, args); in seq_vprintf()
396 if (m->count + len < m->size) { in seq_vprintf()
397 m->count += len; in seq_vprintf()
401 seq_set_overflow(m); in seq_vprintf()
405 void seq_printf(struct seq_file *m, const char *f, ...) in seq_printf() argument
410 seq_vprintf(m, f, args); in seq_printf()
416 * mangle_path - mangle and copy path to buffer beginning
448 * seq_path - seq_file interface to print a pathname
449 * @m: the seq_file handle
456 int seq_path(struct seq_file *m, const struct path *path, const char *esc) in seq_path() argument
459 size_t size = seq_get_buf(m, &buf); in seq_path()
460 int res = -1; in seq_path()
467 res = end - buf; in seq_path()
470 seq_commit(m, res); in seq_path()
477 * seq_file_path - seq_file interface to print a pathname of a file
478 * @m: the seq_file handle
484 int seq_file_path(struct seq_file *m, struct file *file, const char *esc) in seq_file_path() argument
486 return seq_path(m, &file->f_path, esc); in seq_file_path()
493 int seq_path_root(struct seq_file *m, const struct path *path, in seq_path_root() argument
497 size_t size = seq_get_buf(m, &buf); in seq_path_root()
498 int res = -ENAMETOOLONG; in seq_path_root()
510 res = end - buf; in seq_path_root()
512 res = -ENAMETOOLONG; in seq_path_root()
515 seq_commit(m, res); in seq_path_root()
517 return res < 0 && res != -ENAMETOOLONG ? res : 0; in seq_path_root()
523 int seq_dentry(struct seq_file *m, struct dentry *dentry, const char *esc) in seq_dentry() argument
526 size_t size = seq_get_buf(m, &buf); in seq_dentry()
527 int res = -1; in seq_dentry()
534 res = end - buf; in seq_dentry()
537 seq_commit(m, res); in seq_dentry()
562 int res = -ENOMEM; in single_open()
565 op->start = single_start; in single_open()
566 op->next = single_next; in single_open()
567 op->stop = single_stop; in single_open()
568 op->show = show; in single_open()
571 ((struct seq_file *)file->private_data)->private = data; in single_open()
585 return -ENOMEM; in single_open_size()
591 ((struct seq_file *)file->private_data)->buf = buf; in single_open_size()
592 ((struct seq_file *)file->private_data)->size = size; in single_open_size()
599 const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; in single_release()
608 struct seq_file *seq = file->private_data; in seq_release_private()
610 kfree(seq->private); in seq_release_private()
611 seq->private = NULL; in seq_release_private()
631 seq = f->private_data; in __seq_open_private()
632 seq->private = private; in __seq_open_private()
645 return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM; in seq_open_private()
649 void seq_putc(struct seq_file *m, char c) in seq_putc() argument
651 if (m->count >= m->size) in seq_putc()
654 m->buf[m->count++] = c; in seq_putc()
658 void seq_puts(struct seq_file *m, const char *s) in seq_puts() argument
662 if (m->count + len >= m->size) { in seq_puts()
663 seq_set_overflow(m); in seq_puts()
666 memcpy(m->buf + m->count, s, len); in seq_puts()
667 m->count += len; in seq_puts()
674 * @m: seq_file identifying the buffer to which data should be written
683 void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter, in seq_put_decimal_ull_width() argument
688 if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */ in seq_put_decimal_ull_width()
693 seq_putc(m, delimiter[0]); in seq_put_decimal_ull_width()
695 seq_puts(m, delimiter); in seq_put_decimal_ull_width()
701 if (m->count + width >= m->size) in seq_put_decimal_ull_width()
704 len = num_to_str(m->buf + m->count, m->size - m->count, num, width); in seq_put_decimal_ull_width()
708 m->count += len; in seq_put_decimal_ull_width()
712 seq_set_overflow(m); in seq_put_decimal_ull_width()
715 void seq_put_decimal_ull(struct seq_file *m, const char *delimiter, in seq_put_decimal_ull() argument
718 return seq_put_decimal_ull_width(m, delimiter, num, 0); in seq_put_decimal_ull()
723 * seq_put_hex_ll - put a number in hexadecimal notation
724 * @m: seq_file identifying the buffer to which data should be written
729 * seq_put_hex_ll(m, "", v, 8) is equal to seq_printf(m, "%08llx", v)
734 void seq_put_hex_ll(struct seq_file *m, const char *delimiter, in seq_put_hex_ll() argument
742 seq_putc(m, delimiter[0]); in seq_put_hex_ll()
744 seq_puts(m, delimiter); in seq_put_hex_ll()
751 len = (sizeof(v) * 8 - __builtin_clzll(v) + 3) / 4; in seq_put_hex_ll()
756 if (m->count + len > m->size) { in seq_put_hex_ll()
757 seq_set_overflow(m); in seq_put_hex_ll()
761 for (i = len - 1; i >= 0; i--) { in seq_put_hex_ll()
762 m->buf[m->count + i] = hex_asc[0xf & v]; in seq_put_hex_ll()
765 m->count += len; in seq_put_hex_ll()
768 void seq_put_decimal_ll(struct seq_file *m, const char *delimiter, long long num) in seq_put_decimal_ll() argument
772 if (m->count + 3 >= m->size) /* we'll write 2 bytes at least */ in seq_put_decimal_ll()
777 seq_putc(m, delimiter[0]); in seq_put_decimal_ll()
779 seq_puts(m, delimiter); in seq_put_decimal_ll()
782 if (m->count + 2 >= m->size) in seq_put_decimal_ll()
786 m->buf[m->count++] = '-'; in seq_put_decimal_ll()
787 num = -num; in seq_put_decimal_ll()
791 m->buf[m->count++] = num + '0'; in seq_put_decimal_ll()
795 len = num_to_str(m->buf + m->count, m->size - m->count, num, 0); in seq_put_decimal_ll()
799 m->count += len; in seq_put_decimal_ll()
803 seq_set_overflow(m); in seq_put_decimal_ll()
808 * seq_write - write arbitrary data to buffer
813 * Return 0 on success, non-zero otherwise.
817 if (seq->count + len < seq->size) { in seq_write()
818 memcpy(seq->buf + seq->count, data, len); in seq_write()
819 seq->count += len; in seq_write()
823 return -1; in seq_write()
828 * seq_pad - write padding spaces to buffer
829 * @m: seq_file identifying the buffer to which data should be written
830 * @c: the byte to append after padding if non-zero
832 void seq_pad(struct seq_file *m, char c) in seq_pad() argument
834 int size = m->pad_until - m->count; in seq_pad()
836 if (size + m->count > m->size) { in seq_pad()
837 seq_set_overflow(m); in seq_pad()
840 memset(m->buf + m->count, ' ', size); in seq_pad()
841 m->count += size; in seq_pad()
844 seq_putc(m, c); in seq_pad()
849 void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type, in seq_hex_dump() argument
862 for (i = 0; i < len && !seq_has_overflowed(m); i += rowsize) { in seq_hex_dump()
864 remaining -= rowsize; in seq_hex_dump()
868 seq_printf(m, "%s%p: ", prefix_str, ptr + i); in seq_hex_dump()
871 seq_printf(m, "%s%.8x: ", prefix_str, i); in seq_hex_dump()
874 seq_printf(m, "%s", prefix_str); in seq_hex_dump()
878 size = seq_get_buf(m, &buffer); in seq_hex_dump()
881 seq_commit(m, ret < size ? ret : -1); in seq_hex_dump()
883 seq_putc(m, '\n'); in seq_hex_dump()
893 if (pos-- == 0) in seq_list_start()
905 return seq_list_start(head, pos - 1); in seq_list_start_head()
913 lh = ((struct list_head *)v)->next; in seq_list_next()
920 * seq_hlist_start - start an iteration of a hlist
924 * Called at seq_file->op->start().
931 if (pos-- == 0) in seq_hlist_start()
938 * seq_hlist_start_head - start an iteration of a hlist
942 * Called at seq_file->op->start(). Call this function if you want to
950 return seq_hlist_start(head, pos - 1); in seq_hlist_start_head()
955 * seq_hlist_next - move to the next position of the hlist
960 * Called at seq_file->op->next().
969 return head->first; in seq_hlist_next()
971 return node->next; in seq_hlist_next()
976 * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
980 * Called at seq_file->op->start().
982 * This list-traversal primitive may safely run concurrently with
983 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
992 if (pos-- == 0) in seq_hlist_start_rcu()
999 * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
1003 * Called at seq_file->op->start(). Call this function if you want to
1006 * This list-traversal primitive may safely run concurrently with
1007 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1016 return seq_hlist_start_rcu(head, pos - 1); in seq_hlist_start_head_rcu()
1021 * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
1026 * Called at seq_file->op->next().
1028 * This list-traversal primitive may safely run concurrently with
1029 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1040 return rcu_dereference(head->first); in seq_hlist_next_rcu()
1042 return rcu_dereference(node->next); in seq_hlist_next_rcu()
1047 * seq_hlist_start_precpu - start an iteration of a percpu hlist array
1052 * Called at seq_file->op->start().
1061 if (pos-- == 0) in seq_hlist_start_percpu()
1070 * seq_hlist_next_percpu - move to the next position of the percpu hlist array
1076 * Called at seq_file->op->next().
1086 if (node->next) in seq_hlist_next_percpu()
1087 return node->next; in seq_hlist_next_percpu()
1094 return bucket->first; in seq_hlist_next_percpu()