don't bother with call_rcu() in put_files_struct()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 16 Aug 2012 00:00:58 +0000 (20:00 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 27 Sep 2012 01:08:54 +0000 (21:08 -0400)
At that point nobody can see us anyway; everything that
looks at files_fdtable(files) is separated from the
guts of put_files_struct(files) - either since files is
current->files or because we fetched it under task_lock()
and hadn't dropped that yet, or because we'd bumped
files->count while holding task_lock()...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/file.c

index 0be423cadb266fb09e319a35c7c2c667e0bc25e4..533fa5d56a5f98179340906e0f12e2fc776398e6 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -447,18 +447,14 @@ void put_files_struct(struct files_struct *files)
 
        if (atomic_dec_and_test(&files->count)) {
                close_files(files);
-               /*
-                * Free the fd and fdset arrays if we expanded them.
-                * If the fdtable was embedded, pass files for freeing
-                * at the end of the RCU grace period. Otherwise,
-                * you can free files immediately.
-                */
+               /* not really needed, since nobody can see us */
                rcu_read_lock();
                fdt = files_fdtable(files);
-               if (fdt != &files->fdtab)
-                       kmem_cache_free(files_cachep, files);
-               free_fdtable(fdt);
                rcu_read_unlock();
+               /* free the arrays if they are not embedded */
+               if (fdt != &files->fdtab)
+                       __free_fdtable(fdt);
+               kmem_cache_free(files_cachep, files);
        }
 }