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,
 
        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:
        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;
        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;
                task = find_lively_task_by_vpid(pid);
                if (IS_ERR(task)) {
                        err = PTR_ERR(task);
-                       goto err_group_fd;
+                       goto err_fd;
                }
        }
 
        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;
 
 err_task:
        if (task)
                put_task_struct(task);
-err_group_fd:
-       fdput(group);
 err_fd:
        put_unused_fd(event_fd);
        return err;