Skip to content

Commit

Permalink
tracing: Add full state to trace_seq
Browse files Browse the repository at this point in the history
The trace_seq buffer might fill up, and right now one needs to check the
return value of each printf into the buffer to check for that.

Instead, have the buffer keep track of whether it is full or not, and
reject more input if it is full or would have overflowed with an input
that wasn't added.

Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
jmberg authored and rostedt committed Dec 9, 2009
1 parent a63ce5b commit d184b31
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
2 changes: 2 additions & 0 deletions include/linux/trace_seq.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ struct trace_seq {
unsigned char buffer[PAGE_SIZE];
unsigned int len;
unsigned int readpos;
int full;
};

static inline void
trace_seq_init(struct trace_seq *s)
{
s->len = 0;
s->readpos = 0;
s->full = 0;
}

/*
Expand Down
61 changes: 50 additions & 11 deletions kernel/trace/trace_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,18 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
va_list ap;
int ret;

if (!len)
if (s->full || !len)
return 0;

va_start(ap, fmt);
ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
va_end(ap);

/* If we can't write it all, don't bother writing anything */
if (ret >= len)
if (ret >= len) {
s->full = 1;
return 0;
}

s->len += ret;

Expand All @@ -127,14 +129,16 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
int len = (PAGE_SIZE - 1) - s->len;
int ret;

if (!len)
if (s->full || !len)
return 0;

ret = vsnprintf(s->buffer + s->len, len, fmt, args);

/* If we can't write it all, don't bother writing anything */
if (ret >= len)
if (ret >= len) {
s->full = 1;
return 0;
}

s->len += ret;

Expand All @@ -147,14 +151,16 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
int len = (PAGE_SIZE - 1) - s->len;
int ret;

if (!len)
if (s->full || !len)
return 0;

ret = bstr_printf(s->buffer + s->len, len, fmt, binary);

/* If we can't write it all, don't bother writing anything */
if (ret >= len)
if (ret >= len) {
s->full = 1;
return 0;
}

s->len += ret;

Expand All @@ -175,9 +181,14 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
{
int len = strlen(str);

if (len > ((PAGE_SIZE - 1) - s->len))
if (s->full)
return 0;

if (len > ((PAGE_SIZE - 1) - s->len)) {
s->full = 1;
return 0;
}

memcpy(s->buffer + s->len, str, len);
s->len += len;

Expand All @@ -186,19 +197,29 @@ int trace_seq_puts(struct trace_seq *s, const char *str)

int trace_seq_putc(struct trace_seq *s, unsigned char c)
{
if (s->len >= (PAGE_SIZE - 1))
if (s->full)
return 0;

if (s->len >= (PAGE_SIZE - 1)) {
s->full = 1;
return 0;
}

s->buffer[s->len++] = c;

return 1;
}

int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
{
if (len > ((PAGE_SIZE - 1) - s->len))
if (s->full)
return 0;

if (len > ((PAGE_SIZE - 1) - s->len)) {
s->full = 1;
return 0;
}

memcpy(s->buffer + s->len, mem, len);
s->len += len;

Expand All @@ -211,6 +232,9 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
const unsigned char *data = mem;
int i, j;

if (s->full)
return 0;

#ifdef __BIG_ENDIAN
for (i = 0, j = 0; i < len; i++) {
#else
Expand All @@ -228,8 +252,13 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len)
{
void *ret;

if (len > ((PAGE_SIZE - 1) - s->len))
if (s->full)
return 0;

if (len > ((PAGE_SIZE - 1) - s->len)) {
s->full = 1;
return NULL;
}

ret = s->buffer + s->len;
s->len += len;
Expand All @@ -241,8 +270,14 @@ int trace_seq_path(struct trace_seq *s, struct path *path)
{
unsigned char *p;

if (s->len >= (PAGE_SIZE - 1))
if (s->full)
return 0;

if (s->len >= (PAGE_SIZE - 1)) {
s->full = 1;
return 0;
}

p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
if (!IS_ERR(p)) {
p = mangle_path(s->buffer + s->len, p, "\n");
Expand All @@ -255,6 +290,7 @@ int trace_seq_path(struct trace_seq *s, struct path *path)
return 1;
}

s->full = 1;
return 0;
}

Expand Down Expand Up @@ -381,6 +417,9 @@ int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
unsigned long vmstart = 0;
int ret = 1;

if (s->full)
return 0;

if (mm) {
const struct vm_area_struct *vma;

Expand Down

0 comments on commit d184b31

Please sign in to comment.