{
        OP_OR,
        OP_AND,
+       OP_GLOB,
        OP_NE,
        OP_EQ,
        OP_LT,
 };
 
 static struct filter_op filter_ops[] = {
-       { OP_OR, "||", 1 },
-       { OP_AND, "&&", 2 },
-       { OP_NE, "!=", 4 },
-       { OP_EQ, "==", 4 },
-       { OP_LT, "<", 5 },
-       { OP_LE, "<=", 5 },
-       { OP_GT, ">", 5 },
-       { OP_GE, ">=", 5 },
-       { OP_NONE, "OP_NONE", 0 },
-       { OP_OPEN_PAREN, "(", 0 },
+       { OP_OR,        "||",           1 },
+       { OP_AND,       "&&",           2 },
+       { OP_GLOB,      "~",            4 },
+       { OP_NE,        "!=",           4 },
+       { OP_EQ,        "==",           4 },
+       { OP_LT,        "<",            5 },
+       { OP_LE,        "<=",           5 },
+       { OP_GT,        ">",            5 },
+       { OP_GE,        ">=",           5 },
+       { OP_NONE,      "OP_NONE",      0 },
+       { OP_OPEN_PAREN, "(",           0 },
 };
 
 enum {
        return type;
 }
 
-static int filter_build_regex(struct filter_pred *pred)
+static void filter_build_regex(struct filter_pred *pred)
 {
        struct regex *r = &pred->regex;
-       char *search, *dup;
-       enum regex_type type;
-       int not;
-
-       type = filter_parse_regex(r->pattern, r->len, &search, ¬);
-       dup = kstrdup(search, GFP_KERNEL);
-       if (!dup)
-               return -ENOMEM;
-
-       strcpy(r->pattern, dup);
-       kfree(dup);
-
-       r->len = strlen(r->pattern);
+       char *search;
+       enum regex_type type = MATCH_FULL;
+       int not = 0;
+
+       if (pred->op == OP_GLOB) {
+               type = filter_parse_regex(r->pattern, r->len, &search, ¬);
+               r->len = strlen(search);
+               memmove(r->pattern, search, r->len+1);
+       }
 
        switch (type) {
        case MATCH_FULL:
        }
 
        pred->not ^= not;
-
-       return 0;
 }
 
 /* return 1 if event matches, 0 otherwise (discard) */
 
 static int is_legal_op(struct ftrace_event_field *field, int op)
 {
-       if (is_string_field(field) && (op != OP_EQ && op != OP_NE))
+       if (is_string_field(field) &&
+           (op != OP_EQ && op != OP_NE && op != OP_GLOB))
+               return 0;
+       if (!is_string_field(field) && op == OP_GLOB)
                return 0;
 
        return 1;
        }
 
        if (is_string_field(field)) {
-               ret = filter_build_regex(pred);
-               if (ret)
-                       return ret;
+               filter_build_regex(pred);
 
                if (field->filter_type == FILTER_STATIC_STRING) {
                        fn = filter_pred_string;
                        pred->regex.field_len = field->size;
                } else if (field->filter_type == FILTER_DYN_STRING)
-                               fn = filter_pred_strloc;
+                       fn = filter_pred_strloc;
                else {
                        fn = filter_pred_pchar;
                        pred->regex.field_len = strlen(pred->regex.pattern);