LCOV - code coverage report
Current view: top level - include/linux - seq_file.h (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 23 23 100.0 %
Date: 2023-07-31 20:08:12 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : #ifndef _LINUX_SEQ_FILE_H
       3             : #define _LINUX_SEQ_FILE_H
       4             : 
       5             : #include <linux/types.h>
       6             : #include <linux/string.h>
       7             : #include <linux/string_helpers.h>
       8             : #include <linux/bug.h>
       9             : #include <linux/mutex.h>
      10             : #include <linux/cpumask.h>
      11             : #include <linux/nodemask.h>
      12             : #include <linux/fs.h>
      13             : #include <linux/cred.h>
      14             : 
      15             : struct seq_operations;
      16             : 
      17             : struct seq_file {
      18             :         char *buf;
      19             :         size_t size;
      20             :         size_t from;
      21             :         size_t count;
      22             :         size_t pad_until;
      23             :         loff_t index;
      24             :         loff_t read_pos;
      25             :         struct mutex lock;
      26             :         const struct seq_operations *op;
      27             :         int poll_event;
      28             :         const struct file *file;
      29             :         void *private;
      30             : };
      31             : 
      32             : struct seq_operations {
      33             :         void * (*start) (struct seq_file *m, loff_t *pos);
      34             :         void (*stop) (struct seq_file *m, void *v);
      35             :         void * (*next) (struct seq_file *m, void *v, loff_t *pos);
      36             :         int (*show) (struct seq_file *m, void *v);
      37             : };
      38             : 
      39             : #define SEQ_SKIP 1
      40             : 
      41             : /**
      42             :  * seq_has_overflowed - check if the buffer has overflowed
      43             :  * @m: the seq_file handle
      44             :  *
      45             :  * seq_files have a buffer which may overflow. When this happens a larger
      46             :  * buffer is reallocated and all the data will be printed again.
      47             :  * The overflow state is true when m->count == m->size.
      48             :  *
      49             :  * Returns true if the buffer received more than it can hold.
      50             :  */
      51             : static inline bool seq_has_overflowed(struct seq_file *m)
      52             : {
      53   983327676 :         return m->count == m->size;
      54             : }
      55             : 
      56             : /**
      57             :  * seq_get_buf - get buffer to write arbitrary data to
      58             :  * @m: the seq_file handle
      59             :  * @bufp: the beginning of the buffer is stored here
      60             :  *
      61             :  * Return the number of bytes available in the buffer, or zero if
      62             :  * there's no space.
      63             :  */
      64  2779172583 : static inline size_t seq_get_buf(struct seq_file *m, char **bufp)
      65             : {
      66  2779172583 :         BUG_ON(m->count > m->size);
      67  2779172583 :         if (m->count < m->size)
      68  2779172061 :                 *bufp = m->buf + m->count;
      69             :         else
      70         522 :                 *bufp = NULL;
      71             : 
      72  2779172583 :         return m->size - m->count;
      73             : }
      74             : 
      75             : /**
      76             :  * seq_commit - commit data to the buffer
      77             :  * @m: the seq_file handle
      78             :  * @num: the number of bytes to commit
      79             :  *
      80             :  * Commit @num bytes of data written to a buffer previously acquired
      81             :  * by seq_buf_get.  To signal an error condition, or that the data
      82             :  * didn't fit in the available space, pass a negative @num value.
      83             :  */
      84             : static inline void seq_commit(struct seq_file *m, int num)
      85             : {
      86  2774961920 :         if (num < 0) {
      87      692375 :                 m->count = m->size;
      88             :         } else {
      89  2774961920 :                 BUG_ON(m->count + num > m->size);
      90  2774961920 :                 m->count += num;
      91             :         }
      92             : }
      93             : 
      94             : /**
      95             :  * seq_setwidth - set padding width
      96             :  * @m: the seq_file handle
      97             :  * @size: the max number of bytes to pad.
      98             :  *
      99             :  * Call seq_setwidth() for setting max width, then call seq_printf() etc. and
     100             :  * finally call seq_pad() to pad the remaining bytes.
     101             :  */
     102             : static inline void seq_setwidth(struct seq_file *m, size_t size)
     103             : {
     104             :         m->pad_until = m->count + size;
     105             : }
     106             : void seq_pad(struct seq_file *m, char c);
     107             : 
     108             : char *mangle_path(char *s, const char *p, const char *esc);
     109             : int seq_open(struct file *, const struct seq_operations *);
     110             : ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
     111             : ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     112             : loff_t seq_lseek(struct file *, loff_t, int);
     113             : int seq_release(struct inode *, struct file *);
     114             : int seq_write(struct seq_file *seq, const void *data, size_t len);
     115             : 
     116             : __printf(2, 0)
     117             : void seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
     118             : __printf(2, 3)
     119             : void seq_printf(struct seq_file *m, const char *fmt, ...);
     120             : void seq_putc(struct seq_file *m, char c);
     121             : void seq_puts(struct seq_file *m, const char *s);
     122             : void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter,
     123             :                                unsigned long long num, unsigned int width);
     124             : void seq_put_decimal_ull(struct seq_file *m, const char *delimiter,
     125             :                          unsigned long long num);
     126             : void seq_put_decimal_ll(struct seq_file *m, const char *delimiter, long long num);
     127             : void seq_put_hex_ll(struct seq_file *m, const char *delimiter,
     128             :                     unsigned long long v, unsigned int width);
     129             : 
     130             : void seq_escape_mem(struct seq_file *m, const char *src, size_t len,
     131             :                     unsigned int flags, const char *esc);
     132             : 
     133  1429818805 : static inline void seq_escape_str(struct seq_file *m, const char *src,
     134             :                                   unsigned int flags, const char *esc)
     135             : {
     136  2859637610 :         seq_escape_mem(m, src, strlen(src), flags, esc);
     137  1430826995 : }
     138             : 
     139             : /**
     140             :  * seq_escape - print string into buffer, escaping some characters
     141             :  * @m: target buffer
     142             :  * @s: NULL-terminated string
     143             :  * @esc: set of characters that need escaping
     144             :  *
     145             :  * Puts string into buffer, replacing each occurrence of character from
     146             :  * @esc with usual octal escape.
     147             :  *
     148             :  * Use seq_has_overflowed() to check for errors.
     149             :  */
     150             : static inline void seq_escape(struct seq_file *m, const char *s, const char *esc)
     151             : {
     152  1430432425 :         seq_escape_str(m, s, ESCAPE_OCTAL, esc);
     153     7200521 : }
     154             : 
     155             : void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
     156             :                   int rowsize, int groupsize, const void *buf, size_t len,
     157             :                   bool ascii);
     158             : 
     159             : int seq_path(struct seq_file *, const struct path *, const char *);
     160             : int seq_file_path(struct seq_file *, struct file *, const char *);
     161             : int seq_dentry(struct seq_file *, struct dentry *, const char *);
     162             : int seq_path_root(struct seq_file *m, const struct path *path,
     163             :                   const struct path *root, const char *esc);
     164             : 
     165             : void *single_start(struct seq_file *, loff_t *);
     166             : int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
     167             : int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t);
     168             : int single_release(struct inode *, struct file *);
     169             : void *__seq_open_private(struct file *, const struct seq_operations *, int);
     170             : int seq_open_private(struct file *, const struct seq_operations *, int);
     171             : int seq_release_private(struct inode *, struct file *);
     172             : 
     173             : #ifdef CONFIG_BINARY_PRINTF
     174             : void seq_bprintf(struct seq_file *m, const char *f, const u32 *binary);
     175             : #endif
     176             : 
     177             : #define DEFINE_SEQ_ATTRIBUTE(__name)                                    \
     178             : static int __name ## _open(struct inode *inode, struct file *file)      \
     179             : {                                                                       \
     180             :         int ret = seq_open(file, &__name ## _sops);                 \
     181             :         if (!ret && inode->i_private) {                                      \
     182             :                 struct seq_file *seq_f = file->private_data;         \
     183             :                 seq_f->private = inode->i_private;                        \
     184             :         }                                                               \
     185             :         return ret;                                                     \
     186             : }                                                                       \
     187             :                                                                         \
     188             : static const struct file_operations __name ## _fops = {                 \
     189             :         .owner          = THIS_MODULE,                                  \
     190             :         .open           = __name ## _open,                              \
     191             :         .read           = seq_read,                                     \
     192             :         .llseek         = seq_lseek,                                    \
     193             :         .release        = seq_release,                                  \
     194             : }
     195             : 
     196             : #define DEFINE_SHOW_ATTRIBUTE(__name)                                   \
     197             : static int __name ## _open(struct inode *inode, struct file *file)      \
     198             : {                                                                       \
     199             :         return single_open(file, __name ## _show, inode->i_private); \
     200             : }                                                                       \
     201             :                                                                         \
     202             : static const struct file_operations __name ## _fops = {                 \
     203             :         .owner          = THIS_MODULE,                                  \
     204             :         .open           = __name ## _open,                              \
     205             :         .read           = seq_read,                                     \
     206             :         .llseek         = seq_lseek,                                    \
     207             :         .release        = single_release,                               \
     208             : }
     209             : 
     210             : #define DEFINE_PROC_SHOW_ATTRIBUTE(__name)                              \
     211             : static int __name ## _open(struct inode *inode, struct file *file)      \
     212             : {                                                                       \
     213             :         return single_open(file, __name ## _show, pde_data(inode));     \
     214             : }                                                                       \
     215             :                                                                         \
     216             : static const struct proc_ops __name ## _proc_ops = {                    \
     217             :         .proc_open      = __name ## _open,                              \
     218             :         .proc_read      = seq_read,                                     \
     219             :         .proc_lseek     = seq_lseek,                                    \
     220             :         .proc_release   = single_release,                               \
     221             : }
     222             : 
     223             : static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
     224             : {
     225             : #ifdef CONFIG_USER_NS
     226             :         return seq->file->f_cred->user_ns;
     227             : #else
     228             :         extern struct user_namespace init_user_ns;
     229             :         return &init_user_ns;
     230             : #endif
     231             : }
     232             : 
     233             : /**
     234             :  * seq_show_options - display mount options with appropriate escapes.
     235             :  * @m: the seq_file handle
     236             :  * @name: the mount option name
     237             :  * @value: the mount option name's value, can be NULL
     238             :  */
     239     7200375 : static inline void seq_show_option(struct seq_file *m, const char *name,
     240             :                                    const char *value)
     241             : {
     242     7200375 :         seq_putc(m, ',');
     243     7193938 :         seq_escape(m, name, ",= \t\n\\");
     244     7199578 :         if (value) {
     245     7199578 :                 seq_putc(m, '=');
     246     7204835 :                 seq_escape(m, value, ", \t\n\\");
     247             :         }
     248     7200521 : }
     249             : 
     250             : /**
     251             :  * seq_show_option_n - display mount options with appropriate escapes
     252             :  *                     where @value must be a specific length.
     253             :  * @m: the seq_file handle
     254             :  * @name: the mount option name
     255             :  * @value: the mount option name's value, cannot be NULL
     256             :  * @length: the length of @value to display
     257             :  *
     258             :  * This is a macro since this uses "length" to define the size of the
     259             :  * stack buffer.
     260             :  */
     261             : #define seq_show_option_n(m, name, value, length) {     \
     262             :         char val_buf[length + 1];                       \
     263             :         strncpy(val_buf, value, length);                \
     264             :         val_buf[length] = '\0';                         \
     265             :         seq_show_option(m, name, val_buf);              \
     266             : }
     267             : 
     268             : #define SEQ_START_TOKEN ((void *)1)
     269             : /*
     270             :  * Helpers for iteration over list_head-s in seq_files
     271             :  */
     272             : 
     273             : extern struct list_head *seq_list_start(struct list_head *head,
     274             :                 loff_t pos);
     275             : extern struct list_head *seq_list_start_head(struct list_head *head,
     276             :                 loff_t pos);
     277             : extern struct list_head *seq_list_next(void *v, struct list_head *head,
     278             :                 loff_t *ppos);
     279             : 
     280             : extern struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos);
     281             : extern struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos);
     282             : extern struct list_head *seq_list_next_rcu(void *v, struct list_head *head, loff_t *ppos);
     283             : 
     284             : /*
     285             :  * Helpers for iteration over hlist_head-s in seq_files
     286             :  */
     287             : 
     288             : extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
     289             :                                           loff_t pos);
     290             : extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
     291             :                                                loff_t pos);
     292             : extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
     293             :                                          loff_t *ppos);
     294             : 
     295             : extern struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
     296             :                                               loff_t pos);
     297             : extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
     298             :                                                    loff_t pos);
     299             : extern struct hlist_node *seq_hlist_next_rcu(void *v,
     300             :                                                    struct hlist_head *head,
     301             :                                                    loff_t *ppos);
     302             : 
     303             : /* Helpers for iterating over per-cpu hlist_head-s in seq_files */
     304             : extern struct hlist_node *seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos);
     305             : 
     306             : extern struct hlist_node *seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head, int *cpu, loff_t *pos);
     307             : 
     308             : void seq_file_init(void);
     309             : #endif

Generated by: LCOV version 1.14