Lines Matching +full:count +full:- +full:width

1 // SPDX-License-Identifier: GPL-2.0
6 * initial implementation -- AV, Oct 2001.
30 m->count = m->size; in seq_set_overflow()
42 * seq_open - initialize sequential file
47 * by @op. @op->start() sets the iterator up and returns the first
48 * element of sequence. @op->stop() shuts it down. @op->next()
49 * returns the next element of sequence. @op->show() prints element
50 * into the buffer. In case of error ->start() and ->next() return
51 * ERR_PTR(error). In the end of sequence they return %NULL. ->show()
55 * pointer in @file->private_data. This pointer should not be modified.
61 WARN_ON(file->private_data); in seq_open()
65 return -ENOMEM; in seq_open()
67 file->private_data = p; in seq_open()
69 mutex_init(&p->lock); in seq_open()
70 p->op = op; in seq_open()
74 p->file = file; in seq_open()
85 file->f_mode &= ~FMODE_PWRITE; in seq_open()
96 m->index = 0; in traverse()
97 m->count = m->from = 0; in traverse()
101 if (!m->buf) { in traverse()
102 m->buf = seq_buf_alloc(m->size = PAGE_SIZE); in traverse()
103 if (!m->buf) in traverse()
104 return -ENOMEM; in traverse()
106 p = m->op->start(m, &m->index); in traverse()
111 error = m->op->show(m, p); in traverse()
116 m->count = 0; in traverse()
120 p = m->op->next(m, p, &m->index); in traverse()
121 if (pos + m->count > offset) { in traverse()
122 m->from = offset - pos; in traverse()
123 m->count -= m->from; in traverse()
126 pos += m->count; in traverse()
127 m->count = 0; in traverse()
131 m->op->stop(m, p); in traverse()
135 m->op->stop(m, p); in traverse()
136 kvfree(m->buf); in traverse()
137 m->count = 0; in traverse()
138 m->buf = seq_buf_alloc(m->size <<= 1); in traverse()
139 return !m->buf ? -ENOMEM : -EAGAIN; in traverse()
143 * seq_read - ->read() method for sequential files.
149 * Ready-made ->f_op->read()
169 * Ready-made ->f_op->read_iter()
173 struct seq_file *m = iocb->ki_filp->private_data; in seq_read_iter()
182 mutex_lock(&m->lock); in seq_read_iter()
188 if (iocb->ki_pos == 0) { in seq_read_iter()
189 m->index = 0; in seq_read_iter()
190 m->count = 0; in seq_read_iter()
194 if (unlikely(iocb->ki_pos != m->read_pos)) { in seq_read_iter()
195 while ((err = traverse(m, iocb->ki_pos)) == -EAGAIN) in seq_read_iter()
199 m->read_pos = 0; in seq_read_iter()
200 m->index = 0; in seq_read_iter()
201 m->count = 0; in seq_read_iter()
204 m->read_pos = iocb->ki_pos; in seq_read_iter()
209 if (!m->buf) { in seq_read_iter()
210 m->buf = seq_buf_alloc(m->size = PAGE_SIZE); in seq_read_iter()
211 if (!m->buf) in seq_read_iter()
214 // something left in the buffer - copy it out first in seq_read_iter()
215 if (m->count) { in seq_read_iter()
216 n = copy_to_iter(m->buf + m->from, m->count, iter); in seq_read_iter()
217 m->count -= n; in seq_read_iter()
218 m->from += n; in seq_read_iter()
220 if (m->count) // hadn't managed to copy everything in seq_read_iter()
223 // get a non-empty record in the buffer in seq_read_iter()
224 m->from = 0; in seq_read_iter()
225 p = m->op->start(m, &m->index); in seq_read_iter()
230 err = m->op->show(m, p); in seq_read_iter()
233 if (unlikely(err)) // ->show() says "skip it" in seq_read_iter()
234 m->count = 0; in seq_read_iter()
235 if (unlikely(!m->count)) { // empty record in seq_read_iter()
236 p = m->op->next(m, p, &m->index); in seq_read_iter()
242 m->op->stop(m, p); in seq_read_iter()
243 kvfree(m->buf); in seq_read_iter()
244 m->count = 0; in seq_read_iter()
245 m->buf = seq_buf_alloc(m->size <<= 1); in seq_read_iter()
246 if (!m->buf) in seq_read_iter()
248 p = m->op->start(m, &m->index); in seq_read_iter()
251 m->op->stop(m, p); in seq_read_iter()
252 m->count = 0; in seq_read_iter()
255 // one non-empty record is in the buffer; if they want more, in seq_read_iter()
259 size_t offs = m->count; in seq_read_iter()
260 loff_t pos = m->index; in seq_read_iter()
262 p = m->op->next(m, p, &m->index); in seq_read_iter()
263 if (pos == m->index) { in seq_read_iter()
265 m->op->next); in seq_read_iter()
266 m->index++; in seq_read_iter()
270 if (m->count >= iov_iter_count(iter)) in seq_read_iter()
272 err = m->op->show(m, p); in seq_read_iter()
273 if (err > 0) { // ->show() says "skip it" in seq_read_iter()
274 m->count = offs; in seq_read_iter()
276 m->count = offs; in seq_read_iter()
280 m->op->stop(m, p); in seq_read_iter()
281 n = copy_to_iter(m->buf, m->count, iter); in seq_read_iter()
283 m->count -= n; in seq_read_iter()
284 m->from = n; in seq_read_iter()
287 copied = m->count ? -EFAULT : err; in seq_read_iter()
289 iocb->ki_pos += copied; in seq_read_iter()
290 m->read_pos += copied; in seq_read_iter()
292 mutex_unlock(&m->lock); in seq_read_iter()
295 err = -ENOMEM; in seq_read_iter()
301 * seq_lseek - ->llseek() method for sequential files.
306 * Ready-made ->f_op->llseek()
310 struct seq_file *m = file->private_data; in seq_lseek()
311 loff_t retval = -EINVAL; in seq_lseek()
313 mutex_lock(&m->lock); in seq_lseek()
316 offset += file->f_pos; in seq_lseek()
322 if (offset != m->read_pos) { in seq_lseek()
323 while ((retval = traverse(m, offset)) == -EAGAIN) in seq_lseek()
327 file->f_pos = 0; in seq_lseek()
328 m->read_pos = 0; in seq_lseek()
329 m->index = 0; in seq_lseek()
330 m->count = 0; in seq_lseek()
332 m->read_pos = offset; in seq_lseek()
333 retval = file->f_pos = offset; in seq_lseek()
336 file->f_pos = offset; in seq_lseek()
339 mutex_unlock(&m->lock); in seq_lseek()
345 * seq_release - free the structures associated with sequential file.
350 * as ->f_op->release() if you don't have private data to destroy.
354 struct seq_file *m = file->private_data; in seq_release()
355 kvfree(m->buf); in seq_release()
362 * seq_escape_mem - print data into buffer, escaping some characters
382 seq_commit(m, ret < size ? ret : -1); in seq_escape_mem()
390 if (m->count < m->size) { in seq_vprintf()
391 len = vsnprintf(m->buf + m->count, m->size - m->count, f, args); in seq_vprintf()
392 if (m->count + len < m->size) { in seq_vprintf()
393 m->count += len; in seq_vprintf()
416 if (m->count < m->size) { in seq_bprintf()
417 len = bstr_printf(m->buf + m->count, m->size - m->count, f, in seq_bprintf()
419 if (m->count + len < m->size) { in seq_bprintf()
420 m->count += len; in seq_bprintf()
430 * mangle_path - mangle and copy path to buffer beginning
462 * seq_path - seq_file interface to print a pathname
474 int res = -1; in seq_path()
481 res = end - buf; in seq_path()
491 * seq_file_path - seq_file interface to print a pathname of a file
500 return seq_path(m, &file->f_path, esc); in seq_file_path()
512 int res = -ENAMETOOLONG; in seq_path_root()
524 res = end - buf; in seq_path_root()
526 res = -ENAMETOOLONG; in seq_path_root()
531 return res < 0 && res != -ENAMETOOLONG ? res : 0; in seq_path_root()
541 int res = -1; in seq_dentry()
548 res = end - buf; in seq_dentry()
576 int res = -ENOMEM; in single_open()
579 op->start = single_start; in single_open()
580 op->next = single_next; in single_open()
581 op->stop = single_stop; in single_open()
582 op->show = show; in single_open()
585 ((struct seq_file *)file->private_data)->private = data; in single_open()
599 return -ENOMEM; in single_open_size()
605 ((struct seq_file *)file->private_data)->buf = buf; in single_open_size()
606 ((struct seq_file *)file->private_data)->size = size; in single_open_size()
613 const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; in single_release()
622 struct seq_file *seq = file->private_data; in seq_release_private()
624 kfree(seq->private); in seq_release_private()
625 seq->private = NULL; in seq_release_private()
645 seq = f->private_data; in __seq_open_private()
646 seq->private = private; in __seq_open_private()
659 return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM; in seq_open_private()
665 if (m->count >= m->size) in seq_putc()
668 m->buf[m->count++] = c; in seq_putc()
676 if (m->count + len >= m->size) { in seq_puts()
680 memcpy(m->buf + m->count, s, len); in seq_puts()
681 m->count += len; in seq_puts()
686 * seq_put_decimal_ull_width - A helper routine for putting decimal numbers
692 * @width: a minimum field width
699 unsigned long long num, unsigned int width) in seq_put_decimal_ull_width() argument
703 if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */ in seq_put_decimal_ull_width()
713 if (!width) in seq_put_decimal_ull_width()
714 width = 1; in seq_put_decimal_ull_width()
716 if (m->count + width >= m->size) in seq_put_decimal_ull_width()
719 len = num_to_str(m->buf + m->count, m->size - m->count, num, width); in seq_put_decimal_ull_width()
723 m->count += len; in seq_put_decimal_ull_width()
738 * seq_put_hex_ll - put a number in hexadecimal notation
742 * @width: a minimum field width
750 unsigned long long v, unsigned int width) in seq_put_hex_ll() argument
766 len = (sizeof(v) * 8 - __builtin_clzll(v) + 3) / 4; in seq_put_hex_ll()
768 if (len < width) in seq_put_hex_ll()
769 len = width; in seq_put_hex_ll()
771 if (m->count + len > m->size) { in seq_put_hex_ll()
776 for (i = len - 1; i >= 0; i--) { in seq_put_hex_ll()
777 m->buf[m->count + i] = hex_asc[0xf & v]; in seq_put_hex_ll()
780 m->count += len; in seq_put_hex_ll()
787 if (m->count + 3 >= m->size) /* we'll write 2 bytes at least */ in seq_put_decimal_ll()
797 if (m->count + 2 >= m->size) in seq_put_decimal_ll()
801 m->buf[m->count++] = '-'; in seq_put_decimal_ll()
802 num = -num; in seq_put_decimal_ll()
806 m->buf[m->count++] = num + '0'; in seq_put_decimal_ll()
810 len = num_to_str(m->buf + m->count, m->size - m->count, num, 0); in seq_put_decimal_ll()
814 m->count += len; in seq_put_decimal_ll()
823 * seq_write - write arbitrary data to buffer
828 * Return 0 on success, non-zero otherwise.
832 if (seq->count + len < seq->size) { in seq_write()
833 memcpy(seq->buf + seq->count, data, len); in seq_write()
834 seq->count += len; in seq_write()
838 return -1; in seq_write()
843 * seq_pad - write padding spaces to buffer
845 * @c: the byte to append after padding if non-zero
849 int size = m->pad_until - m->count; in seq_pad()
851 if (size + m->count > m->size) { in seq_pad()
855 memset(m->buf + m->count, ' ', size); in seq_pad()
856 m->count += size; in seq_pad()
879 remaining -= rowsize; in seq_hex_dump()
896 seq_commit(m, ret < size ? ret : -1); in seq_hex_dump()
908 if (pos-- == 0) in seq_list_start()
920 return seq_list_start(head, pos - 1); in seq_list_start_head()
928 lh = ((struct list_head *)v)->next; in seq_list_next()
939 if (pos-- == 0) in seq_list_start_rcu()
951 return seq_list_start_rcu(head, pos - 1); in seq_list_start_head_rcu()
967 * seq_hlist_start - start an iteration of a hlist
971 * Called at seq_file->op->start().
978 if (pos-- == 0) in seq_hlist_start()
985 * seq_hlist_start_head - start an iteration of a hlist
989 * Called at seq_file->op->start(). Call this function if you want to
997 return seq_hlist_start(head, pos - 1); in seq_hlist_start_head()
1002 * seq_hlist_next - move to the next position of the hlist
1007 * Called at seq_file->op->next().
1016 return head->first; in seq_hlist_next()
1018 return node->next; in seq_hlist_next()
1023 * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
1027 * Called at seq_file->op->start().
1029 * This list-traversal primitive may safely run concurrently with
1030 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1039 if (pos-- == 0) in seq_hlist_start_rcu()
1046 * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
1050 * Called at seq_file->op->start(). Call this function if you want to
1053 * This list-traversal primitive may safely run concurrently with
1054 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1063 return seq_hlist_start_rcu(head, pos - 1); in seq_hlist_start_head_rcu()
1068 * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
1073 * Called at seq_file->op->next().
1075 * This list-traversal primitive may safely run concurrently with
1076 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
1087 return rcu_dereference(head->first); in seq_hlist_next_rcu()
1089 return rcu_dereference(node->next); in seq_hlist_next_rcu()
1094 * seq_hlist_start_percpu - start an iteration of a percpu hlist array
1099 * Called at seq_file->op->start().
1108 if (pos-- == 0) in seq_hlist_start_percpu()
1117 * seq_hlist_next_percpu - move to the next position of the percpu hlist array
1123 * Called at seq_file->op->next().
1133 if (node->next) in seq_hlist_next_percpu()
1134 return node->next; in seq_hlist_next_percpu()
1141 return bucket->first; in seq_hlist_next_percpu()