diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-09-03 12:03:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-03 12:46:23 -0400 |
commit | dc86cabe4b242446ea9aa8492c727e1220817898 (patch) | |
tree | eace3c21e20231d6f6359a223941efa419a82ea4 /kernel/perf_counter.c | |
parent | 6f4596d9312ba5fbf5f3231ef484823c4e684d2e (diff) |
perf_counter: Fix output-sharing error path
We forget to release the fd in the PERF_FLAG_FD_OUTPUT
error path.
Reorganize the error flow here to be a clean fall-through
logic.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0aa609f69103..e0d91fdf0c3c 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -4316,15 +4316,15 @@ SYSCALL_DEFINE5(perf_counter_open, | |||
4316 | struct file *group_file = NULL; | 4316 | struct file *group_file = NULL; |
4317 | int fput_needed = 0; | 4317 | int fput_needed = 0; |
4318 | int fput_needed2 = 0; | 4318 | int fput_needed2 = 0; |
4319 | int ret; | 4319 | int err; |
4320 | 4320 | ||
4321 | /* for future expandability... */ | 4321 | /* for future expandability... */ |
4322 | if (flags & ~(PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT)) | 4322 | if (flags & ~(PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT)) |
4323 | return -EINVAL; | 4323 | return -EINVAL; |
4324 | 4324 | ||
4325 | ret = perf_copy_attr(attr_uptr, &attr); | 4325 | err = perf_copy_attr(attr_uptr, &attr); |
4326 | if (ret) | 4326 | if (err) |
4327 | return ret; | 4327 | return err; |
4328 | 4328 | ||
4329 | if (!attr.exclude_kernel) { | 4329 | if (!attr.exclude_kernel) { |
4330 | if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) | 4330 | if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) |
@@ -4348,7 +4348,7 @@ SYSCALL_DEFINE5(perf_counter_open, | |||
4348 | */ | 4348 | */ |
4349 | group_leader = NULL; | 4349 | group_leader = NULL; |
4350 | if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) { | 4350 | if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) { |
4351 | ret = -EINVAL; | 4351 | err = -EINVAL; |
4352 | group_file = fget_light(group_fd, &fput_needed); | 4352 | group_file = fget_light(group_fd, &fput_needed); |
4353 | if (!group_file) | 4353 | if (!group_file) |
4354 | goto err_put_context; | 4354 | goto err_put_context; |
@@ -4377,22 +4377,22 @@ SYSCALL_DEFINE5(perf_counter_open, | |||
4377 | 4377 | ||
4378 | counter = perf_counter_alloc(&attr, cpu, ctx, group_leader, | 4378 | counter = perf_counter_alloc(&attr, cpu, ctx, group_leader, |
4379 | NULL, GFP_KERNEL); | 4379 | NULL, GFP_KERNEL); |
4380 | ret = PTR_ERR(counter); | 4380 | err = PTR_ERR(counter); |
4381 | if (IS_ERR(counter)) | 4381 | if (IS_ERR(counter)) |
4382 | goto err_put_context; | 4382 | goto err_put_context; |
4383 | 4383 | ||
4384 | ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); | 4384 | err = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); |
4385 | if (ret < 0) | 4385 | if (err < 0) |
4386 | goto err_free_put_context; | 4386 | goto err_free_put_context; |
4387 | 4387 | ||
4388 | counter_file = fget_light(ret, &fput_needed2); | 4388 | counter_file = fget_light(err, &fput_needed2); |
4389 | if (!counter_file) | 4389 | if (!counter_file) |
4390 | goto err_free_put_context; | 4390 | goto err_free_put_context; |
4391 | 4391 | ||
4392 | if (flags & PERF_FLAG_FD_OUTPUT) { | 4392 | if (flags & PERF_FLAG_FD_OUTPUT) { |
4393 | ret = perf_counter_set_output(counter, group_fd); | 4393 | err = perf_counter_set_output(counter, group_fd); |
4394 | if (ret) | 4394 | if (err) |
4395 | goto err_free_put_context; | 4395 | goto err_fput_free_put_context; |
4396 | } | 4396 | } |
4397 | 4397 | ||
4398 | counter->filp = counter_file; | 4398 | counter->filp = counter_file; |
@@ -4408,20 +4408,20 @@ SYSCALL_DEFINE5(perf_counter_open, | |||
4408 | list_add_tail(&counter->owner_entry, ¤t->perf_counter_list); | 4408 | list_add_tail(&counter->owner_entry, ¤t->perf_counter_list); |
4409 | mutex_unlock(¤t->perf_counter_mutex); | 4409 | mutex_unlock(¤t->perf_counter_mutex); |
4410 | 4410 | ||
4411 | err_fput_free_put_context: | ||
4411 | fput_light(counter_file, fput_needed2); | 4412 | fput_light(counter_file, fput_needed2); |
4412 | 4413 | ||
4413 | out_fput: | ||
4414 | fput_light(group_file, fput_needed); | ||
4415 | |||
4416 | return ret; | ||
4417 | |||
4418 | err_free_put_context: | 4414 | err_free_put_context: |
4419 | kfree(counter); | 4415 | if (err < 0) |
4416 | kfree(counter); | ||
4420 | 4417 | ||
4421 | err_put_context: | 4418 | err_put_context: |
4422 | put_ctx(ctx); | 4419 | if (err < 0) |
4420 | put_ctx(ctx); | ||
4421 | |||
4422 | fput_light(group_file, fput_needed); | ||
4423 | 4423 | ||
4424 | goto out_fput; | 4424 | return err; |
4425 | } | 4425 | } |
4426 | 4426 | ||
4427 | /* | 4427 | /* |