diff options
| -rw-r--r-- | Documentation/filesystems/seq_file.txt | 22 | ||||
| -rw-r--r-- | fs/seq_file.c | 15 | ||||
| -rw-r--r-- | include/linux/seq_file.h | 15 |
3 files changed, 30 insertions, 22 deletions
diff --git a/Documentation/filesystems/seq_file.txt b/Documentation/filesystems/seq_file.txt index 8ea3e90ace07..b797ed38de46 100644 --- a/Documentation/filesystems/seq_file.txt +++ b/Documentation/filesystems/seq_file.txt | |||
| @@ -180,23 +180,19 @@ output must be passed to the seq_file code. Some utility functions have | |||
| 180 | been defined which make this task easy. | 180 | been defined which make this task easy. |
| 181 | 181 | ||
| 182 | Most code will simply use seq_printf(), which works pretty much like | 182 | Most code will simply use seq_printf(), which works pretty much like |
| 183 | printk(), but which requires the seq_file pointer as an argument. It is | 183 | printk(), but which requires the seq_file pointer as an argument. |
| 184 | common to ignore the return value from seq_printf(), but a function | ||
| 185 | producing complicated output may want to check that value and quit if | ||
| 186 | something non-zero is returned; an error return means that the seq_file | ||
| 187 | buffer has been filled and further output will be discarded. | ||
| 188 | 184 | ||
| 189 | For straight character output, the following functions may be used: | 185 | For straight character output, the following functions may be used: |
| 190 | 186 | ||
| 191 | int seq_putc(struct seq_file *m, char c); | 187 | seq_putc(struct seq_file *m, char c); |
| 192 | int seq_puts(struct seq_file *m, const char *s); | 188 | seq_puts(struct seq_file *m, const char *s); |
| 193 | int seq_escape(struct seq_file *m, const char *s, const char *esc); | 189 | seq_escape(struct seq_file *m, const char *s, const char *esc); |
| 194 | 190 | ||
| 195 | The first two output a single character and a string, just like one would | 191 | The first two output a single character and a string, just like one would |
| 196 | expect. seq_escape() is like seq_puts(), except that any character in s | 192 | expect. seq_escape() is like seq_puts(), except that any character in s |
| 197 | which is in the string esc will be represented in octal form in the output. | 193 | which is in the string esc will be represented in octal form in the output. |
| 198 | 194 | ||
| 199 | There is also a pair of functions for printing filenames: | 195 | There are also a pair of functions for printing filenames: |
| 200 | 196 | ||
| 201 | int seq_path(struct seq_file *m, struct path *path, char *esc); | 197 | int seq_path(struct seq_file *m, struct path *path, char *esc); |
| 202 | int seq_path_root(struct seq_file *m, struct path *path, | 198 | int seq_path_root(struct seq_file *m, struct path *path, |
| @@ -209,6 +205,14 @@ root is desired, it can be used with seq_path_root(). Note that, if it | |||
| 209 | turns out that path cannot be reached from root, the value of root will be | 205 | turns out that path cannot be reached from root, the value of root will be |
| 210 | changed in seq_file_root() to a root which *does* work. | 206 | changed in seq_file_root() to a root which *does* work. |
| 211 | 207 | ||
| 208 | A function producing complicated output may want to check | ||
| 209 | bool seq_has_overflowed(struct seq_file *m); | ||
| 210 | and avoid further seq_<output> calls if true is returned. | ||
| 211 | |||
| 212 | A true return from seq_has_overflowed means that the seq_file buffer will | ||
| 213 | be discarded and the seq_show function will attempt to allocate a larger | ||
| 214 | buffer and retry printing. | ||
| 215 | |||
| 212 | 216 | ||
| 213 | Making it all work | 217 | Making it all work |
| 214 | 218 | ||
diff --git a/fs/seq_file.c b/fs/seq_file.c index 3857b720cb1b..353948ba1c5b 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -16,17 +16,6 @@ | |||
| 16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
| 17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
| 18 | 18 | ||
| 19 | |||
| 20 | /* | ||
| 21 | * seq_files have a buffer which can may overflow. When this happens a larger | ||
| 22 | * buffer is reallocated and all the data will be printed again. | ||
| 23 | * The overflow state is true when m->count == m->size. | ||
| 24 | */ | ||
| 25 | static bool seq_overflow(struct seq_file *m) | ||
| 26 | { | ||
| 27 | return m->count == m->size; | ||
| 28 | } | ||
| 29 | |||
| 30 | static void seq_set_overflow(struct seq_file *m) | 19 | static void seq_set_overflow(struct seq_file *m) |
| 31 | { | 20 | { |
| 32 | m->count = m->size; | 21 | m->count = m->size; |
| @@ -124,7 +113,7 @@ static int traverse(struct seq_file *m, loff_t offset) | |||
| 124 | error = 0; | 113 | error = 0; |
| 125 | m->count = 0; | 114 | m->count = 0; |
| 126 | } | 115 | } |
| 127 | if (seq_overflow(m)) | 116 | if (seq_has_overflowed(m)) |
| 128 | goto Eoverflow; | 117 | goto Eoverflow; |
| 129 | if (pos + m->count > offset) { | 118 | if (pos + m->count > offset) { |
| 130 | m->from = offset - pos; | 119 | m->from = offset - pos; |
| @@ -267,7 +256,7 @@ Fill: | |||
| 267 | break; | 256 | break; |
| 268 | } | 257 | } |
| 269 | err = m->op->show(m, p); | 258 | err = m->op->show(m, p); |
| 270 | if (seq_overflow(m) || err) { | 259 | if (seq_has_overflowed(m) || err) { |
| 271 | m->count = offs; | 260 | m->count = offs; |
| 272 | if (likely(err <= 0)) | 261 | if (likely(err <= 0)) |
| 273 | break; | 262 | break; |
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 52e0097f61f0..cf6a9daaaf6d 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h | |||
| @@ -43,6 +43,21 @@ struct seq_operations { | |||
| 43 | #define SEQ_SKIP 1 | 43 | #define SEQ_SKIP 1 |
| 44 | 44 | ||
| 45 | /** | 45 | /** |
| 46 | * seq_has_overflowed - check if the buffer has overflowed | ||
| 47 | * @m: the seq_file handle | ||
| 48 | * | ||
| 49 | * seq_files have a buffer which may overflow. When this happens a larger | ||
| 50 | * buffer is reallocated and all the data will be printed again. | ||
| 51 | * The overflow state is true when m->count == m->size. | ||
| 52 | * | ||
| 53 | * Returns true if the buffer received more than it can hold. | ||
| 54 | */ | ||
| 55 | static inline bool seq_has_overflowed(struct seq_file *m) | ||
| 56 | { | ||
| 57 | return m->count == m->size; | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 46 | * seq_get_buf - get buffer to write arbitrary data to | 61 | * seq_get_buf - get buffer to write arbitrary data to |
| 47 | * @m: the seq_file handle | 62 | * @m: the seq_file handle |
| 48 | * @bufp: the beginning of the buffer is stored here | 63 | * @bufp: the beginning of the buffer is stored here |
