mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
get rid of perf_fget_light(), convert kernel/events/core.c to CLASS(fd)
Lift fdget() and fdput() out of perf_fget_light(), turning it into is_perf_file(struct fd f). The life gets easier in both callers if we do fdget() unconditionally, including the case when we are given -1 instead of a descriptor - that avoids a reassignment in perf_event_open(2) and it avoids a nasty temptation in _perf_ioctl() where we must *not* lift output_event out of scope for output. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -5998,18 +5998,9 @@ EXPORT_SYMBOL_GPL(perf_event_period);
|
||||
|
||||
static const struct file_operations perf_fops;
|
||||
|
||||
static inline int perf_fget_light(int fd, struct fd *p)
|
||||
static inline bool is_perf_file(struct fd f)
|
||||
{
|
||||
struct fd f = fdget(fd);
|
||||
if (!fd_file(f))
|
||||
return -EBADF;
|
||||
|
||||
if (fd_file(f)->f_op != &perf_fops) {
|
||||
fdput(f);
|
||||
return -EBADF;
|
||||
}
|
||||
*p = f;
|
||||
return 0;
|
||||
return !fd_empty(f) && fd_file(f)->f_op == &perf_fops;
|
||||
}
|
||||
|
||||
static int perf_event_set_output(struct perf_event *event,
|
||||
@@ -6057,20 +6048,14 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon
|
||||
|
||||
case PERF_EVENT_IOC_SET_OUTPUT:
|
||||
{
|
||||
int ret;
|
||||
CLASS(fd, output)(arg); // arg == -1 => empty
|
||||
struct perf_event *output_event = NULL;
|
||||
if (arg != -1) {
|
||||
struct perf_event *output_event;
|
||||
struct fd output;
|
||||
ret = perf_fget_light(arg, &output);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!is_perf_file(output))
|
||||
return -EBADF;
|
||||
output_event = fd_file(output)->private_data;
|
||||
ret = perf_event_set_output(event, output_event);
|
||||
fdput(output);
|
||||
} else {
|
||||
ret = perf_event_set_output(event, NULL);
|
||||
}
|
||||
return ret;
|
||||
return perf_event_set_output(event, output_event);
|
||||
}
|
||||
|
||||
case PERF_EVENT_IOC_SET_FILTER:
|
||||
@@ -12664,7 +12649,6 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
struct perf_event_attr attr;
|
||||
struct perf_event_context *ctx;
|
||||
struct file *event_file = NULL;
|
||||
struct fd group = EMPTY_FD;
|
||||
struct task_struct *task = NULL;
|
||||
struct pmu *pmu;
|
||||
int event_fd;
|
||||
@@ -12735,10 +12719,12 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
if (event_fd < 0)
|
||||
return event_fd;
|
||||
|
||||
CLASS(fd, group)(group_fd); // group_fd == -1 => empty
|
||||
if (group_fd != -1) {
|
||||
err = perf_fget_light(group_fd, &group);
|
||||
if (err)
|
||||
if (!is_perf_file(group)) {
|
||||
err = -EBADF;
|
||||
goto err_fd;
|
||||
}
|
||||
group_leader = fd_file(group)->private_data;
|
||||
if (flags & PERF_FLAG_FD_OUTPUT)
|
||||
output_event = group_leader;
|
||||
@@ -12750,7 +12736,7 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
task = find_lively_task_by_vpid(pid);
|
||||
if (IS_ERR(task)) {
|
||||
err = PTR_ERR(task);
|
||||
goto err_group_fd;
|
||||
goto err_fd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13017,12 +13003,11 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
mutex_unlock(¤t->perf_event_mutex);
|
||||
|
||||
/*
|
||||
* Drop the reference on the group_event after placing the
|
||||
* new event on the sibling_list. This ensures destruction
|
||||
* of the group leader will find the pointer to itself in
|
||||
* perf_group_detach().
|
||||
* File reference in group guarantees that group_leader has been
|
||||
* kept alive until we place the new event on the sibling_list.
|
||||
* This ensures destruction of the group leader will find
|
||||
* the pointer to itself in perf_group_detach().
|
||||
*/
|
||||
fdput(group);
|
||||
fd_install(event_fd, event_file);
|
||||
return event_fd;
|
||||
|
||||
@@ -13041,8 +13026,6 @@ err_alloc:
|
||||
err_task:
|
||||
if (task)
|
||||
put_task_struct(task);
|
||||
err_group_fd:
|
||||
fdput(group);
|
||||
err_fd:
|
||||
put_unused_fd(event_fd);
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user