summaryrefslogtreecommitdiff
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorPrasanna Meda <pmeda@akamai.com>2005-01-20 16:03:48 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-20 16:03:48 -0800
commit46c4ad2c4f871ae58af4aa9862ee53be478dcc22 (patch)
treea03e6e364c81f64051ace09e6a09cfa27f370df8 /kernel/fork.c
parente07e53dd45c531aae8749bc51687c8620a3b19bc (diff)
[PATCH] file_table:expand_files() code cleanup
expand_files() cleanup: Make expand_files() common code for fork.c:fork/copy_files(), open.c:open/get_unused_fd() and fcntl.c:dup/locate_fd(). expand_files() does both expand_fd_array and expand_fd_set based on the need. This is used in dup(). open() and fork() duplicates the work of expand files. At all places we check for expanding fd array, we also check for expanding fdset. There is no need of checking and calling them seperately. This change also moves the expand_files to file.c from fcntl.c, and makes the expand_fd_array and expand_fd_set local to that file. Signed-off-by: Prasanna Meda <pmeda@akamai.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index be1ff8ddbb9c..f6b929e69f5b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -555,7 +555,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
{
struct files_struct *oldf, *newf;
struct file **old_fds, **new_fds;
- int open_files, nfds, size, i, error = 0;
+ int open_files, size, i, error = 0, expand;
/*
* A background process may not have any files ...
@@ -590,36 +590,32 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
newf->open_fds = &newf->open_fds_init;
newf->fd = &newf->fd_array[0];
- /* We don't yet have the oldf readlock, but even if the old
- fdset gets grown now, we'll only copy up to "size" fds */
- size = oldf->max_fdset;
- if (size > __FD_SETSIZE) {
- newf->max_fdset = 0;
- spin_lock(&newf->file_lock);
- error = expand_fdset(newf, size-1);
- spin_unlock(&newf->file_lock);
- if (error)
- goto out_release;
- }
spin_lock(&oldf->file_lock);
- open_files = count_open_files(oldf, size);
+ open_files = count_open_files(oldf, oldf->max_fdset);
+ expand = 0;
/*
- * Check whether we need to allocate a larger fd array.
- * Note: we're not a clone task, so the open count won't
- * change.
+ * Check whether we need to allocate a larger fd array or fd set.
+ * Note: we're not a clone task, so the open count won't change.
*/
- nfds = NR_OPEN_DEFAULT;
- if (open_files > nfds) {
- spin_unlock(&oldf->file_lock);
+ if (open_files > newf->max_fdset) {
+ newf->max_fdset = 0;
+ expand = 1;
+ }
+ if (open_files > newf->max_fds) {
newf->max_fds = 0;
+ expand = 1;
+ }
+
+ /* if the old fdset gets grown now, we'll only copy up to "size" fds */
+ if (expand) {
+ spin_unlock(&oldf->file_lock);
spin_lock(&newf->file_lock);
- error = expand_fd_array(newf, open_files-1);
+ error = expand_files(newf, open_files-1);
spin_unlock(&newf->file_lock);
- if (error)
+ if (error < 0)
goto out_release;
- nfds = newf->max_fds;
spin_lock(&oldf->file_lock);
}
@@ -668,6 +664,7 @@ out:
out_release:
free_fdset (newf->close_on_exec, newf->max_fdset);
free_fdset (newf->open_fds, newf->max_fdset);
+ free_fd_array(newf->fd, newf->max_fds);
kmem_cache_free(files_cachep, newf);
goto out;
}