EXPORT_SYMBOL(fd_install);
 
+/**
+ * pick_file - return file associatd with fd
+ * @files: file struct to retrieve file from
+ * @fd: file descriptor to retrieve file for
+ *
+ * If this functions returns an EINVAL error pointer the fd was beyond the
+ * current maximum number of file descriptors for that fdtable.
+ *
+ * Returns: The file associated with @fd, on error returns an error pointer.
+ */
 static struct file *pick_file(struct files_struct *files, unsigned fd)
 {
-       struct file *file = NULL;
+       struct file *file;
        struct fdtable *fdt;
 
        spin_lock(&files->file_lock);
        fdt = files_fdtable(files);
-       if (fd >= fdt->max_fds)
+       if (fd >= fdt->max_fds) {
+               file = ERR_PTR(-EINVAL);
                goto out_unlock;
+       }
        file = fdt->fd[fd];
-       if (!file)
+       if (!file) {
+               file = ERR_PTR(-EBADF);
                goto out_unlock;
+       }
        rcu_assign_pointer(fdt->fd[fd], NULL);
        __put_unused_fd(files, fd);
 
        struct file *file;
 
        file = pick_file(files, fd);
-       if (!file)
+       if (IS_ERR(file))
                return -EBADF;
 
        return filp_close(file, files);
                struct file *file;
 
                file = pick_file(cur_fds, fd++);
-               if (!file)
+               if (!IS_ERR(file)) {
+                       /* found a valid file to close */
+                       filp_close(file, cur_fds);
+                       cond_resched();
                        continue;
+               }
 
-               filp_close(file, cur_fds);
-               cond_resched();
+               /* beyond the last fd in that table */
+               if (PTR_ERR(file) == -EINVAL)
+                       return;
        }
 }