aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>2009-07-09 04:22:22 -0400
committerIngo Molnar <mingo@elte.hu>2009-07-10 05:55:28 -0400
commitdc82ec98a4727fd51b77e92d05fe7d2db3dcc11c (patch)
treec66955e01458db480185c963304a60b6fd77c72c
parentc5cb183608167c744cb28bbd85884be5a4ce875d (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.h1
-rw-r--r--kernel/trace/trace_events.c32
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
762struct filter_pred; 763struct 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
911static 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
908static int 937static int
909event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, 938event_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