aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 23:25:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 23:25:04 -0400
commitaab174f0df5d72d31caccf281af5f614fa254578 (patch)
tree2a172c5009c4ac8755e858593154c258ce7709a0 /kernel/events
parentca41cc96b2813221b05af57d0355157924de5a07 (diff)
parent2bd2c1941f141ad780135ccc1cd08ca71a24f10a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs update from Al Viro: - big one - consolidation of descriptor-related logics; almost all of that is moved to fs/file.c (BTW, I'm seriously tempted to rename the result to fd.c. As it is, we have a situation when file_table.c is about handling of struct file and file.c is about handling of descriptor tables; the reasons are historical - file_table.c used to be about a static array of struct file we used to have way back). A lot of stray ends got cleaned up and converted to saner primitives, disgusting mess in android/binder.c is still disgusting, but at least doesn't poke so much in descriptor table guts anymore. A bunch of relatively minor races got fixed in process, plus an ext4 struct file leak. - related thing - fget_light() partially unuglified; see fdget() in there (and yes, it generates the code as good as we used to have). - also related - bits of Cyrill's procfs stuff that got entangled into that work; _not_ all of it, just the initial move to fs/proc/fd.c and switch of fdinfo to seq_file. - Alex's fs/coredump.c spiltoff - the same story, had been easier to take that commit than mess with conflicts. The rest is a separate pile, this was just a mechanical code movement. - a few misc patches all over the place. Not all for this cycle, there'll be more (and quite a few currently sit in akpm's tree)." Fix up trivial conflicts in the android binder driver, and some fairly simple conflicts due to two different changes to the sock_alloc_file() interface ("take descriptor handling from sock_alloc_file() to callers" vs "net: Providing protocol type via system.sockprotoname xattr of /proc/PID/fd entries" adding a dentry name to the socket) * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (72 commits) MAX_LFS_FILESIZE should be a loff_t compat: fs: Generic compat_sys_sendfile implementation fs: push rcu_barrier() from deactivate_locked_super() to filesystems btrfs: reada_extent doesn't need kref for refcount coredump: move core dump functionality into its own file coredump: prevent double-free on an error path in core dumper usb/gadget: fix misannotations fcntl: fix misannotations ceph: don't abuse d_delete() on failure exits hypfs: ->d_parent is never NULL or negative vfs: delete surplus inode NULL check switch simple cases of fget_light to fdget new helpers: fdget()/fdput() switch o2hb_region_dev_write() to fget_light() proc_map_files_readdir(): don't bother with grabbing files make get_file() return its argument vhost_set_vring(): turn pollstart/pollstop into bool switch prctl_set_mm_exe_file() to fget_light() switch xfs_find_handle() to fget_light() switch xfs_swapext() to fget_light() ...
Diffstat (limited to 'kernel/events')
-rw-r--r--kernel/events/core.c72
1 files changed, 31 insertions, 41 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index deec4e50eb30..f16f3c58f11a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -468,14 +468,13 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
468{ 468{
469 struct perf_cgroup *cgrp; 469 struct perf_cgroup *cgrp;
470 struct cgroup_subsys_state *css; 470 struct cgroup_subsys_state *css;
471 struct file *file; 471 struct fd f = fdget(fd);
472 int ret = 0, fput_needed; 472 int ret = 0;
473 473
474 file = fget_light(fd, &fput_needed); 474 if (!f.file)
475 if (!file)
476 return -EBADF; 475 return -EBADF;
477 476
478 css = cgroup_css_from_dir(file, perf_subsys_id); 477 css = cgroup_css_from_dir(f.file, perf_subsys_id);
479 if (IS_ERR(css)) { 478 if (IS_ERR(css)) {
480 ret = PTR_ERR(css); 479 ret = PTR_ERR(css);
481 goto out; 480 goto out;
@@ -501,7 +500,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
501 ret = -EINVAL; 500 ret = -EINVAL;
502 } 501 }
503out: 502out:
504 fput_light(file, fput_needed); 503 fdput(f);
505 return ret; 504 return ret;
506} 505}
507 506
@@ -3234,21 +3233,18 @@ unlock:
3234 3233
3235static const struct file_operations perf_fops; 3234static const struct file_operations perf_fops;
3236 3235
3237static struct file *perf_fget_light(int fd, int *fput_needed) 3236static inline int perf_fget_light(int fd, struct fd *p)
3238{ 3237{
3239 struct file *file; 3238 struct fd f = fdget(fd);
3240 3239 if (!f.file)
3241 file = fget_light(fd, fput_needed); 3240 return -EBADF;
3242 if (!file)
3243 return ERR_PTR(-EBADF);
3244 3241
3245 if (file->f_op != &perf_fops) { 3242 if (f.file->f_op != &perf_fops) {
3246 fput_light(file, *fput_needed); 3243 fdput(f);
3247 *fput_needed = 0; 3244 return -EBADF;
3248 return ERR_PTR(-EBADF);
3249 } 3245 }
3250 3246 *p = f;
3251 return file; 3247 return 0;
3252} 3248}
3253 3249
3254static int perf_event_set_output(struct perf_event *event, 3250static int perf_event_set_output(struct perf_event *event,
@@ -3280,22 +3276,19 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3280 3276
3281 case PERF_EVENT_IOC_SET_OUTPUT: 3277 case PERF_EVENT_IOC_SET_OUTPUT:
3282 { 3278 {
3283 struct file *output_file = NULL;
3284 struct perf_event *output_event = NULL;
3285 int fput_needed = 0;
3286 int ret; 3279 int ret;
3287
3288 if (arg != -1) { 3280 if (arg != -1) {
3289 output_file = perf_fget_light(arg, &fput_needed); 3281 struct perf_event *output_event;
3290 if (IS_ERR(output_file)) 3282 struct fd output;
3291 return PTR_ERR(output_file); 3283 ret = perf_fget_light(arg, &output);
3292 output_event = output_file->private_data; 3284 if (ret)
3285 return ret;
3286 output_event = output.file->private_data;
3287 ret = perf_event_set_output(event, output_event);
3288 fdput(output);
3289 } else {
3290 ret = perf_event_set_output(event, NULL);
3293 } 3291 }
3294
3295 ret = perf_event_set_output(event, output_event);
3296 if (output_event)
3297 fput_light(output_file, fput_needed);
3298
3299 return ret; 3292 return ret;
3300 } 3293 }
3301 3294
@@ -6443,12 +6436,11 @@ SYSCALL_DEFINE5(perf_event_open,
6443 struct perf_event_attr attr; 6436 struct perf_event_attr attr;
6444 struct perf_event_context *ctx; 6437 struct perf_event_context *ctx;
6445 struct file *event_file = NULL; 6438 struct file *event_file = NULL;
6446 struct file *group_file = NULL; 6439 struct fd group = {NULL, 0};
6447 struct task_struct *task = NULL; 6440 struct task_struct *task = NULL;
6448 struct pmu *pmu; 6441 struct pmu *pmu;
6449 int event_fd; 6442 int event_fd;
6450 int move_group = 0; 6443 int move_group = 0;
6451 int fput_needed = 0;
6452 int err; 6444 int err;
6453 6445
6454 /* for future expandability... */ 6446 /* for future expandability... */
@@ -6478,17 +6470,15 @@ SYSCALL_DEFINE5(perf_event_open,
6478 if ((flags & PERF_FLAG_PID_CGROUP) && (pid == -1 || cpu == -1)) 6470 if ((flags & PERF_FLAG_PID_CGROUP) && (pid == -1 || cpu == -1))
6479 return -EINVAL; 6471 return -EINVAL;
6480 6472
6481 event_fd = get_unused_fd_flags(O_RDWR); 6473 event_fd = get_unused_fd();
6482 if (event_fd < 0) 6474 if (event_fd < 0)
6483 return event_fd; 6475 return event_fd;
6484 6476
6485 if (group_fd != -1) { 6477 if (group_fd != -1) {
6486 group_file = perf_fget_light(group_fd, &fput_needed); 6478 err = perf_fget_light(group_fd, &group);
6487 if (IS_ERR(group_file)) { 6479 if (err)
6488 err = PTR_ERR(group_file);
6489 goto err_fd; 6480 goto err_fd;
6490 } 6481 group_leader = group.file->private_data;
6491 group_leader = group_file->private_data;
6492 if (flags & PERF_FLAG_FD_OUTPUT) 6482 if (flags & PERF_FLAG_FD_OUTPUT)
6493 output_event = group_leader; 6483 output_event = group_leader;
6494 if (flags & PERF_FLAG_FD_NO_GROUP) 6484 if (flags & PERF_FLAG_FD_NO_GROUP)
@@ -6664,7 +6654,7 @@ SYSCALL_DEFINE5(perf_event_open,
6664 * of the group leader will find the pointer to itself in 6654 * of the group leader will find the pointer to itself in
6665 * perf_group_detach(). 6655 * perf_group_detach().
6666 */ 6656 */
6667 fput_light(group_file, fput_needed); 6657 fdput(group);
6668 fd_install(event_fd, event_file); 6658 fd_install(event_fd, event_file);
6669 return event_fd; 6659 return event_fd;
6670 6660
@@ -6678,7 +6668,7 @@ err_task:
6678 if (task) 6668 if (task)
6679 put_task_struct(task); 6669 put_task_struct(task);
6680err_group_fd: 6670err_group_fd:
6681 fput_light(group_file, fput_needed); 6671 fdput(group);
6682err_fd: 6672err_fd:
6683 put_unused_fd(event_fd); 6673 put_unused_fd(event_fd);
6684 return err; 6674 return err;