The attached patch does: Ansification of several functions in block drivers. Moved assembly function printsp() from "kernel/memdumpk.c" to "arch/i86/kernel/printreg.c". Now, all assembly code is under directories "arch/i86" and "include/arch". Simplify code in files "fs/block_dev.c" and "fs/minix/file.c". At the start of functions minix_file_read() and minix_file_write() was a check for inode == NULL or inode mode != regular-file. After a thorough examination of the kernel code, I concluded that these conditions will never happen, so commented out the checks. Update of i_size field of inode structure when opening block devices. Simplify code in "fs/pipe.c", function pipe_read(). Functionality is exactly the same, with less code. Improve some comments in file "fs/namei.c". Code size was reduced by 80 bytes and data size reduced by 64 bytes. Juan
diff -Nur elks.orig/arch/i86/drivers/block/directhd.c elks/arch/i86/drivers/block/directhd.c --- elks.orig/arch/i86/drivers/block/directhd.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/drivers/block/directhd.c 2015-04-06 15:20:28.000000000 -0500 @@ -244,7 +244,7 @@ return; } -int directhd_init() +int directhd_init(void) { unsigned int buffer[256]; struct gendisk *ptr; @@ -380,11 +380,8 @@ /* why is arg unsigned int here if it's used as hd_geometry later ? * one of joys of K&R ? Someone please answer ... */ -static int directhd_ioctl( - struct inode *inode, - struct file *filp, - unsigned int cmd, - unsigned int arg) +static int directhd_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned int arg) { struct hd_geometry *loc = (struct hd_geometry *) arg; int dev, err; @@ -415,14 +412,16 @@ return -EINVAL; } -static int directhd_open( - struct inode *inode, - struct file *filp) +static int directhd_open(struct inode *inode, struct file *filp) { + unsigned int minor; int target = DEVICE_NR(inode->i_rdev); if (target >= 4 || !directhd_initialized) return -ENXIO; + minor = MINOR(inode->i_rdev); + if (((int) hd[minor].start_sect) == -1) + return -ENXIO; access_count[target]++; @@ -433,12 +432,11 @@ * any clues ? */ + inode->i_size = (hd[minor].nr_sects) << 9; return 0; } -static void directhd_release( - struct inode *inode, - struct file *filp) +static void directhd_release(struct inode *inode, struct file *filp) { int target = DEVICE_NR(inode->i_rdev); diff -Nur elks.orig/arch/i86/drivers/block/doshd.c elks/arch/i86/drivers/block/doshd.c --- elks.orig/arch/i86/drivers/block/doshd.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/drivers/block/doshd.c 2015-04-06 15:42:00.000000000 -0500 @@ -341,10 +341,12 @@ { register struct drive_infot *drivep; int fdtype, target; + unsigned int minor; target = DEVICE_NR(inode->i_rdev); /* >> 6 */ drivep = &drive_info[target]; fdtype = drivep->fdtype; + minor = MINOR(inode->i_rdev); /* Bounds testing */ @@ -352,7 +354,7 @@ return -ENXIO; if (target >= 4) return -ENXIO; - if (((int) hd[MINOR(inode->i_rdev)].start_sect) == -1) + if (((int) hd[minor].start_sect) == -1) return -ENXIO; #if 0 @@ -426,6 +428,8 @@ drivep->sectors = sector_probe[count]; } while(++count < 5); + drivep->heads = 2; + #else /* We can get the Geometry of the floppy from the BIOS. @@ -477,10 +481,14 @@ * * You may have to copy dpb to RAM as the original is in ROM. */ + hd[minor].start_sect = 0; + hd[minor].nr_sects = ((sector_t)(drivep->sectors * drivep->heads)) + * ((sector_t)drivep->cylinders); } #endif + inode->i_size = (hd[minor].nr_sects) << 9; return 0; } diff -Nur elks.orig/arch/i86/drivers/block/floppy.c elks/arch/i86/drivers/block/floppy.c --- elks.orig/arch/i86/drivers/block/floppy.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/drivers/block/floppy.c 2015-04-06 15:20:28.000000000 -0500 @@ -275,7 +275,7 @@ extern char tmp_floppy_area[BLOCK_SIZE]; extern char floppy_track_buffer[512 * 2 * MAX_BUFFER_SECTORS]; -static void redo_fd_request(); +static void redo_fd_request(void); /* * These are global variables, as that's the easiest way to give @@ -299,7 +299,7 @@ static unsigned char command = 0; static unsigned char fdc_version = FDC_TYPE_STD; /* FDC version code */ -static void floppy_ready(); +static void floppy_ready(void); static void delay_loop(int cnt) { @@ -316,7 +316,7 @@ :"c" (BLOCK_SIZE/4),"S" ((long)(from)),"D" ((long)(to)) \ :"cx","di","si") #else -static void copy_buffer(from, to) +static void copy_buffer(void *from, void *to) { memcpy(to, from, BLOCK_SIZE); } @@ -829,7 +829,7 @@ redo_fd_request(); } -static void recalibrate_floppy() +static void recalibrate_floppy(void) { recalibrate = 0; current_track = 0; @@ -857,7 +857,7 @@ redo_fd_request(); } -static void unexpected_floppy_interrupt() +static void unexpected_floppy_interrupt(void) { current_track = NO_TRACK; output_byte(FD_SENSEI); @@ -939,10 +939,8 @@ redo_fd_request(); } -/* FIXME: How does one ANSI'fy the following function? */ -static int retry_recal(proc) - void (*proc) (); +static int retry_recal(void (*proc)()) { output_byte(FD_SENSEI); if (result() == 2 && (ST0 & 0x10) != 0x10) @@ -1316,7 +1314,7 @@ */ static int floppy_open(struct inode *inode, struct file *filp) { - int drive, old_dev; + int drive, old_dev, device; drive = inode->i_rdev & 3; old_dev = fd_device[drive]; @@ -1330,6 +1328,22 @@ invalidate_buffers(old_dev); if (filp && filp->f_mode) check_disk_change(inode->i_rdev); + +/* FIXME: Put the correct value for inode->i_size */ + device = MINOR(inode->i_rdev); + if (device > 3) + floppy = (device >> 2) + floppy_type; + else { /* Auto-detection */ + floppy = current_type[device & 3]; + if (!floppy) { + probing = 1; + floppy = base_type[device & 3]; + if (!floppy) + return -ENXIO; + } + } + inode->i_size = ((sector_t)(floppy->size)) << 9; + return 0; } diff -Nur elks.orig/arch/i86/drivers/block/rd.c elks/arch/i86/drivers/block/rd.c --- elks.orig/arch/i86/drivers/block/rd.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/drivers/block/rd.c 2015-04-06 15:20:28.000000000 -0500 @@ -119,7 +119,7 @@ int target = DEVICE_NR(inode->i_rdev); debug1("RD: open ram%d\n", target); - if (rd_initialised == 0) + if((rd_initialised == 0) || (target >= MAX_ENTRIES)) return -ENXIO; #if 0 @@ -127,6 +127,7 @@ return -EBUSY; #endif + inode->i_size = (rd_info[target].size) << 9; return 0; } diff -Nur elks.orig/arch/i86/drivers/block/sibo_ssd.c elks/arch/i86/drivers/block/sibo_ssd.c --- elks.orig/arch/i86/drivers/block/sibo_ssd.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/drivers/block/sibo_ssd.c 2015-04-06 15:20:28.000000000 -0500 @@ -7,7 +7,7 @@ #ifdef CONFIG_BLK_DEV_SSD -#define MAJOR_NR 3 /* FLOPPY_MAJOR as the're fairly similar in practice */ +#define MAJOR_NR 3 /* FLOPPY_MAJOR as the're fairly similar in practice */ #define SSDDISK #include "blk.h" @@ -73,6 +73,7 @@ if (rd_busy[target]) return (-EBUSY); #endif + inode->i_size = NUM_SECTS << 9; return 0; } @@ -118,8 +119,7 @@ static void do_ssd_request(void) { register char *buff; - unsigned long count; - unsigned long start; + unsigned long count, start; int target; while (1) { @@ -192,7 +192,7 @@ for (loop = 0; loop < (count << 9); loop = loop + 0x10) ssd_readblk4(address_high, (address_low + loop), (buff + loop)); #else - for (loop = 0; loop < (count * 512); loop++) + for (loop = 0; loop < (count << 9); loop++) *destination++ = ssd_read4(address_high, (address_low + loop)); #endif diff -Nur elks.orig/arch/i86/drivers/block/ssd.c elks/arch/i86/drivers/block/ssd.c --- elks.orig/arch/i86/drivers/block/ssd.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/drivers/block/ssd.c 2015-04-06 15:20:28.000000000 -0500 @@ -1,7 +1,5 @@ #include <linuxmt/config.h> -#if 0 -#include <linuxmt/rd.h> -#endif +/*#include <linuxmt/rd.h>*/ #include <linuxmt/major.h> #include <linuxmt/kernel.h> #include <linuxmt/debug.h> @@ -9,7 +7,7 @@ #ifdef CONFIG_BLK_DEV_SSD -#define MAJOR_NR 3 +#define MAJOR_NR 3 /* FLOPPY_MAJOR as the're fairly similar in practice */ #define SSDDISK #include "blk.h" @@ -72,6 +70,7 @@ if (rd_busy[target]) return (-EBUSY); #endif + inode->i_size = NUM_SECTS << 9; return 0; } @@ -170,9 +169,10 @@ unsigned long start, register char *buff, unsigned long count) { /* read a number of sectors from ssd */ - char *destination = buff; unsigned int address_high, address_low, loop; + char *destination = buff; + address_high = (unsigned int) (start >> 7); /* Start * 512/65536 */ address_low = (unsigned int) ((start & 0x7F) << 9); @@ -180,10 +180,9 @@ printk("SSD high = %x, low %x\n", address_high, address_low); #endif - for (loop = 0; loop < (count * 512); loop++) { - *destination = ssd_read4(address_high, (address_low + loop)); - destination++; - } + for (loop = 0; loop < (count << 9); loop++) + *destination++ = ssd_read4(address_high, (address_low + loop)); + } #endif diff -Nur elks.orig/arch/i86/kernel/printreg.c elks/arch/i86/kernel/printreg.c --- elks.orig/arch/i86/kernel/printreg.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/arch/i86/kernel/printreg.c 2015-04-07 18:01:15.000000000 -0500 @@ -45,3 +45,26 @@ ret #endasm #endif + +void printsp(void) +{ +#ifndef S_SPLINT_S +#asm + + .data +msg: .ascii "SP=%x:%x\n" + .byte 0 + + .text + push sp + push ss + push #msg + call _printk + pop ax + pop ax + pop ax + ret + +#endasm +#endif +} diff -Nur elks.orig/fs/block_dev.c elks/fs/block_dev.c --- elks.orig/fs/block_dev.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/fs/block_dev.c 2015-04-09 17:31:02.000000000 -0500 @@ -23,23 +23,14 @@ char *buf, size_t count, int wr) { register struct buffer_head *bh; - kdev_t dev; - unsigned int offset; - size_t chars; + size_t chars, offset; int written = 0; - dev = inode->i_rdev; - while (count > 0) { - /* * Offset to block/offset */ - offset = ((unsigned int)filp->f_pos) & (BLOCK_SIZE - 1); - - /* - * Bytes to do - */ + offset = ((size_t)filp->f_pos) & (BLOCK_SIZE - 1); chars = BLOCK_SIZE - offset; if (chars > count) chars = count; @@ -47,10 +38,13 @@ * Read the block in - use getblk on a write * of a whole block to avoid a read of the data. */ - bh = getblk(dev, (block_t)(filp->f_pos >> BLOCK_SIZE_BITS)); + bh = getblk(inode->i_rdev, (block_t)(filp->f_pos >> BLOCK_SIZE_BITS)); if((wr == BLOCK_READ) || (chars != BLOCK_SIZE)) { - if (!readbuf(bh)) - return written ? written : -EIO; + if (!readbuf(bh)) { + if(!written) + written = -EIO; + break; + } } map_buffer(bh); @@ -67,7 +61,9 @@ wait_on_buffer(bh); if (!bh->b_uptodate) { /* Write error. */ unmap_brelse(bh); - return -EIO; + if(!written) + written = -EIO; + break; } } else { /* @@ -86,7 +82,7 @@ written += chars; count -= chars; } - return ((wr == BLOCK_WRITE) && !written) ? -ENOSPC : written; + return written; } int block_read(struct inode *inode, register struct file *filp, diff -Nur elks.orig/fs/minix/file.c elks/fs/minix/file.c --- elks.orig/fs/minix/file.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/fs/minix/file.c 2015-04-09 17:30:25.000000000 -0500 @@ -19,11 +19,6 @@ #include <arch/segment.h> #include <arch/system.h> -#define NBUF 2 - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - #include <linuxmt/fs.h> #include <linuxmt/minix_fs.h> @@ -33,8 +28,6 @@ static int minix_file_write(register struct inode *inode, struct file *filp, char *buf, size_t count); -/*@-type@*/ - /* * We have mostly NULL's here: the current defaults are ok for * the minix filesystem. @@ -79,17 +72,20 @@ /* * FIXME: Readahead */ - +#ifdef DEBUG static char inode_equal_NULL[] = "inode = NULL\n"; static char mode_equal_val[] = "mode = %07o\n"; +#endif static int minix_file_read(struct inode *inode, register struct file *filp, char *buf, size_t count) { - loff_t offset; - size_t chars; + register struct buffer_head *bh; + loff_t pos; + size_t chars, offset; int read = 0; +#ifdef DEBUG { register char *s; if (!inode) { @@ -103,47 +99,50 @@ return -EINVAL; } } +#endif /* * Amount we can do I/O over */ - offset = ((loff_t)inode->i_size) - filp->f_pos; - if (offset <= 0) { + pos = ((loff_t)inode->i_size) - filp->f_pos; + if (pos <= 0) { debug("MFSREAD: EOF reached.\n"); - return 0; /* EOF */ + goto mfread; /* EOF */ } - if (offset < (loff_t)count) - count = (size_t)offset; + if ((loff_t)count > pos) + count = (size_t)pos; while (count > 0) { - register struct buffer_head *bh; /* - * Block, offset pair from the byte offset + * Offset to block/offset */ - 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); + offset = ((size_t)filp->f_pos) & (BLOCK_SIZE - 1); + chars = BLOCK_SIZE - offset; + if (chars > count) + chars = count; + /* + * Read the block in - use getblk on a write + * of a whole block to avoid a read of the data. + */ + bh = minix_getblk(inode, (block_t)(filp->f_pos >> BLOCK_SIZE_BITS), 0); if (bh) { if (!readbuf(bh)) { debug("MINREAD: readbuf failed\n"); + if (!read) + read = -EIO; break; } map_buffer(bh); - memcpy_tofs(buf, bh->b_data + offset, chars); + memcpy_tofs(buf, bh->b_data + (size_t)offset, chars); unmap_brelse(bh); } else { - fmemset(buf, current->t_regs.ds, 0, chars); + fmemset(buf, current->t_regs.ds, 0, chars); } buf += chars; - filp->f_pos += chars; - read += chars; - count -= chars; + filp->f_pos += chars; + read += chars; + count -= chars; } - if (!read) - return -EIO; #ifdef BLOAT_FS filp->f_reada = 1; @@ -152,16 +151,18 @@ if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME; #endif + mfread: return read; } static int minix_file_write(register struct inode *inode, struct file *filp, char *buf, size_t count) { - loff_t pos; + register struct buffer_head *bh; size_t chars, offset; - size_t written = 0; + int written = 0; +#ifdef DEBUG { register char *s; if (!inode) { @@ -176,20 +177,24 @@ return -EINVAL; } } +#endif - pos = (filp->f_flags & O_APPEND) - ? (loff_t) inode->i_size - : filp->f_pos; + if(filp->f_flags & O_APPEND) + filp->f_pos = (loff_t)inode->i_size; while (count > 0) { - register struct buffer_head *bh; - - offset = (size_t)pos & (BLOCK_SIZE - 1); + /* + * Offset to block/offset + */ + offset = ((size_t)filp->f_pos) & (BLOCK_SIZE - 1); chars = BLOCK_SIZE - offset; if (chars > count) chars = count; - - bh = minix_getblk(inode, (block_t) (pos >> BLOCK_SIZE_BITS), 1); + /* + * Read the block in - use getblk on a write + * of a whole block to avoid a read of the data. + */ + bh = minix_getblk(inode, (block_t) (filp->f_pos >> BLOCK_SIZE_BITS), 1); if (!bh) { if (!written) written = -ENOSPC; @@ -208,14 +213,13 @@ mark_buffer_dirty(bh, 1); unmap_brelse(bh); buf += chars; - pos += chars; + filp->f_pos += chars; written += chars; - count -= chars; + count -= chars; } - if (pos > (loff_t) inode->i_size) - inode->i_size = (__u32) pos; - filp->f_pos = pos; + if ((loff_t)inode->i_size < filp->f_pos) + inode->i_size = (__u32) filp->f_pos; inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_dirt = 1; - return (int) written; + return written; } diff -Nur elks.orig/fs/namei.c elks/fs/namei.c --- elks.orig/fs/namei.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/fs/namei.c 2015-04-06 15:20:28.000000000 -0500 @@ -214,6 +214,14 @@ return error; } +/* + * _namei() + * + * Get the inode of 'pathname'. + * + * follow_links != 0 means can follow links + * + */ int _namei(char *pathname, struct inode *base, int follow_links, register struct inode **res_inode) { @@ -253,6 +261,10 @@ * is used by most simple commands to get the inode of a specified name. * Open, link etc use their own routines, but this is enough for things * like 'chmod' etc. + * + * dir can be: IS_DIR, pathname must be a directory + * NOT_DIR, pathname must not be a directory + * 0, pathname may be any */ int namei(char *pathname, register struct inode **res_inode, int dir, int perm) { @@ -612,5 +624,5 @@ return !(err = sys_link(oldname, newname)) ? sys_unlink(oldname) : err; - + } diff -Nur elks.orig/fs/pipe.c elks/fs/pipe.c --- elks.orig/fs/pipe.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/fs/pipe.c 2015-04-06 15:20:28.000000000 -0500 @@ -93,21 +93,17 @@ register char *chars; debug("PIPE: read called.\n"); - if (filp->f_flags & O_NONBLOCK) { - if ((inode->u.pipe_i.lock)) + while(!(inode->u.pipe_i.len) || (inode->u.pipe_i.lock)) { + if(!(inode->u.pipe_i.lock) && !(inode->u.pipe_i.writers)) { + return 0; + } + if(filp->f_flags & O_NONBLOCK) { return -EAGAIN; - if (((inode->u.pipe_i.len) == 0)) - return ((inode->u.pipe_i.writers)) ? -EAGAIN : 0; - } else - while (((inode->u.pipe_i.len) == 0) || (inode->u.pipe_i.lock)) { - if (((inode->u.pipe_i.len) == 0)) { - if (!(inode->u.pipe_i.writers)) - return 0; - } - if (current->signal) - return -ERESTARTSYS; - interruptible_sleep_on(&(inode->u.pipe_i.wait)); } + if(current->signal) + return -ERESTARTSYS; + interruptible_sleep_on(&(inode->u.pipe_i.wait)); + } (inode->u.pipe_i.lock)++; while (count > 0 && inode->u.pipe_i.len) { chars = (char *)(PIPE_BUF - (inode->u.pipe_i.start)); diff -Nur elks.orig/kernel/memdumpk.c elks/kernel/memdumpk.c --- elks.orig/kernel/memdumpk.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/kernel/memdumpk.c 2015-04-07 18:01:18.000000000 -0500 @@ -36,26 +36,3 @@ len -= 8; } } - -void printsp(void) -{ -#ifndef S_SPLINT_S -#asm - - .data -msg: .ascii "SP=%x:%x\n" - .byte 0 - - .text - push sp - push ss - push #msg - call _printk - pop ax - pop ax - pop ax - ret - -#endasm -#endif -} diff -Nur elks.orig/lib/chqueue.c elks/lib/chqueue.c --- elks.orig/lib/chqueue.c 2015-04-05 20:18:27.000000000 -0500 +++ elks/lib/chqueue.c 2015-04-06 15:20:28.000000000 -0500 @@ -1,5 +1,5 @@ /* lib/chqueue.c - * (C) 1997 Chad Page + * (C) 1997 Chad Page * * (Based on the original character queue code by Alan Cox(?)) * @@ -64,6 +64,7 @@ return 0; } +#if 0 /* Deletes last character in list */ int chq_delch(register struct ch_queue *q) { @@ -73,6 +74,7 @@ } return 0; } +#endif /* Gets tail character, waiting for one if wait != 0 */ int chq_getch(register struct ch_queue *q, register unsigned char *c, int wait)