Hi, Functions sys_execve(), get_pipe_inode(), sys_open(), close_fp() and get_fd() repeated a lot of code. Now most of the work is done in the new functions open_filp() and close_filp(). The new kernel was tested under QEMU and a PentiumPro PC booting from floppy. There was a reduction of 176 bytes in code size. Greetings, Juan
diff -Nur elks.orig/arch/i86/drivers/char/dircon.c elks/arch/i86/drivers/char/dircon.c --- elks.orig/arch/i86/drivers/char/dircon.c 2014-12-08 07:24:41.000000000 -0600 +++ elks/arch/i86/drivers/char/dircon.c 2015-01-23 18:03:06.000000000 -0600 @@ -105,8 +105,6 @@ }; #endif -static void ClearRange(register Console * C, int x, int y, int xx, int yy); - #ifdef CONFIG_DCON_VT52 static void ScrollDown(register Console * C, int st, int en); @@ -138,6 +136,20 @@ } } +static void ClearRange(register Console * C, int x, int y, int xx, int yy) +{ + __u16 en, ClrW; + register char *ofsp; + + ClrW = (__u16) ((A_DEFAULT << 8) + ' '); + en = (__u16) ((xx + yy * Width) << 1); + ofsp = (char *)((__u16) ((x + y * Width) << 1)); + while (((__u16)ofsp) < en) { + pokew((__u16) C->vseg, (__u16) ofsp, ClrW); + ofsp += 2; + } +} + static void ScrollUp(register Console * C, int st, int en) { unsigned rdofs, wrofs; @@ -253,20 +265,6 @@ #endif -static void ClearRange(register Console * C, int x, int y, int xx, int yy) -{ - __u16 en, ClrW; - register char *ofsp; - - ClrW = (__u16) ((A_DEFAULT << 8) + ' '); - en = (__u16) ((xx + yy * Width) << 1); - ofsp = (char *)((__u16) ((x + y * Width) << 1)); - while (((__u16)ofsp) < en) { - pokew((__u16) C->vseg, (__u16) ofsp, ClrW); - ofsp += 2; - } -} - #ifdef CONFIG_DCON_VT52 void Vt52Cmd(register Console * C, char c) diff -Nur elks.orig/fs/exec.c elks/fs/exec.c --- elks.orig/fs/exec.c 2015-01-21 18:26:30.000000000 -0600 +++ elks/fs/exec.c 2015-01-16 15:17:02.000000000 -0600 @@ -56,8 +56,8 @@ { void *ptr; struct inode *inode; - register struct file *filp; - __registers *tregs; + struct file *filp; + register __registers *tregs; unsigned int suidfile, sgidfile; int retval; __u16 ds; @@ -84,24 +84,11 @@ /* * Get a reading file handle */ - retval = -ENFILE; - filp = get_empty_filp(O_RDONLY); - if(!filp) { - debug("\nNo filps\n"); + if((retval = open_filp(O_RDONLY, inode, &filp))) goto error_exec2; - } - filp->f_inode = inode; - -#ifdef BLOAT_FS - filp->f_reada = 0; -#endif - - filp->f_op = inode->i_op->default_file_ops; retval = -ENOEXEC; - if ((!filp->f_op) - || ((filp->f_op->open) && (filp->f_op->open(inode, filp))) - || (!filp->f_op->read)) - goto normal_out; + if(!(filp->f_op) || !(filp->f_op->read)) + goto error_exec3; debug1("EXEC: Inode dev = 0x%x opened OK.\n", inode->i_dev); @@ -348,9 +335,7 @@ error_exec3: tregs->ds = ds; normal_out: - if(filp->f_op->release) - filp->f_op->release(inode, filp); - filp->f_count--; + close_filp(inode, filp); error_exec2: if(retval) diff -Nur elks.orig/fs/file_table.c elks/fs/file_table.c --- elks.orig/fs/file_table.c 2014-12-08 07:24:41.000000000 -0600 +++ elks/fs/file_table.c 2015-01-15 17:11:35.000000000 -0600 @@ -8,6 +8,7 @@ #include <linuxmt/config.h> #include <linuxmt/fs.h> #include <linuxmt/fcntl.h> +#include <linuxmt/stat.h> #include <linuxmt/string.h> #include <linuxmt/mm.h> @@ -24,23 +25,70 @@ * we run out of memory. */ -struct file *get_empty_filp(unsigned short flags) +int open_filp(unsigned short flags, struct inode *inode, struct file **fp) { + int result = 0; register struct file *f = file_array; + register struct file_operations *fop; do { - if (!f->f_count) { /* TODO: is nr_file const? */ - 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 */ + if (!f->f_count) + goto found_unused_fp; + } while(++f < &file_array[NR_FILE]); /* TODO: is nr_file const? */ + result = -ENFILE; + printk("\nNo filps\n"); + goto exit_open_filp; + + found_unused_fp: + 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; + f->f_version = ++event; #endif - return f; - } - } while(++f < &file_array[NR_FILE]); + f->f_inode = inode; +#ifdef BLOAT_FS + if (f->f_mode & FMODE_WRITE) { + result = get_write_access(inode); + if (result) + goto cleanup_file; + } +#endif + +#ifdef BLOAT_FS + f->f_reada = 0; +#endif + + if(inode->i_op) + f->f_op = inode->i_op->default_file_ops; + fop = f->f_op; + if(fop && fop->open && (result = fop->open(inode, f))) { +#ifdef BLOAT_FS + if(f->f_mode & FMODE_WRITE) + put_write_access(inode); + cleanup_file: +#endif + f->f_count--; + } + *fp = f; - return NULL; + exit_open_filp: + return result; +} + +void close_filp(struct inode *inode, struct file *f) +{ + register struct file_operations *fop; + + fop = f->f_op; + if(fop && fop->release) + fop->release(inode, f); + +#ifdef BLOAT_FS + if(f->f_mode & FMODE_WRITE) + put_write_access(inode); +#endif + f->f_count--; } diff -Nur elks.orig/fs/inode.c elks/fs/inode.c --- elks.orig/fs/inode.c 2015-01-21 17:05:29.000000000 -0600 +++ elks/fs/inode.c 2015-01-23 18:44:01.000000000 -0600 @@ -432,7 +432,7 @@ extern struct inode_operations pipe_inode_operations; if ((inode = get_empty_inode())) { - inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; + inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR; inode->i_op = &pipe_inode_operations; inode->i_gid = (__u8) current->egid; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; @@ -444,7 +444,7 @@ inode->i_pipe = 1; PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; + PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; PIPE_LOCK(*inode) = 0; #if 0 diff -Nur elks.orig/fs/minix/inode.c elks/fs/minix/inode.c --- elks.orig/fs/minix/inode.c 2014-12-08 07:24:41.000000000 -0600 +++ elks/fs/minix/inode.c 2014-12-19 10:28:01.000000000 -0600 @@ -26,7 +26,6 @@ static void minix_commit_super(register struct super_block *); static void minix_read_inode(register struct inode *); static struct buffer_head *minix_update_inode(register struct inode *); -extern struct inode_operations pipe_inode_operations; /* Function definitions */ @@ -413,7 +412,7 @@ &blkdev_inode_operations, &minix_file_inode_operations, &minix_symlink_inode_operations, - NULL, /* Socket */ + &sock_inode_operations, /* Socket */ }; inode->i_op = inop[(int)tabc[(inode->i_mode & S_IFMT) >> 12]]; diff -Nur elks.orig/fs/open.c elks/fs/open.c --- elks.orig/fs/open.c 2014-12-08 07:24:41.000000000 -0600 +++ elks/fs/open.c 2015-01-15 17:26:25.000000000 -0600 @@ -369,76 +369,36 @@ int sys_open(char *filename, int flags, int mode) { struct inode *inode; - register struct file *f; - int error, fd, flag; + struct file *f; + int error, flag; - f = get_empty_filp(flags); - if (!f) { - printk("\nNo filps\n"); - return -ENFILE; - } flag = flags; - if (f->f_mode) + if ((mode_t)((flags + 1) & O_ACCMODE)) flag++; if (flag & (O_TRUNC | O_CREAT)) - flag |= 2; + flag |= FMODE_WRITE; + error = open_namei(filename, flag, mode, &inode, NULL); + if(error) + goto exit_open; - if (!error) { + error = open_filp(flags, inode, &f); + if(error) + goto cleanup_inode; + f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); + + /* + * We have to do this last, because we mustn't export + * an incomplete fd to other processes which may share + * the same file table with us. + */ + if ((error = get_unused_fd(f)) > -1) + goto exit_open; + close_filp(inode, f); -#ifdef BLOAT_FS - if (f->f_mode & FMODE_WRITE) { - error = get_write_access(inode); - if (error) - goto cleanup_inode; - } -#endif - - f->f_inode = inode; - -#ifdef BLOAT_FS - f->f_reada = 0; -#endif - - f->f_op = NULL; - { - register struct inode_operations *iop = inode->i_op; - if (iop) - f->f_op = iop->default_file_ops; - } - { - register struct file_operations *fop = f->f_op; - if (fop && fop->open) { - error = fop->open(inode, f); - if (error) { - goto cleanup_all; - } - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - - /* - * We have to do this last, because we mustn't export - * an incomplete fd to other processes which may share - * the same file table with us. - */ - if ((fd = get_unused_fd()) > -1) { - current->files.fd[fd] = f; - return fd; - } - error = -EMFILE; - if (fop && fop->release) - fop->release(inode, f); - } - cleanup_all: -#ifdef BLOAT_FS - if (f->f_mode & FMODE_WRITE) - put_write_access(inode); - cleanup_inode: -#endif - iput(inode); - } - cleanup_file: - f->f_count--; + cleanup_inode: + iput(inode); + exit_open: return error; } @@ -446,25 +406,16 @@ { register struct inode *inode; - if (filp->f_count == 0) { + if (filp->f_count < 1) printk("VFS: Close: file count is 0\n"); - goto cfp_end; - } - if (filp->f_count > 1) { + else if (filp->f_count > 1) filp->f_count--; - goto cfp_end; + else { + inode = filp->f_inode; + close_filp(inode, filp); + filp->f_inode = NULL; + iput(inode); } - inode = filp->f_inode; - if (filp->f_op && filp->f_op->release) - filp->f_op->release(inode, filp); - filp->f_count--; - filp->f_inode = NULL; -#ifdef BLOAT_FS - if (filp->f_mode & FMODE_WRITE) - put_write_access(inode); -#endif - iput(inode); - cfp_end: return 0; } diff -Nur elks.orig/fs/pipe.c elks/fs/pipe.c --- elks.orig/fs/pipe.c 2015-01-21 17:28:26.000000000 -0600 +++ elks/fs/pipe.c 2015-01-23 17:17:42.000000000 -0600 @@ -28,13 +28,14 @@ #define MAX_PIPES 8 -int get_unused_fd(void) +int get_unused_fd(struct file *f) { register char *pfd = 0; register struct file_struct *cfs = ¤t->files; do { if (!cfs->fd[(unsigned int) pfd]) { + cfs->fd[(unsigned int) pfd] = f; clear_bit((unsigned int) pfd, &cfs->close_on_exec); return (int) pfd; @@ -183,6 +184,7 @@ return written; } +#ifdef STRICT_PIPES static void pipe_read_release(register struct inode *inode, struct file *filp) { debug("PIPE: read_release called.\n"); @@ -196,6 +198,7 @@ (inode->u.pipe_i.writers)--; wake_up_interruptible(&(inode->u.pipe_i.wait)); } +#endif static void pipe_rdwr_release(register struct inode *inode, register struct file *filp) @@ -211,6 +214,7 @@ wake_up_interruptible(&(inode->u.pipe_i.wait)); } +#ifdef STRICT_PIPES static int pipe_read_open(struct inode *inode, struct file *filp) { debug("PIPE: read_open called.\n"); @@ -226,6 +230,7 @@ return 0; } +#endif static int pipe_rdwr_open(register struct inode *inode, register struct file *filp) @@ -241,6 +246,7 @@ return 0; } +#ifdef STRICT_PIPES static size_t bad_pipe_rw(struct inode *inode, struct file *filp, char *buf, int count) { @@ -268,6 +274,7 @@ pipe_write_open, pipe_write_release, }; +#endif struct file_operations rdwr_pipe_fops = { pipe_lseek, @@ -304,9 +311,9 @@ int do_pipe(int *fd) { - struct inode *inode; - register struct file *f1; - register struct file *f2; + register struct inode *inode; + struct file *f1; + struct file *f2; int error = -ENOMEM; int i; @@ -315,48 +322,34 @@ goto no_inodes; /* read file */ - error = -ENFILE; - f1 = get_empty_filp(O_RDONLY); - if (!f1) + if((error = open_filp(O_RDONLY, inode, &f1))) goto no_files; - f1->f_inode = inode; - f1->f_op = &read_pipe_fops; - - error = get_unused_fd(); - if (error < 0) + if ((error = get_unused_fd(f1)) < 0) goto close_f1; - current->files.fd[error] = f1; fd[0] = error; i = error; (inode->i_count)++; /* Increase inode usage count */ /* write file */ - error = -ENFILE; - f2 = get_empty_filp(O_WRONLY); - if (!f2) + if((error = open_filp(O_WRONLY, inode, &f2))) goto close_f1_i; - f2->f_inode = inode; - f2->f_op = &write_pipe_fops; - - error = get_unused_fd(); - if (error < 0) + if ((error = get_unused_fd(f2)) < 0) goto close_f12; - current->files.fd[error] = f2; fd[1] = error; return 0; close_f12: - f2->f_count--; + close_filp(inode, f2); close_f1_i: current->files.fd[i] = NULL; inode->i_count--; close_f1: - f1->f_count--; + close_filp(inode, f1); no_files: iput(inode); diff -Nur elks.orig/include/linuxmt/fs.h elks/include/linuxmt/fs.h --- elks.orig/include/linuxmt/fs.h 2015-01-21 16:42:52.000000000 -0600 +++ elks/include/linuxmt/fs.h 2015-01-15 16:49:43.000000000 -0600 @@ -415,6 +415,10 @@ extern struct file_operations read_pipe_fops; extern struct file_operations write_pipe_fops; extern struct file_operations rdwr_pipe_fops; +extern struct inode_operations pipe_inode_operations; + +extern struct file_operations socket_file_ops; +extern struct inode_operations sock_inode_operations; extern struct file_system_type *get_fs_type(char *); @@ -461,7 +465,8 @@ 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(unsigned short); +extern int open_filp(unsigned short, struct inode *, struct file **); +extern void close_filp(struct inode *, struct file *); extern struct buffer_head *get_hash_table(kdev_t,block_t); extern struct buffer_head *getblk(kdev_t,block_t); @@ -509,7 +514,7 @@ extern struct buffer_head *bread(dev_t,block_t); -extern int get_unused_fd(void); +extern int get_unused_fd(struct file *); extern char *get_pipe_mem(void); extern void free_pipe_mem(char *buf); diff -Nur elks.orig/net/socket.c elks/net/socket.c --- elks.orig/net/socket.c 2014-12-08 07:24:41.000000000 -0600 +++ elks/net/socket.c 2015-01-15 18:04:28.000000000 -0600 @@ -103,6 +103,7 @@ return NULL; inode->i_mode = S_IFSOCK; + inode->i_op = &sock_inode_operations; inode->i_gid = (__u8) current->egid; inode->i_sock = 1; @@ -401,25 +402,42 @@ #endif }; +struct inode_operations sock_inode_operations = { + &socket_file_ops, NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* readlink */ + NULL, /* follow_link */ +#ifdef BLOAT_FS + NULL, /* bmap */ +#endif + NULL, /* truncate */ +#ifdef BLOAT_FS + NULL /* permission */ +#endif +}; + /*@+type@*/ -int get_fd(register struct inode *inode) +static int get_fd(register struct inode *inode) { int fd; + struct file *file; - fd = get_unused_fd(); - if (fd >= 0) { - struct file *file = get_empty_filp(O_RDWR); - if (!file) { - return -ENFILE; - } - - file->f_inode = inode; - file->f_op = &socket_file_ops; - if (inode) - inode->i_count++; - current->files.fd[fd] = file; + if((fd = open_filp(O_RDWR, inode, &file))) + goto no_files; + if ((fd = get_unused_fd(file)) > -1) { + inode->i_count++; /*FIXME: Really needed?*/ + goto no_files; } + + close_filp(inode, file); + no_files: return fd; }