[PATCH] Simplification of file structures initialization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 = &current->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;
 }
 

[Index of Archives]     [Kernel]     [Linux ia64]     [DCCP]     [Linux for ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux