patch for 2.1.89 file_struct

Bill Hawes (whawes@star.net)
Sat, 07 Mar 1998 15:37:06 -0500


This is a multi-part message in MIME format.
--------------EA15AB6EAFA5C8C119B1B0EE
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

The attached patch splits the allocation of the files_struct into two parts and
adds a max_fds field, in preparation for a variable-length fd[] array. Breaking
the structure into two parts will help ease memory allocation problems on busy
systems.

As soon as the remaining direct references to current->files->fd[] are suitably
wrapped, I'll add the changes for a variable-length array.

I've been running the patch on my system for a while now with no problems.

Regards,
Bill
--------------EA15AB6EAFA5C8C119B1B0EE
Content-Type: text/plain; charset=us-ascii; name="fd_array89-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="fd_array89-patch"

--- linux-2.1.89/include/linux/sched.h.old Sat Mar 7 11:40:57 1998
+++ linux-2.1.89/include/linux/sched.h Sat Mar 7 15:02:59 1998
@@ -113,19 +113,24 @@

asmlinkage void schedule(void);

-/* Open file table structure */
+
+/*
+ * Open file table structure
+ */
struct files_struct {
int count;
+ int max_fds;
+ struct file ** fd; /* current fd array */
fd_set close_on_exec;
fd_set open_fds;
- struct file * fd[NR_OPEN];
};

#define INIT_FILES { \
1, \
+ NR_OPEN, \
+ &init_fd_array[0], \
{ { 0, } }, \
- { { 0, } }, \
- { NULL, } \
+ { { 0, } } \
}

struct fs_struct {
@@ -571,19 +576,6 @@
extern int do_execve(char *, char **, char **, struct pt_regs *);
extern int do_fork(unsigned long, unsigned long, struct pt_regs *);

-/* See if we have a valid user level fd.
- * If it makes sense, return the file structure it references.
- * Otherwise return NULL.
- */
-extern inline struct file *file_from_fd(const unsigned int fd)
-{
-
- if (fd >= NR_OPEN)
- return NULL;
- /* either valid or null */
- return current->files->fd[fd];
-}
-
/*
* The wait-queues are circular lists, and you have to be *very* sure
* to keep them correct. Use only these two functions to add/remove
--- linux-2.1.89/kernel/fork.c.old Sat Mar 7 11:32:19 1998
+++ linux-2.1.89/kernel/fork.c Sat Mar 7 15:02:59 1998
@@ -375,44 +375,66 @@
return __copy_fdset(dst->fds_bits, src->fds_bits);
}

-static inline int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
{
- int i;
struct files_struct *oldf, *newf;
struct file **old_fds, **new_fds;
+ int size, i, error = 0;

/*
* A background process may not have any files ...
*/
oldf = current->files;
if (!oldf)
- return 0;
+ goto out;

if (clone_flags & CLONE_FILES) {
oldf->count++;
- return 0;
+ goto out;
}

+ tsk->files = NULL;
+ error = -ENOMEM;
newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
- tsk->files = newf;
if (!newf)
- return -1;
+ goto out;
+
+ /*
+ * Allocate the fd array, using get_free_page() if possible.
+ * Eventually we want to make the array size variable ...
+ */
+ size = NR_OPEN * sizeof(struct file *);
+ if (size == PAGE_SIZE)
+ new_fds = (struct file **) __get_free_page(GFP_KERNEL);
+ else
+ new_fds = (struct file **) kmalloc(size, GFP_KERNEL);
+ if (!new_fds)
+ goto out_release;
+ memset((void *) new_fds, 0, size);

newf->count = 1;
+ newf->max_fds = NR_OPEN;
+ newf->fd = new_fds;
newf->close_on_exec = oldf->close_on_exec;
- i = copy_fdset(&newf->open_fds,&oldf->open_fds);
+ i = copy_fdset(&newf->open_fds, &oldf->open_fds);

old_fds = oldf->fd;
- new_fds = newf->fd;
for (; i != 0; i--) {
struct file * f = *old_fds;
old_fds++;
*new_fds = f;
- new_fds++;
if (f)
f->f_count++;
+ new_fds++;
}
- return 0;
+ tsk->files = newf;
+ error = 0;
+out:
+ return error;
+
+out_release:
+ kmem_cache_free(files_cachep, newf);
+ goto out;
}

static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
--- linux-2.1.89/kernel/exit.c.old Sat Mar 7 11:32:19 1998
+++ linux-2.1.89/kernel/exit.c Sat Mar 7 15:02:59 1998
@@ -157,7 +157,7 @@
unsigned long set = files->open_fds.fds_bits[j];
i = j * __NFDBITS;
j++;
- if (i >= NR_OPEN)
+ if (i >= files->max_fds)
break;
while (set) {
if (set & 1) {
@@ -183,6 +183,13 @@
tsk->files = NULL;
if (!--files->count) {
close_files(files);
+ /*
+ * Free the fd array as appropriate ...
+ */
+ if (NR_OPEN * sizeof(struct file *) == PAGE_SIZE)
+ free_page((unsigned long) files->fd);
+ else
+ kfree(files->fd);
kmem_cache_free(files_cachep, files);
}
}
--- linux-2.1.89/arch/i386/kernel/init_task.c.old Mon Dec 1 23:56:55 1997
+++ linux-2.1.89/arch/i386/kernel/init_task.c Sat Mar 7 15:02:59 1998
@@ -6,6 +6,7 @@

static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
--- linux-2.1.89/arch/mips/kernel/init_task.c.old Thu Jun 26 15:33:37 1997
+++ linux-2.1.89/arch/mips/kernel/init_task.c Sat Mar 7 15:02:59 1998
@@ -5,6 +5,7 @@

static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
--- linux-2.1.89/arch/arm/kernel/init_task.c.old Tue Jan 20 23:55:24 1998
+++ linux-2.1.89/arch/arm/kernel/init_task.c Sat Mar 7 15:02:59 1998
@@ -6,6 +6,7 @@

static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
--- linux-2.1.89/arch/sparc/kernel/init_task.c.old Wed May 14 01:41:03 1997
+++ linux-2.1.89/arch/sparc/kernel/init_task.c Sat Mar 7 15:02:59 1998
@@ -6,6 +6,7 @@

static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
--- linux-2.1.89/arch/sparc64/kernel/init_task.c.old Thu May 15 19:48:02 1997
+++ linux-2.1.89/arch/sparc64/kernel/init_task.c Sat Mar 7 15:02:59 1998
@@ -6,6 +6,7 @@

static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
--- linux-2.1.89/arch/alpha/kernel/process.c.old Tue Jan 13 10:38:14 1998
+++ linux-2.1.89/arch/alpha/kernel/process.c Sat Mar 7 15:03:00 1998
@@ -50,6 +50,7 @@
unsigned long init_user_stack[1024] = { STACK_MAGIC, };
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
--- linux-2.1.89/arch/ppc/kernel/process.c.old Sat Feb 21 09:24:51 1998
+++ linux-2.1.89/arch/ppc/kernel/process.c Sat Mar 7 15:03:00 1998
@@ -64,6 +64,7 @@

static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;

--- linux-2.1.89/arch/m68k/kernel/process.c.old Tue Feb 17 10:34:24 1998
+++ linux-2.1.89/arch/m68k/kernel/process.c Sat Mar 7 15:03:00 1998
@@ -40,6 +40,7 @@
*/
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;

--------------EA15AB6EAFA5C8C119B1B0EE--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu