*fput_needed = 0;
        if (atomic_read(&files->count) == 1) {
-               file = fcheck_files(files, fd);
+               file = __fcheck_files(files, fd);
                if (file && (file->f_mode & FMODE_PATH))
                        file = NULL;
        } else {
 
        *fput_needed = 0;
        if (atomic_read(&files->count) == 1) {
-               file = fcheck_files(files, fd);
+               file = __fcheck_files(files, fd);
        } else {
                rcu_read_lock();
                file = fcheck_files(files, fd);
 
        struct file __rcu * fd_array[NR_OPEN_DEFAULT];
 };
 
-#define rcu_dereference_check_fdtable(files, fdtfd) \
-       (rcu_dereference_check((fdtfd), \
-                              lockdep_is_held(&(files)->file_lock) || \
-                              atomic_read(&(files)->count) == 1 || \
-                              rcu_my_thread_group_empty()))
-
-#define files_fdtable(files) \
-               (rcu_dereference_check_fdtable((files), (files)->fdt))
-
 struct file_operations;
 struct vfsmount;
 struct dentry;
 
 extern void __init files_defer_init(void);
 
-static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
+#define rcu_dereference_check_fdtable(files, fdtfd) \
+       rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock))
+
+#define files_fdtable(files) \
+       rcu_dereference_check_fdtable((files), (files)->fdt)
+
+/*
+ * The caller must ensure that fd table isn't shared or hold rcu or file lock
+ */
+static inline struct file *__fcheck_files(struct files_struct *files, unsigned int fd)
 {
-       struct file * file = NULL;
-       struct fdtable *fdt = files_fdtable(files);
+       struct fdtable *fdt = rcu_dereference_raw(files->fdt);
 
        if (fd < fdt->max_fds)
-               file = rcu_dereference_check_fdtable(files, fdt->fd[fd]);
-       return file;
+               return rcu_dereference_raw(fdt->fd[fd]);
+       return NULL;
+}
+
+static inline struct file *fcheck_files(struct files_struct *files, unsigned int fd)
+{
+       rcu_lockdep_assert(rcu_read_lock_held() ||
+                          lockdep_is_held(&files->file_lock),
+                          "suspicious rcu_dereference_check() usage");
+       return __fcheck_files(files, fd);
 }
 
 /*
 
 }
 EXPORT_SYMBOL_GPL(wait_rcu_gp);
 
-#ifdef CONFIG_PROVE_RCU
-/*
- * wrapper function to avoid #include problems.
- */
-int rcu_my_thread_group_empty(void)
-{
-       return thread_group_empty(current);
-}
-EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
-#endif /* #ifdef CONFIG_PROVE_RCU */
-
 #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
 static inline void debug_init_rcu_head(struct rcu_head *head)
 {