return ERR_PTR(-ENOMEM);
}
- return tr->dir;
+ return NULL;
}
-static __init int tracer_init_debugfs(void)
+ extern struct trace_enum_map *__start_ftrace_enum_maps[];
+ extern struct trace_enum_map *__stop_ftrace_enum_maps[];
+
+ static void __init trace_enum_init(void)
+ {
+ int len;
+
+ len = __stop_ftrace_enum_maps - __start_ftrace_enum_maps;
+ trace_insert_enum_map(NULL, __start_ftrace_enum_maps, len);
+ }
+
+ #ifdef CONFIG_MODULES
+ static void trace_module_add_enums(struct module *mod)
+ {
+ if (!mod->num_trace_enums)
+ return;
+
+ /*
+ * Modules with bad taint do not have events created, do
+ * not bother with enums either.
+ */
+ if (trace_module_has_bad_taint(mod))
+ return;
+
+ trace_insert_enum_map(mod, mod->trace_enums, mod->num_trace_enums);
+ }
+
+ #ifdef CONFIG_TRACE_ENUM_MAP_FILE
+ static void trace_module_remove_enums(struct module *mod)
+ {
+ union trace_enum_map_item *map;
+ union trace_enum_map_item **last = &trace_enum_maps;
+
+ if (!mod->num_trace_enums)
+ return;
+
+ mutex_lock(&trace_enum_mutex);
+
+ map = trace_enum_maps;
+
+ while (map) {
+ if (map->head.mod == mod)
+ break;
+ map = trace_enum_jmp_to_tail(map);
+ last = &map->tail.next;
+ map = map->tail.next;
+ }
+ if (!map)
+ goto out;
+
+ *last = trace_enum_jmp_to_tail(map)->tail.next;
+ kfree(map);
+ out:
+ mutex_unlock(&trace_enum_mutex);
+ }
+ #else
+ static inline void trace_module_remove_enums(struct module *mod) { }
+ #endif /* CONFIG_TRACE_ENUM_MAP_FILE */
+
+ static int trace_module_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+ {
+ struct module *mod = data;
+
+ switch (val) {
+ case MODULE_STATE_COMING:
+ trace_module_add_enums(mod);
+ break;
+ case MODULE_STATE_GOING:
+ trace_module_remove_enums(mod);
+ break;
+ }
+
+ return 0;
+ }
+
+ static struct notifier_block trace_module_nb = {
+ .notifier_call = trace_module_notify,
+ .priority = 0,
+ };
+ #endif /* CONFIG_MODULES */
+
+static __init int tracer_init_tracefs(void)
{
struct dentry *d_tracer;