}
 }
 
-static void free_fdtable_rcu(struct rcu_head *rcu)
+void free_fdtable_rcu(struct rcu_head *rcu)
 {
        struct fdtable *fdt = container_of(rcu, struct fdtable, rcu);
        int fdset_size, fdarray_size;
        fdset_size = fdt->max_fds / 8;
        fdarray_size = fdt->max_fds * sizeof(struct file *);
 
-       if (fdt->free_files) {
+       if (fdt->max_fds <= NR_OPEN_DEFAULT) {
                /*
-                * The this fdtable was embedded in the files structure
-                * and the files structure itself was getting destroyed.
-                * It is now safe to free the files structure.
+                * This fdtable is embedded in the files structure and that
+                * structure itself is getting destroyed.
                 */
-               kmem_cache_free(files_cachep, fdt->free_files);
+               kmem_cache_free(files_cachep,
+                               container_of(fdt, struct files_struct, fdtab));
                return;
        }
-       if (fdt->max_fds <= NR_OPEN_DEFAULT)
-               /*
-                * The fdtable was embedded
-                */
-               return;
        if (fdset_size <= PAGE_SIZE && fdarray_size <= PAGE_SIZE) {
                kfree(fdt->open_fds);
                kfree(fdt->close_on_exec);
        }
 }
 
-void free_fdtable(struct fdtable *fdt)
-{
-       if (fdt->free_files || fdt->max_fds > NR_OPEN_DEFAULT)
-               call_rcu(&fdt->rcu, free_fdtable_rcu);
-}
-
 /*
  * Expand the fdset in the files_struct.  Called with the files spinlock
  * held for write.
                goto out;
        fdt->fd = new_fds;
        fdt->max_fds = nfds;
-       fdt->free_files = NULL;
        return fdt;
 out:
        free_fdset(new_openset, nfds);
                /* Continue as planned */
                copy_fdtable(new_fdt, cur_fdt);
                rcu_assign_pointer(files->fdt, new_fdt);
-               free_fdtable(cur_fdt);
+               if (cur_fdt->max_fds > NR_OPEN_DEFAULT)
+                       call_rcu(&cur_fdt->rcu, free_fdtable_rcu);
        } else {
                /* Somebody else expanded, so undo our attempt */
                __free_fdtable(new_fdt);
 
        fd_set *close_on_exec;
        fd_set *open_fds;
        struct rcu_head rcu;
-       struct files_struct *free_files;
        struct fdtable *next;
 };
 
 extern void free_fdset(fd_set *, int);
 
 extern int expand_files(struct files_struct *, int nr);
-extern void free_fdtable(struct fdtable *fdt);
+extern void free_fdtable_rcu(struct rcu_head *rcu);
 extern void __init files_defer_init(void);
 
 static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
 
                 * you can free files immediately.
                 */
                fdt = files_fdtable(files);
-               if (fdt == &files->fdtab)
-                       fdt->free_files = files;
-               else
+               if (fdt != &files->fdtab)
                        kmem_cache_free(files_cachep, files);
-               free_fdtable(fdt);
+               call_rcu(&fdt->rcu, free_fdtable_rcu);
        }
 }