diff options
author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2009-07-09 04:22:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-07-10 05:55:28 -0400 |
commit | dc82ec98a4727fd51b77e92d05fe7d2db3dcc11c (patch) | |
tree | c66955e01458db480185c963304a60b6fd77c72c | |
parent | c5cb183608167c744cb28bbd85884be5a4ce875d (diff) |
tracing/filter: Remove empty subsystem and its directory
Remove empty subsystem and its directory when module unload.
Before patch:
# rmmod trace-events-sample.ko
# ls sample
enable filter
After patch:
# rmmod trace-events-sample.ko
# ls sample
ls: cannot access sample: No such file or directory
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Acked-by: Tom Zanussi <tzanussi@gmail.com>
Reviewed-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <4A55A8BE.9010707@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/trace/trace.h | 1 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 32 |
2 files changed, 32 insertions, 1 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 52eb0d8dcd75..94305c7bc11c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -757,6 +757,7 @@ struct event_subsystem { | |||
757 | const char *name; | 757 | const char *name; |
758 | struct dentry *entry; | 758 | struct dentry *entry; |
759 | void *filter; | 759 | void *filter; |
760 | int nr_events; | ||
760 | }; | 761 | }; |
761 | 762 | ||
762 | struct filter_pred; | 763 | struct filter_pred; |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index fecac1314cbe..90cf9360e140 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -851,8 +851,10 @@ event_subsystem_dir(const char *name, struct dentry *d_events) | |||
851 | 851 | ||
852 | /* First see if we did not already create this dir */ | 852 | /* First see if we did not already create this dir */ |
853 | list_for_each_entry(system, &event_subsystems, list) { | 853 | list_for_each_entry(system, &event_subsystems, list) { |
854 | if (strcmp(system->name, name) == 0) | 854 | if (strcmp(system->name, name) == 0) { |
855 | system->nr_events++; | ||
855 | return system->entry; | 856 | return system->entry; |
857 | } | ||
856 | } | 858 | } |
857 | 859 | ||
858 | /* need to create new entry */ | 860 | /* need to create new entry */ |
@@ -871,6 +873,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) | |||
871 | return d_events; | 873 | return d_events; |
872 | } | 874 | } |
873 | 875 | ||
876 | system->nr_events = 1; | ||
874 | system->name = kstrdup(name, GFP_KERNEL); | 877 | system->name = kstrdup(name, GFP_KERNEL); |
875 | if (!system->name) { | 878 | if (!system->name) { |
876 | debugfs_remove(system->entry); | 879 | debugfs_remove(system->entry); |
@@ -905,6 +908,32 @@ event_subsystem_dir(const char *name, struct dentry *d_events) | |||
905 | return system->entry; | 908 | return system->entry; |
906 | } | 909 | } |
907 | 910 | ||
911 | static void remove_subsystem_dir(const char *name) | ||
912 | { | ||
913 | struct event_subsystem *system; | ||
914 | |||
915 | if (strcmp(name, TRACE_SYSTEM) == 0) | ||
916 | return; | ||
917 | |||
918 | list_for_each_entry(system, &event_subsystems, list) { | ||
919 | if (strcmp(system->name, name) == 0) { | ||
920 | if (!--system->nr_events) { | ||
921 | struct event_filter *filter = system->filter; | ||
922 | |||
923 | debugfs_remove_recursive(system->entry); | ||
924 | list_del(&system->list); | ||
925 | if (filter) { | ||
926 | kfree(filter->filter_string); | ||
927 | kfree(filter); | ||
928 | } | ||
929 | kfree(system->name); | ||
930 | kfree(system); | ||
931 | } | ||
932 | break; | ||
933 | } | ||
934 | } | ||
935 | } | ||
936 | |||
908 | static int | 937 | static int |
909 | event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | 938 | event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, |
910 | const struct file_operations *id, | 939 | const struct file_operations *id, |
@@ -1079,6 +1108,7 @@ static void trace_module_remove_events(struct module *mod) | |||
1079 | list_del(&call->list); | 1108 | list_del(&call->list); |
1080 | trace_destroy_fields(call); | 1109 | trace_destroy_fields(call); |
1081 | destroy_preds(call); | 1110 | destroy_preds(call); |
1111 | remove_subsystem_dir(call->system); | ||
1082 | } | 1112 | } |
1083 | } | 1113 | } |
1084 | 1114 | ||