[RFC][PATCH v2 5/7] trace: make filter_parse_regex() provide the length of substring to compare with

From: Al Viro
Date: Thu Feb 05 2015 - 23:01:46 EST


From: Al Viro <viro@xxxxxxxxxxxxxxxxxx>

By this point the only thing that cares about
NUL-termination of substring found by filter_parse_regex() is
strlen() done immediately by all its callers. Once we have found
the length, that's it - we won't be looking at more than that
many bytes in the substring in question.

This commit consolidates those strlen() calls into one
done by filter_parse_regex() itself. To report the length to the
callers, we switch to passing 'len' argument of filter_parse_regex()
by address and use it to pass the length of our substring on the
way out.

The next commit will eliminate modifying the string
completely - filter_parse_regex() has enough information to find
the length of the substring without bothering with this strlen()
call.

Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
---
kernel/trace/ftrace.c | 24 +++++++++---------------
kernel/trace/trace.h | 2 +-
kernel/trace/trace_events_filter.c | 10 +++++-----
3 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a369a54..f640458 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3441,7 +3441,6 @@ static int
match_records(struct ftrace_hash *hash, char *buff,
int len, char *mod, int not)
{
- unsigned search_len = 0;
struct ftrace_page *pg;
struct dyn_ftrace *rec;
int type = MATCH_FULL;
@@ -3449,10 +3448,8 @@ match_records(struct ftrace_hash *hash, char *buff,
int found = 0;
int ret;

- if (len) {
- type = filter_parse_regex(buff, len, &search, &not);
- search_len = strlen(search);
- }
+ if (len)
+ type = filter_parse_regex(buff, &len, &search, &not);

mutex_lock(&ftrace_lock);

@@ -3460,7 +3457,7 @@ match_records(struct ftrace_hash *hash, char *buff,
goto out_unlock;

do_for_each_ftrace_rec(pg, rec) {
- if (ftrace_match_record(rec, mod, search, search_len, type)) {
+ if (ftrace_match_record(rec, mod, search, len, type)) {
ret = enter_record(hash, rec, not);
if (ret < 0) {
found = ret;
@@ -3648,14 +3645,13 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
struct ftrace_hash *hash;
struct ftrace_page *pg;
struct dyn_ftrace *rec;
- int type, len, not;
+ int type, len = strlen(glob), not;
unsigned long key;
int count = 0;
char *search;
int ret;

- type = filter_parse_regex(glob, strlen(glob), &search, &not);
- len = strlen(search);
+ type = filter_parse_regex(glob, &len, &search, &not);

/* we do not support '!' for function probes */
if (WARN_ON(not))
@@ -3768,9 +3764,9 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,

if (glob && *glob && strcmp(glob, "*") != 0) {
int not;
+ len = strlen(glob);

- type = filter_parse_regex(glob, strlen(glob), &search, &not);
- len = strlen(search);
+ type = filter_parse_regex(glob, &len, &search, &not);

/* we do not support '!' for function probes */
if (WARN_ON(not))
@@ -4549,7 +4545,7 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
{
struct dyn_ftrace *rec;
struct ftrace_page *pg;
- int search_len;
+ int search_len = strlen(buffer);
int fail = 1;
int type, not;
char *search;
@@ -4557,12 +4553,10 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
int i;

/* decode regex */
- type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
+ type = filter_parse_regex(buffer, &search_len, &search, &not);
if (!not && *idx >= size)
return -EBUSY;

- search_len = strlen(search);
-
mutex_lock(&ftrace_lock);

if (unlikely(ftrace_disabled)) {
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 8de48ba..7483205 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1051,7 +1051,7 @@ struct filter_pred {
};

extern enum regex_type
-filter_parse_regex(char *buff, int len, char **search, int *not);
+filter_parse_regex(char *buff, int *len, char **search, int *not);
extern void print_event_filter(struct ftrace_event_file *file,
struct trace_seq *s);
extern int apply_event_filter(struct ftrace_event_file *file,
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 6c4a96b..6a659e1 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -321,7 +321,7 @@ static int regex_match_end(char *str, struct regex *r, int len)
* not returns 1 if buff started with a '!'
* 0 otherwise.
*/
-enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
+enum regex_type filter_parse_regex(char *buff, int *len, char **search, int *not)
{
int type = MATCH_FULL;
int i;
@@ -329,13 +329,13 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
if (buff[0] == '!') {
*not = 1;
buff++;
- len--;
+ (*len)--;
} else
*not = 0;

*search = buff;

- for (i = 0; i < len; i++) {
+ for (i = 0; i < *len; i++) {
if (buff[i] == '*') {
if (!i) {
*search = buff + 1;
@@ -350,6 +350,7 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
}
}
}
+ *len = strlen(*search);

return type;
}
@@ -362,8 +363,7 @@ static void filter_build_regex(struct filter_pred *pred)
int not = 0;

if (pred->op == OP_GLOB) {
- type = filter_parse_regex(r->pattern, r->len, &search, &not);
- r->len = strlen(search);
+ type = filter_parse_regex(r->pattern, &r->len, &search, &not);
memmove(r->pattern, search, r->len+1);
}

--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/