aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c24
1 files changed, 6 insertions, 18 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 30eab4f063cd..aba595424f78 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -614,7 +614,7 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
614 614
615static int count_open_files(struct fdtable *fdt) 615static int count_open_files(struct fdtable *fdt)
616{ 616{
617 int size = fdt->max_fdset; 617 int size = fdt->max_fds;
618 int i; 618 int i;
619 619
620 /* Find the last open fd */ 620 /* Find the last open fd */
@@ -641,7 +641,6 @@ static struct files_struct *alloc_files(void)
641 newf->next_fd = 0; 641 newf->next_fd = 0;
642 fdt = &newf->fdtab; 642 fdt = &newf->fdtab;
643 fdt->max_fds = NR_OPEN_DEFAULT; 643 fdt->max_fds = NR_OPEN_DEFAULT;
644 fdt->max_fdset = EMBEDDED_FD_SET_SIZE;
645 fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; 644 fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
646 fdt->open_fds = (fd_set *)&newf->open_fds_init; 645 fdt->open_fds = (fd_set *)&newf->open_fds_init;
647 fdt->fd = &newf->fd_array[0]; 646 fdt->fd = &newf->fd_array[0];
@@ -662,7 +661,7 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
662{ 661{
663 struct files_struct *newf; 662 struct files_struct *newf;
664 struct file **old_fds, **new_fds; 663 struct file **old_fds, **new_fds;
665 int open_files, size, i, expand; 664 int open_files, size, i;
666 struct fdtable *old_fdt, *new_fdt; 665 struct fdtable *old_fdt, *new_fdt;
667 666
668 *errorp = -ENOMEM; 667 *errorp = -ENOMEM;
@@ -673,25 +672,14 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
673 spin_lock(&oldf->file_lock); 672 spin_lock(&oldf->file_lock);
674 old_fdt = files_fdtable(oldf); 673 old_fdt = files_fdtable(oldf);
675 new_fdt = files_fdtable(newf); 674 new_fdt = files_fdtable(newf);
676 size = old_fdt->max_fdset;
677 open_files = count_open_files(old_fdt); 675 open_files = count_open_files(old_fdt);
678 expand = 0;
679 676
680 /* 677 /*
681 * Check whether we need to allocate a larger fd array or fd set. 678 * Check whether we need to allocate a larger fd array and fd set.
682 * Note: we're not a clone task, so the open count won't change. 679 * Note: we're not a clone task, so the open count won't change.
683 */ 680 */
684 if (open_files > new_fdt->max_fdset) {
685 new_fdt->max_fdset = 0;
686 expand = 1;
687 }
688 if (open_files > new_fdt->max_fds) { 681 if (open_files > new_fdt->max_fds) {
689 new_fdt->max_fds = 0; 682 new_fdt->max_fds = 0;
690 expand = 1;
691 }
692
693 /* if the old fdset gets grown now, we'll only copy up to "size" fds */
694 if (expand) {
695 spin_unlock(&oldf->file_lock); 683 spin_unlock(&oldf->file_lock);
696 spin_lock(&newf->file_lock); 684 spin_lock(&newf->file_lock);
697 *errorp = expand_files(newf, open_files-1); 685 *errorp = expand_files(newf, open_files-1);
@@ -739,8 +727,8 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
739 /* This is long word aligned thus could use a optimized version */ 727 /* This is long word aligned thus could use a optimized version */
740 memset(new_fds, 0, size); 728 memset(new_fds, 0, size);
741 729
742 if (new_fdt->max_fdset > open_files) { 730 if (new_fdt->max_fds > open_files) {
743 int left = (new_fdt->max_fdset-open_files)/8; 731 int left = (new_fdt->max_fds-open_files)/8;
744 int start = open_files / (8 * sizeof(unsigned long)); 732 int start = open_files / (8 * sizeof(unsigned long));
745 733
746 memset(&new_fdt->open_fds->fds_bits[start], 0, left); 734 memset(&new_fdt->open_fds->fds_bits[start], 0, left);