[PATCH] dup_fd() - part 3
merge alloc_files() into dup_fd(), leave setting newf->fdt until the end
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/file.c b/fs/file.c
index 6491b2b..689d2b6 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -273,31 +273,6 @@
return i;
}
-static struct files_struct *alloc_files(void)
-{
- struct files_struct *newf;
- struct fdtable *fdt;
-
- newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);
- if (!newf)
- goto out;
-
- atomic_set(&newf->count, 1);
-
- spin_lock_init(&newf->file_lock);
- newf->next_fd = 0;
- fdt = &newf->fdtab;
- fdt->max_fds = NR_OPEN_DEFAULT;
- fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
- fdt->open_fds = (fd_set *)&newf->open_fds_init;
- fdt->fd = &newf->fd_array[0];
- INIT_RCU_HEAD(&fdt->rcu);
- fdt->next = NULL;
- rcu_assign_pointer(newf->fdt, fdt);
-out:
- return newf;
-}
-
/*
* Allocate a new files structure and copy contents from the
* passed in files structure.
@@ -311,13 +286,24 @@
struct fdtable *old_fdt, *new_fdt;
*errorp = -ENOMEM;
- newf = alloc_files();
+ newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);
if (!newf)
goto out;
+ atomic_set(&newf->count, 1);
+
+ spin_lock_init(&newf->file_lock);
+ newf->next_fd = 0;
+ new_fdt = &newf->fdtab;
+ new_fdt->max_fds = NR_OPEN_DEFAULT;
+ new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
+ new_fdt->open_fds = (fd_set *)&newf->open_fds_init;
+ new_fdt->fd = &newf->fd_array[0];
+ INIT_RCU_HEAD(&new_fdt->rcu);
+ new_fdt->next = NULL;
+
spin_lock(&oldf->file_lock);
old_fdt = files_fdtable(oldf);
- new_fdt = files_fdtable(newf);
open_files = count_open_files(old_fdt);
/*
@@ -341,7 +327,6 @@
*errorp = -EMFILE;
goto out_release;
}
- rcu_assign_pointer(files->fdt, new_fdt);
/*
* Reacquire the oldf lock and a pointer to its fd table
@@ -391,6 +376,8 @@
memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
}
+ rcu_assign_pointer(newf->fdt, new_fdt);
+
return newf;
out_release: