Hi, This patch makes: -Function get_empty_filp() now initializes some fields of file struct. Previously, these initializations were repeated at several points in the source tree: open.c, pipe.c, socket.c and exec.c. -Variable nr_files always equals NR_FILE. So, removed it and simplified the code that uses it. -Function get_pipe_mem() uses a boolean array. Replaced it with a bitmap. -Code size was reduced by 112 bytes and data reduced by 20 bytes. Greetings, Juan
diff -Nur elks.orig/fs/exec.c elks/fs/exec.c --- elks.orig/fs/exec.c 2014-04-26 22:12:31.000000000 -0500 +++ elks/fs/exec.c 2014-10-14 10:39:02.000000000 -0500 @@ -54,10 +54,9 @@ int sys_execve(char *filename, char *sptr, size_t slen) { - struct file file; /* We can push this to stack its now only 20 bytes */ void *ptr; struct inode *inode; - register struct file *filp = &file; + register struct file *filp; __registers *tregs; unsigned int suidfile, sgidfile; int retval; @@ -84,11 +83,9 @@ debug("EXEC: start building a file handle\n"); /* - * Build a reading file handle + * Get a reading file handle */ - filp->f_mode = filp->f_count = 1; - filp->f_flags = 0; - filp->f_pos = 0; /* FIXME - should call lseek */ + filp = get_empty_filp(O_RDONLY); filp->f_inode = inode; #ifdef BLOAT_FS @@ -98,7 +95,7 @@ filp->f_op = inode->i_op->default_file_ops; retval = -ENOEXEC; if ((!filp->f_op) - || ((filp->f_op->open) && (filp->f_op->open(inode, &file))) + || ((filp->f_op->open) && (filp->f_op->open(inode, filp))) || (!filp->f_op->read)) goto close_readexec; @@ -121,7 +118,7 @@ effuid = pinode->i_uid; effgid = pinode->i_gid; - result = filp->f_op->read(pinode, &file, &mh, sizeof(mh)); + result = filp->f_op->read(pinode, filp, &mh, sizeof(mh)); } tregs->ds = ds; @@ -140,7 +137,7 @@ if ((unsigned int) mh.hlen == 0x30) { /* BIG HEADER */ tregs->ds = get_ds(); - result = filp->f_op->read(inode, &file, &msuph, sizeof(msuph)); + result = filp->f_op->read(inode, filp, &msuph, sizeof(msuph)); tregs->ds = ds; if (result != sizeof(msuph)) { debug1("EXEC: Bad secondary header, result %u\n", result); @@ -217,7 +214,7 @@ if(load_code){ tregs->ds = cseg; - result = filp->f_op->read(inode, &file, 0, mh.tseg); + result = filp->f_op->read(inode, filp, 0, mh.tseg); tregs->ds = ds; if (result != mh.tseg) { debug2("EXEC(tseg read): bad result %u, expected %u\n", @@ -232,7 +229,7 @@ } tregs->ds = dseg; - result = filp->f_op->read(inode, &file, (char *)stack_top, mh.dseg); + result = filp->f_op->read(inode, filp, (char *)stack_top, mh.dseg); tregs->ds = ds; if (result != mh.dseg) { debug2("EXEC(dseg read): bad result %d, expected %d\n", @@ -348,7 +345,8 @@ close_readexec: if (filp->f_op->release) - filp->f_op->release(inode, &file); + filp->f_op->release(inode, filp); + filp->f_count--; end_readexec: diff -Nur elks.orig/fs/file_table.c elks/fs/file_table.c --- elks.orig/fs/file_table.c 2014-04-26 22:12:31.000000000 -0500 +++ elks/fs/file_table.c 2014-10-14 10:49:03.000000000 -0500 @@ -7,16 +7,15 @@ #include <linuxmt/types.h> #include <linuxmt/config.h> #include <linuxmt/fs.h> +#include <linuxmt/fcntl.h> #include <linuxmt/string.h> #include <linuxmt/mm.h> /* * first_file points to a doubly linked list of all file structures in * the system. - * nr_files holds the length of this list. */ -int nr_files = NR_FILE; struct file file_array[NR_FILE]; /* @@ -25,20 +24,23 @@ * we run out of memory. */ -struct file *get_empty_filp(void) +struct file *get_empty_filp(unsigned short flags) { - register struct file *f; + register struct file *f = file_array; - for(f = file_array; f < &file_array[NR_FILE]; f++) { + do { if (!f->f_count) { /* TODO: is nr_file const? */ - memset(f, 0, sizeof(*f)); + memset(f, 0, sizeof(struct file)); + f->f_flags = flags; + f->f_mode = (mode_t) ((flags + 1) & O_ACCMODE); f->f_count = 1; + f->f_pos = 0; /* FIXME - should call lseek */ #ifdef BLOAT_FS f->f_version = ++event; #endif return f; } - } + } while(++f < &file_array[NR_FILE]); return NULL; } diff -Nur elks.orig/fs/inode.c elks/fs/inode.c --- elks.orig/fs/inode.c 2014-04-26 22:12:31.000000000 -0500 +++ elks/fs/inode.c 2014-10-14 10:49:03.000000000 -0500 @@ -142,18 +142,17 @@ int fs_may_remount_ro(kdev_t dev) { - register struct file *file; + register struct file *file = file_array; register struct inode *inode; - int i; /* Check that no files are currently opened for writing. */ - for (file = file_array, i = 0; i < nr_files; i++, file++) { + do { inode = file->f_inode; if (!file->f_count || !inode || inode->i_dev != dev) continue; if (S_ISREG(inode->i_mode) && (file->f_mode & 2)) return 0; - } + } while(++file < &file_array[NR_FILE]); return 1; } diff -Nur elks.orig/fs/open.c elks/fs/open.c --- elks.orig/fs/open.c 2014-04-26 22:12:31.000000000 -0500 +++ elks/fs/open.c 2014-10-14 10:49:03.000000000 -0500 @@ -372,13 +372,12 @@ register struct file *f; int error, fd, flag; - f = get_empty_filp(); + f = get_empty_filp(flags); if (!f) { printk("\nNo filps\n"); return -ENFILE; } - f->f_flags = (unsigned short int) (flag = flags); - f->f_mode = (mode_t) ((flag + 1) & O_ACCMODE); + flag = flags; if (f->f_mode) flag++; if (flag & (O_TRUNC | O_CREAT)) @@ -396,7 +395,6 @@ #endif f->f_inode = inode; - f->f_pos = 0; #ifdef BLOAT_FS f->f_reada = 0; diff -Nur elks.orig/fs/pipe.c elks/fs/pipe.c --- elks.orig/fs/pipe.c 2014-04-26 22:12:31.000000000 -0500 +++ elks/fs/pipe.c 2014-10-14 10:49:03.000000000 -0500 @@ -60,25 +60,22 @@ char pipe_base[MAX_PIPES][PIPE_BUF]; -int pipe_in_use[MAX_PIPES] = /*@i1@*/ { 0, }; +int pipe_in_use[(MAX_PIPES + 15)/16]; char *get_pipe_mem(void) { - register char *pi = 0; + int i = 0; - do { - if (!pipe_in_use[(int)pi]) { - pipe_in_use[(int)pi] = 1; - return pipe_base[(int)pi]; - } - ++pi; - } while (((int)pi) < MAX_PIPES); + i = find_first_zero_bit(pipe_in_use, MAX_PIPES); + if(i < MAX_PIPES) { + set_bit(i, pipe_in_use); + return pipe_base[i]; + } debug("PIPE: No more buffers.\n"); /* FIXME */ return NULL; } - static size_t pipe_read(register struct inode *inode, struct file *filp, char *buf, int count) { @@ -302,66 +299,60 @@ register struct file *f1; register struct file *f2; int error = ENFILE; - int i, j; + int i; - f1 = get_empty_filp(); + /* read file */ + f1 = get_empty_filp(O_RDONLY); if (!f1) goto no_files; + f1->f_op = &read_pipe_fops; - f2 = get_empty_filp(); + /* write file */ + f2 = get_empty_filp(O_WRONLY); if (!f2) goto close_f1; + f2->f_op = &write_pipe_fops; inode = get_pipe_inode(); if (!inode) goto close_f12; + f1->f_inode = f2->f_inode = inode; error = get_unused_fd(); if (error < 0) goto close_f12_inode; - i = error; - current->files.fd[i] = f1; error = get_unused_fd(); if (error < 0) goto close_f12_inode_i; - j = error; - f1->f_inode = f2->f_inode = inode; - - /* read file */ - f1->f_pos = f2->f_pos = 0; - f1->f_flags = O_RDONLY; - f1->f_op = &read_pipe_fops; - f1->f_mode = 1; - - /* write file */ - f2->f_flags = O_WRONLY; - f2->f_op = &write_pipe_fops; - f2->f_mode = 2; - - current->files.fd[j] = f2; + current->files.fd[i] = f1; + current->files.fd[error] = f2; fd[0] = i; - fd[1] = j; + fd[1] = error; return 0; close_f12_inode_i: #if 0 + put_unused_fd(error); /* Not sure this is needed */ +#endif + close_f12_inode: +#if 0 put_unused_fd(i); /* Not sure this is needed */ #endif - - current->files.fd[i] = NULL; - - close_f12_inode:inode->i_count--; + inode->i_count--; iput(inode); - close_f12:f2->f_count--; + close_f12: + f2->f_count--; - close_f1:f1->f_count--; + close_f1: + f1->f_count--; - no_files:return error; + no_files: + return error; } int sys_pipe(unsigned int *filedes) diff -Nur elks.orig/include/linuxmt/fs.h elks/include/linuxmt/fs.h --- elks.orig/include/linuxmt/fs.h 2014-04-26 22:12:31.000000000 -0500 +++ elks/include/linuxmt/fs.h 2014-10-14 10:49:03.000000000 -0500 @@ -423,7 +423,6 @@ extern int fs_may_remount_ro(kdev_t); extern struct file file_array[]; -extern int nr_files; extern struct super_block super_blocks[]; extern void invalidate_inodes(kdev_t); @@ -462,7 +461,7 @@ extern void insert_inode_hash(struct inode *); extern void clear_inode(struct inode *); extern struct inode *get_pipe_inode(void); -extern struct file *get_empty_filp(void); +extern struct file *get_empty_filp(unsigned short); extern struct buffer_head *get_hash_table(kdev_t,block_t); extern struct buffer_head *getblk(kdev_t,block_t); diff -Nur elks.orig/net/socket.c elks/net/socket.c --- elks.orig/net/socket.c 2014-04-26 22:12:31.000000000 -0500 +++ elks/net/socket.c 2014-10-14 10:49:03.000000000 -0500 @@ -232,7 +232,7 @@ return -EINVAL; /* - * Put ourselves on the server's incomplete connection queue. + * Put ourselves on the server's incomplete connection queue. */ mysock->next = NULL; @@ -410,20 +410,16 @@ fd = get_unused_fd(); if (fd >= 0) { - struct file *file = get_empty_filp(); + struct file *file = get_empty_filp(O_RDWR); if (!file) { return -ENFILE; } - current->files.fd[fd] = file; - file->f_op = &socket_file_ops; - file->f_mode = 3; - file->f_flags = O_RDWR; - file->f_count = 1; file->f_inode = inode; + file->f_op = &socket_file_ops; if (inode) inode->i_count++; - file->f_pos = 0; + current->files.fd[fd] = file; } return fd; }