Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc82ec98 authored by Xiao Guangrong's avatar Xiao Guangrong Committed by Ingo Molnar
Browse files

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: default avatarXiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Acked-by: default avatarTom Zanussi <tzanussi@gmail.com>
Reviewed-by: default avatarLi 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: default avatarIngo Molnar <mingo@elte.hu>
parent c5cb1836
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -757,6 +757,7 @@ struct event_subsystem {
	const char		*name;
	struct dentry		*entry;
	void			*filter;
	int			nr_events;
};

struct filter_pred;
+31 −1
Original line number Diff line number Diff line
@@ -851,9 +851,11 @@ event_subsystem_dir(const char *name, struct dentry *d_events)

	/* First see if we did not already create this dir */
	list_for_each_entry(system, &event_subsystems, list) {
		if (strcmp(system->name, name) == 0)
		if (strcmp(system->name, name) == 0) {
			system->nr_events++;
			return system->entry;
		}
	}

	/* need to create new entry */
	system = kmalloc(sizeof(*system), GFP_KERNEL);
@@ -871,6 +873,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
		return d_events;
	}

	system->nr_events = 1;
	system->name = kstrdup(name, GFP_KERNEL);
	if (!system->name) {
		debugfs_remove(system->entry);
@@ -905,6 +908,32 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
	return system->entry;
}

static void remove_subsystem_dir(const char *name)
{
	struct event_subsystem *system;

	if (strcmp(name, TRACE_SYSTEM) == 0)
		return;

	list_for_each_entry(system, &event_subsystems, list) {
		if (strcmp(system->name, name) == 0) {
			if (!--system->nr_events) {
				struct event_filter *filter = system->filter;

				debugfs_remove_recursive(system->entry);
				list_del(&system->list);
				if (filter) {
					kfree(filter->filter_string);
					kfree(filter);
				}
				kfree(system->name);
				kfree(system);
			}
			break;
		}
	}
}

static int
event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
		 const struct file_operations *id,
@@ -1079,6 +1108,7 @@ static void trace_module_remove_events(struct module *mod)
			list_del(&call->list);
			trace_destroy_fields(call);
			destroy_preds(call);
			remove_subsystem_dir(call->system);
		}
	}