[PATCH 2 of 6]

Juan Perez-Sanchez <[email protected]>
Newsgroups org.kernel.vger.linux-8086
Message-ID <CAD6VGuZz7OJoPX_X=0OLpFWfx470ZUak1iMZMGkji4Uhem9+Og@mail.gmail.com>
Hi,

Attached is a patch with:

   Modification of file read and write operations in fs/block_dev.c,
fs/minix/file.c and fs/pipe.c to have a closer implementation. Also,
fixed some minor problems in file.c (e.g. minix_file_read checks
*inode to be nonzero after actually dereferencing it).

   The purpose of a closer implementation of these functions is to see
what are the important differences and provide insight on how to write
a unique generic implementation (as in mainstream linux).

   The modified functions do the same things than the originals, only
the pointers and counters book keeping was greatly simplified. These
were tested copying a lot of files running elks under qemu, checking
the integrity of the copied files and running fsck for the modified
filesystem under linux.

   As result of the modifications the code size was reduced in 352 bytes.

 The Image builded without errors. The kernel was tested with QEMU and
dioscuri emulators. Also in a PPro pc booting from floppy.

Greetings,

Juan
elksV.patch (application/octet-stream, 8 KB)
diff -Nur elks.orig/fs/block_dev.c elks/fs/block_dev.c
--- elks.orig/fs/block_dev.c	2012-11-04 13:05:43.000000000 -0600
+++ elks/fs/block_dev.c	2013-02-12 15:11:30.000000000 -0600
@@ -37,7 +37,7 @@
 	/*
 	*      Offset to block/offset
 	*/
-	block = (block_t) (filp->f_pos >> 10);
+        block = (block_t) (filp->f_pos >> BLOCK_SIZE_BITS);
 	offset = ((unsigned int)filp->f_pos) & (BLOCK_SIZE - 1);
 
 	/*
diff -Nur elks.orig/fs/minix/file.c elks/fs/minix/file.c
--- elks.orig/fs/minix/file.c	2012-10-18 13:48:54.000000000 -0500
+++ elks/fs/minix/file.c	2013-02-13 16:04:28.000000000 -0600
@@ -28,7 +28,7 @@
 #include <linuxmt/minix_fs.h>
 
 static int minix_file_read(struct inode *inode, register struct file *filp,
-			   char *buf, size_t icount);
+			    char *buf, size_t count);
 
 static int minix_file_write(register struct inode *inode, struct file *filp,
 			    char *buf, size_t count);
@@ -84,29 +84,12 @@
 static char mode_equal_val[] = "mode = %07o\n";
 
 static int minix_file_read(struct inode *inode, register struct file *filp,
-			   char *buf, size_t icount)
+			    char *buf, size_t count)
 {
     struct buffer_head *bh;
-    loff_t offset, size, left;
-    size_t chars, count = (icount % 65536);
-    int read;
-    block_t block, blocks;
-
-    offset = filp->f_pos;
-    size = (loff_t) inode->i_size;
-
-    /*
-     *      Amount we can do I/O over
-     */
-
-    left = (offset > size) ? 0 : size - offset;
-
-    if (left > count)
-	left = count;
-    if (left <= 0) {
-	debug("MFSREAD: EOF reached.\n");
-	return 0;		/* EOF */
-    }
+    loff_t offset;
+    size_t chars;
+    int read = 0;
 
     {
 	register char *s;
@@ -122,42 +105,42 @@
 	}
     }
 
-    read = 0;
+    /*
+     *      Amount we can do I/O over
+     */
+    offset = ((loff_t)inode->i_size) - filp->f_pos;
+    if (offset <= 0) {
+	debug("MFSREAD: EOF reached.\n");
+	return 0;		/* EOF */
+    }
+    if (offset < (loff_t)count)
+        count = (size_t)offset;
+
+    while (count > 0) {
     /*
      *      Block, offset pair from the byte offset
      */
-    block = (block_t) (offset >> BLOCK_SIZE_BITS);
-    offset &= BLOCK_SIZE - 1;
-    blocks = (block_t) ((offset + left + (BLOCK_SIZE - 1)) >> BLOCK_SIZE_BITS);
-
-    while (blocks--) {
-	debug1("MINREAD: Reading block #%d\n", block);
-	if ((bh = minix_getblk(inode, block++, 0))) {
-	    debug2("MINREAD: block %d = buffer %d\n", block - 1, bh->b_num);
+	offset = filp->f_pos & (BLOCK_SIZE - 1);
+        chars = BLOCK_SIZE - (size_t)offset;
+        if (chars > count)
+            chars = count;
+
+        bh = minix_getblk(inode, (block_t)(filp->f_pos >> BLOCK_SIZE_BITS), 0);
+	if (bh) {
 	    if (!readbuf(bh)) {
 		debug("MINREAD: readbuf failed\n");
-		left = 0;
 		break;
 	    }
-	}
-
-	chars = (left < (BLOCK_SIZE - offset)) ? left : (BLOCK_SIZE - offset);
-
-	filp->f_pos += chars;
-	left -= chars;
-	read += chars;
-	if (bh) {
 	    map_buffer(bh);
-	    debug2("MINREAD: Copying data for block #%d, buffer #%d\n",
-		 block - 1, bh->b_num);
-	    memcpy_tofs(buf, offset + bh->b_data, (size_t) chars);
+	    memcpy_tofs(buf, bh->b_data + offset, chars);
 	    unmap_brelse(bh);
-	    buf += chars;
 	} else {
-	    while (chars-- > 0)
-		put_user_char((unsigned char)0, (void *)(buf++));
+            fmemset(buf, current->t_regs.ds, 0, chars);
 	}
-	offset = 0;
+	buf += chars;
+        filp->f_pos += chars;
+        read += chars;
+        count -= chars;
     }
     if (!read)
 	return -EIO;
@@ -175,9 +158,9 @@
 static int minix_file_write(register struct inode *inode,
 			    struct file *filp, char *buf, size_t count)
 {
-    char *p;
     loff_t pos;
-    size_t c, written;
+    size_t chars, offset;
+    size_t written = 0;
 
     {
 	register char *s;
@@ -198,20 +181,21 @@
 	? (loff_t) inode->i_size
 	: filp->f_pos;
 
-    written = 0;
-    while (written < count) {
+    while (count > 0) {
 	register struct buffer_head *bh;
 
-	bh = minix_getblk(inode, (unsigned short) (pos >> BLOCK_SIZE_BITS), 1);
+        offset = (size_t)pos & (BLOCK_SIZE - 1);
+	chars = BLOCK_SIZE - offset;
+	if (chars > count)
+	    chars = count;
+
+	bh = minix_getblk(inode, (block_t) (pos >> BLOCK_SIZE_BITS), 1);
 	if (!bh) {
 	    if (!written)
 		written = -ENOSPC;
 	    break;
 	}
-	c = BLOCK_SIZE - (pos % BLOCK_SIZE);
-	if (c > count - written)
-	    c = count - written;
-	if (c != BLOCK_SIZE && !buffer_uptodate(bh)) {
+	if (chars != BLOCK_SIZE && !buffer_uptodate(bh)) {
 	    if (!readbuf(bh)) {
 		if (!written)
 		    written = -EIO;
@@ -219,19 +203,19 @@
 	    }
 	}
 	map_buffer(bh);
-	p = (pos % BLOCK_SIZE) + bh->b_data;
-	memcpy_fromfs(p, buf, c);
+	memcpy_fromfs((bh->b_data + offset), buf, chars);
 	mark_buffer_uptodate(bh, 1);
 	mark_buffer_dirty(bh, 1);
 	unmap_brelse(bh);
-	pos += c;
-	written += c;
-	buf += c;
+	buf += chars;
+	pos += chars;
+	written += chars;
+        count -= chars;
     }
     if (pos > (loff_t) inode->i_size)
 	inode->i_size = (__u32) pos;
-    inode->i_mtime = inode->i_ctime = CURRENT_TIME;
     filp->f_pos = pos;
+    inode->i_mtime = inode->i_ctime = CURRENT_TIME;
     inode->i_dirt = 1;
     return (int) written;
 }
diff -Nur elks.orig/fs/pipe.c elks/fs/pipe.c
--- elks.orig/fs/pipe.c	2012-10-18 13:48:54.000000000 -0500
+++ elks/fs/pipe.c	2013-02-13 17:58:05.000000000 -0600
@@ -82,8 +82,8 @@
 static size_t pipe_read(register struct inode *inode, struct file *filp,
 		     char *buf, int count)
 {
-    size_t chars = 0, size = 0, read = 0;
-    register char *pipebuf;
+    size_t size, read = 0;
+    register char *chars;
 
     debug("PIPE: read called.\n");
     if (filp->f_flags & O_NONBLOCK) {
@@ -103,19 +103,17 @@
 	}
     (inode->u.pipe_i.lock)++;
     while (count > 0 && (size = (size_t) (inode->u.pipe_i.len))) {
-	chars = (PIPE_BUF - (inode->u.pipe_i.start));
-	if (chars > (size_t) count)
-	    chars = (size_t) count;
-	if (chars > size)
-	    chars = size;
-	read += chars;
-	pipebuf = (inode->u.pipe_i.base) + (inode->u.pipe_i.start);
-	(inode->u.pipe_i.start) += chars;
-	(inode->u.pipe_i.start) &= (PIPE_BUF - 1);
-	(inode->u.pipe_i.len) -= chars;
-	count -= chars;
-	memcpy_tofs(buf, pipebuf, chars);
-	buf += chars;
+	chars = (char *)(PIPE_BUF - (inode->u.pipe_i.start));
+	if ((size_t)chars > (size_t) count)
+	    chars = (char *)count;
+	if ((size_t)chars > size)
+	    chars = (char *)size;
+	memcpy_tofs(buf, (inode->u.pipe_i.base+inode->u.pipe_i.start), (size_t)chars);
+	buf += (size_t)chars;
+        inode->u.pipe_i.start = (inode->u.pipe_i.start + (size_t)chars)&(PIPE_BUF-1);
+	(inode->u.pipe_i.len) -= (size_t)chars;
+	read += (size_t)chars;
+	count -= (int)chars;
     }
     (inode->u.pipe_i.lock)--;
     wake_up_interruptible(&(inode->u.pipe_i.wait));
@@ -131,8 +129,8 @@
 static size_t pipe_write(register struct inode *inode, struct file *filp,
 		      char *buf, int count)
 {
-    register char *pipebuf;
-    size_t chars = 0, free = 0, written = 0;
+    size_t free, tmp, written = 0;
+    register char *chars;
 
     debug("PIPE: write called.\n");
     if (!(inode->u.pipe_i.readers)) {
@@ -157,23 +155,18 @@
 	(inode->u.pipe_i.lock)++;
 	while (count > 0 && (free = (PIPE_BUF - (inode->u.pipe_i.len)))) {
 
-	    chars = -(((inode->u.pipe_i.start) + (inode->u.pipe_i.len))
-		      & (PIPE_BUF - 1)) + PIPE_BUF;
-
-	    if (chars > (size_t) count)
-		chars = (size_t) count;
-
-	    if (chars > free)
-		chars = free;
-
-	    pipebuf = (((inode->u.pipe_i.start) + (inode->u.pipe_i.len))
-		       & (PIPE_BUF - 1)) + (inode->u.pipe_i.base);
-
-	    written += chars;
-	    (inode->u.pipe_i.len) += chars;
-	    count -= chars;
-	    memcpy_fromfs(pipebuf, buf, chars);
-	    buf += chars;
+            tmp = (inode->u.pipe_i.start + inode->u.pipe_i.len)&(PIPE_BUF-1);
+	    chars = (char *)(PIPE_BUF - tmp);
+	    if ((size_t)chars > (size_t) count)
+		chars = (char *) count;
+	    if ((size_t)chars > free)
+		chars = (char *)free;
+
+	    memcpy_fromfs((inode->u.pipe_i.base + tmp), buf, (size_t)chars);
+	    buf += (size_t)chars;
+	    (inode->u.pipe_i.len) += (size_t)chars;
+	    written += (size_t)chars;
+	    count -= (int)chars;
 	}
 	(inode->u.pipe_i.lock)--;
 	wake_up_interruptible(&(inode->u.pipe_i.wait));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.