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