diff options
Diffstat (limited to 'kernel/trace/trace_uprobe.c')
| -rw-r--r-- | kernel/trace/trace_uprobe.c | 35 | 
1 files changed, 14 insertions, 21 deletions
| diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 34fd0e0ec51d..ac892878dbe6 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -55,6 +55,7 @@ struct trace_uprobe {  	struct list_head		list;  	struct trace_uprobe_filter	filter;  	struct uprobe_consumer		consumer; +	struct path			path;  	struct inode			*inode;  	char				*filename;  	unsigned long			offset; @@ -289,7 +290,7 @@ static void free_trace_uprobe(struct trace_uprobe *tu)  	for (i = 0; i < tu->tp.nr_args; i++)  		traceprobe_free_probe_arg(&tu->tp.args[i]); -	iput(tu->inode); +	path_put(&tu->path);  	kfree(tu->tp.call.class->system);  	kfree(tu->tp.call.name);  	kfree(tu->filename); @@ -363,7 +364,6 @@ end:  static int create_trace_uprobe(int argc, char **argv)  {  	struct trace_uprobe *tu; -	struct inode *inode;  	char *arg, *event, *group, *filename;  	char buf[MAX_EVENT_NAME_LEN];  	struct path path; @@ -371,7 +371,6 @@ static int create_trace_uprobe(int argc, char **argv)  	bool is_delete, is_return;  	int i, ret; -	inode = NULL;  	ret = 0;  	is_delete = false;  	is_return = false; @@ -437,21 +436,16 @@ static int create_trace_uprobe(int argc, char **argv)  	}  	/* Find the last occurrence, in case the path contains ':' too. */  	arg = strrchr(argv[1], ':'); -	if (!arg) { -		ret = -EINVAL; -		goto fail_address_parse; -	} +	if (!arg) +		return -EINVAL;  	*arg++ = '\0';  	filename = argv[1];  	ret = kern_path(filename, LOOKUP_FOLLOW, &path);  	if (ret) -		goto fail_address_parse; - -	inode = igrab(d_real_inode(path.dentry)); -	path_put(&path); +		return ret; -	if (!inode || !S_ISREG(inode->i_mode)) { +	if (!d_is_reg(path.dentry)) {  		ret = -EINVAL;  		goto fail_address_parse;  	} @@ -490,7 +484,7 @@ static int create_trace_uprobe(int argc, char **argv)  		goto fail_address_parse;  	}  	tu->offset = offset; -	tu->inode = inode; +	tu->path = path;  	tu->filename = kstrdup(filename, GFP_KERNEL);  	if (!tu->filename) { @@ -558,7 +552,7 @@ error:  	return ret;  fail_address_parse: -	iput(inode); +	path_put(&path);  	pr_info("Failed to parse address or file.\n"); @@ -922,6 +916,7 @@ probe_event_enable(struct trace_uprobe *tu, struct trace_event_file *file,  		goto err_flags;  	tu->consumer.filter = filter; +	tu->inode = d_real_inode(tu->path.dentry);  	ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);  	if (ret)  		goto err_buffer; @@ -967,6 +962,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file)  	WARN_ON(!uprobe_filter_is_empty(&tu->filter));  	uprobe_unregister(tu->inode, tu->offset, &tu->consumer); +	tu->inode = NULL;  	tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE;  	uprobe_buffer_disable(); @@ -1337,7 +1333,6 @@ struct trace_event_call *  create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)  {  	struct trace_uprobe *tu; -	struct inode *inode;  	struct path path;  	int ret; @@ -1345,11 +1340,8 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)  	if (ret)  		return ERR_PTR(ret); -	inode = igrab(d_inode(path.dentry)); -	path_put(&path); - -	if (!inode || !S_ISREG(inode->i_mode)) { -		iput(inode); +	if (!d_is_reg(path.dentry)) { +		path_put(&path);  		return ERR_PTR(-EINVAL);  	} @@ -1364,11 +1356,12 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)  	if (IS_ERR(tu)) {  		pr_info("Failed to allocate trace_uprobe.(%d)\n",  			(int)PTR_ERR(tu)); +		path_put(&path);  		return ERR_CAST(tu);  	}  	tu->offset = offs; -	tu->inode = inode; +	tu->path = path;  	tu->filename = kstrdup(name, GFP_KERNEL);  	init_trace_event_call(tu, &tu->tp.call); |