Commit 1f33c41c authored by Joe Perches's avatar Joe Perches Committed by Steven Rostedt

seq_file: Rename seq_overflow() to seq_has_overflowed() and make public

The return values of seq_printf/puts/putc are frequently misused.

Start down a path to remove all the return value uses of these
functions.

Move the seq_overflow() to a global inlined function called
seq_has_overflowed() that can be used by the users of seq_file() calls.

Update the documentation to not show return types for seq_printf
et al.  Add a description of seq_has_overflowed().

Link: http://lkml.kernel.org/p/848ac7e3d1c31cddf638a8526fa3c59fa6fdeb8a.1412031505.git.joe@perches.com

Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJoe Perches <joe@perches.com>
[ Reworked the original patch from Joe ]
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent f114040e
...@@ -180,23 +180,19 @@ output must be passed to the seq_file code. Some utility functions have ...@@ -180,23 +180,19 @@ output must be passed to the seq_file code. Some utility functions have
been defined which make this task easy. been defined which make this task easy.
Most code will simply use seq_printf(), which works pretty much like Most code will simply use seq_printf(), which works pretty much like
printk(), but which requires the seq_file pointer as an argument. It is printk(), but which requires the seq_file pointer as an argument.
common to ignore the return value from seq_printf(), but a function
producing complicated output may want to check that value and quit if
something non-zero is returned; an error return means that the seq_file
buffer has been filled and further output will be discarded.
For straight character output, the following functions may be used: For straight character output, the following functions may be used:
int seq_putc(struct seq_file *m, char c); seq_putc(struct seq_file *m, char c);
int seq_puts(struct seq_file *m, const char *s); seq_puts(struct seq_file *m, const char *s);
int seq_escape(struct seq_file *m, const char *s, const char *esc); seq_escape(struct seq_file *m, const char *s, const char *esc);
The first two output a single character and a string, just like one would The first two output a single character and a string, just like one would
expect. seq_escape() is like seq_puts(), except that any character in s expect. seq_escape() is like seq_puts(), except that any character in s
which is in the string esc will be represented in octal form in the output. which is in the string esc will be represented in octal form in the output.
There is also a pair of functions for printing filenames: There are also a pair of functions for printing filenames:
int seq_path(struct seq_file *m, struct path *path, char *esc); int seq_path(struct seq_file *m, struct path *path, char *esc);
int seq_path_root(struct seq_file *m, struct path *path, 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,6 +205,14 @@ root is desired, it can be used with seq_path_root(). Note that, if it
turns out that path cannot be reached from root, the value of root will be turns out that path cannot be reached from root, the value of root will be
changed in seq_file_root() to a root which *does* work. changed in seq_file_root() to a root which *does* work.
A function producing complicated output may want to check
bool seq_has_overflowed(struct seq_file *m);
and avoid further seq_<output> calls if true is returned.
A true return from seq_has_overflowed means that the seq_file buffer will
be discarded and the seq_show function will attempt to allocate a larger
buffer and retry printing.
Making it all work Making it all work
......
...@@ -16,17 +16,6 @@ ...@@ -16,17 +16,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/page.h> #include <asm/page.h>
/*
* seq_files have a buffer which can may overflow. When this happens a larger
* buffer is reallocated and all the data will be printed again.
* The overflow state is true when m->count == m->size.
*/
static bool seq_overflow(struct seq_file *m)
{
return m->count == m->size;
}
static void seq_set_overflow(struct seq_file *m) static void seq_set_overflow(struct seq_file *m)
{ {
m->count = m->size; m->count = m->size;
...@@ -124,7 +113,7 @@ static int traverse(struct seq_file *m, loff_t offset) ...@@ -124,7 +113,7 @@ static int traverse(struct seq_file *m, loff_t offset)
error = 0; error = 0;
m->count = 0; m->count = 0;
} }
if (seq_overflow(m)) if (seq_has_overflowed(m))
goto Eoverflow; goto Eoverflow;
if (pos + m->count > offset) { if (pos + m->count > offset) {
m->from = offset - pos; m->from = offset - pos;
...@@ -267,7 +256,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) ...@@ -267,7 +256,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
break; break;
} }
err = m->op->show(m, p); err = m->op->show(m, p);
if (seq_overflow(m) || err) { if (seq_has_overflowed(m) || err) {
m->count = offs; m->count = offs;
if (likely(err <= 0)) if (likely(err <= 0))
break; break;
......
...@@ -42,6 +42,21 @@ struct seq_operations { ...@@ -42,6 +42,21 @@ struct seq_operations {
#define SEQ_SKIP 1 #define SEQ_SKIP 1
/**
* seq_has_overflowed - check if the buffer has overflowed
* @m: the seq_file handle
*
* seq_files have a buffer which may overflow. When this happens a larger
* buffer is reallocated and all the data will be printed again.
* The overflow state is true when m->count == m->size.
*
* Returns true if the buffer received more than it can hold.
*/
static inline bool seq_has_overflowed(struct seq_file *m)
{
return m->count == m->size;
}
/** /**
* seq_get_buf - get buffer to write arbitrary data to * seq_get_buf - get buffer to write arbitrary data to
* @m: the seq_file handle * @m: the seq_file handle
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment