Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */ 2 : : #ifndef _LINUX_SEQ_BUF_H 3 : : #define _LINUX_SEQ_BUF_H 4 : : 5 : : #include <linux/fs.h> 6 : : 7 : : /* 8 : : * Trace sequences are used to allow a function to call several other functions 9 : : * to create a string of data to use. 10 : : */ 11 : : 12 : : /** 13 : : * seq_buf - seq buffer structure 14 : : * @buffer: pointer to the buffer 15 : : * @size: size of the buffer 16 : : * @len: the amount of data inside the buffer 17 : : * @readpos: The next position to read in the buffer. 18 : : */ 19 : : struct seq_buf { 20 : : char *buffer; 21 : : size_t size; 22 : : size_t len; 23 : : loff_t readpos; 24 : : }; 25 : : 26 : : static inline void seq_buf_clear(struct seq_buf *s) 27 : : { 28 : 0 : s->len = 0; 29 : 0 : s->readpos = 0; 30 : : } 31 : : 32 : : static inline void 33 : : seq_buf_init(struct seq_buf *s, unsigned char *buf, unsigned int size) 34 : : { 35 : 0 : s->buffer = buf; 36 : 0 : s->size = size; 37 : : seq_buf_clear(s); 38 : : } 39 : : 40 : : /* 41 : : * seq_buf have a buffer that might overflow. When this happens 42 : : * the len and size are set to be equal. 43 : : */ 44 : : static inline bool 45 : : seq_buf_has_overflowed(struct seq_buf *s) 46 : : { 47 : 0 : return s->len > s->size; 48 : : } 49 : : 50 : : static inline void 51 : : seq_buf_set_overflow(struct seq_buf *s) 52 : : { 53 : 0 : s->len = s->size + 1; 54 : : } 55 : : 56 : : /* 57 : : * How much buffer is left on the seq_buf? 58 : : */ 59 : : static inline unsigned int 60 : : seq_buf_buffer_left(struct seq_buf *s) 61 : : { 62 [ # # # # : 0 : if (seq_buf_has_overflowed(s)) # # # # # # ] 63 : : return 0; 64 : : 65 : 0 : return s->size - s->len; 66 : : } 67 : : 68 : : /* How much buffer was written? */ 69 : : static inline unsigned int seq_buf_used(struct seq_buf *s) 70 : : { 71 : 0 : return min(s->len, s->size); 72 : : } 73 : : 74 : : /** 75 : : * seq_buf_get_buf - get buffer to write arbitrary data to 76 : : * @s: the seq_buf handle 77 : : * @bufp: the beginning of the buffer is stored here 78 : : * 79 : : * Return the number of bytes available in the buffer, or zero if 80 : : * there's no space. 81 : : */ 82 : 0 : static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp) 83 : : { 84 [ # # ]: 0 : WARN_ON(s->len > s->size + 1); 85 : : 86 [ # # ]: 0 : if (s->len < s->size) { 87 : 0 : *bufp = s->buffer + s->len; 88 : 0 : return s->size - s->len; 89 : : } 90 : : 91 : 0 : *bufp = NULL; 92 : 0 : return 0; 93 : : } 94 : : 95 : : /** 96 : : * seq_buf_commit - commit data to the buffer 97 : : * @s: the seq_buf handle 98 : : * @num: the number of bytes to commit 99 : : * 100 : : * Commit @num bytes of data written to a buffer previously acquired 101 : : * by seq_buf_get. To signal an error condition, or that the data 102 : : * didn't fit in the available space, pass a negative @num value. 103 : : */ 104 : 0 : static inline void seq_buf_commit(struct seq_buf *s, int num) 105 : : { 106 [ # # ]: 0 : if (num < 0) { 107 : : seq_buf_set_overflow(s); 108 : : } else { 109 : : /* num must be negative on overflow */ 110 [ # # ]: 0 : BUG_ON(s->len + num > s->size); 111 : 0 : s->len += num; 112 : : } 113 : 0 : } 114 : : 115 : : extern __printf(2, 3) 116 : : int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); 117 : : extern __printf(2, 0) 118 : : int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); 119 : : extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s); 120 : : extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, 121 : : int cnt); 122 : : extern int seq_buf_puts(struct seq_buf *s, const char *str); 123 : : extern int seq_buf_putc(struct seq_buf *s, unsigned char c); 124 : : extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len); 125 : : extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, 126 : : unsigned int len); 127 : : extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc); 128 : : 129 : : #ifdef CONFIG_BINARY_PRINTF 130 : : extern int 131 : : seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary); 132 : : #endif 133 : : 134 : : #endif /* _LINUX_SEQ_BUF_H */