diff options
Diffstat (limited to 'kernel/trace/trace_output.c')
| -rw-r--r-- | kernel/trace/trace_output.c | 75 | 
1 files changed, 61 insertions, 14 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index b6c12c6a1bc..8e46b3323cd 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -23,13 +23,21 @@ static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;  static int next_event_type = __TRACE_LAST_TYPE + 1; -void trace_print_seq(struct seq_file *m, struct trace_seq *s) +int trace_print_seq(struct seq_file *m, struct trace_seq *s)  {  	int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; +	int ret; + +	ret = seq_write(m, s->buffer, len); -	seq_write(m, s->buffer, len); +	/* +	 * Only reset this buffer if we successfully wrote to the +	 * seq_file buffer. +	 */ +	if (!ret) +		trace_seq_init(s); -	trace_seq_init(s); +	return ret;  }  enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) @@ -85,7 +93,7 @@ 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); @@ -93,8 +101,10 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)  	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; @@ -119,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; @@ -139,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; @@ -167,8 +181,13 @@ 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; @@ -178,9 +197,14 @@ 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; @@ -188,9 +212,14 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)  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; @@ -203,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 @@ -220,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; @@ -233,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"); @@ -247,6 +290,7 @@ int trace_seq_path(struct trace_seq *s, struct path *path)  		return 1;  	} +	s->full = 1;  	return 0;  } @@ -373,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;  | 
