linux-8086.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Juan Perez-Sanchez <lithoxs@gmail.com>
To: linux-8086 <linux-8086@vger.kernel.org>
Cc: Jody Bruchon <jody@jodybruchon.com>
Subject: [PATCH 2 of 6]
Date: Sun, 17 Mar 2013 13:05:21 -0600	[thread overview]
Message-ID: <CAD6VGuZz7OJoPX_X=0OLpFWfx470ZUak1iMZMGkji4Uhem9+Og@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1016 bytes --]

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

[-- Attachment #2: elksV.patch --]
[-- Type: application/octet-stream, Size: 8221 bytes --]

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));

                 reply	other threads:[~2013-03-17 19:05 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAD6VGuZz7OJoPX_X=0OLpFWfx470ZUak1iMZMGkji4Uhem9+Og@mail.gmail.com' \
    --to=lithoxs@gmail.com \
    --cc=jody@jodybruchon.com \
    --cc=linux-8086@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).