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: Joe Perches <joe@perches.com>
[ Reworked the original patch from Joe ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
Joe Perches 2014-09-29 16:08:21 -07:00 committed by Steven Rostedt
parent f114040e3e
commit 1f33c41c03
3 changed files with 30 additions and 22 deletions

View File

@ -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
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

View File

@ -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)
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 @@ Fill:
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;

View File

@ -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