diff -aurN milo-2.2-18-patched/boot.c milo-2.2-18/boot.c --- milo-2.2-18-patched/boot.c 2024-02-17 11:44:12.000000000 +0900 +++ milo-2.2-18/boot.c 2025-02-24 16:49:45.000000000 +0900 @@ -327,7 +327,7 @@ return -1; } - if (elf->e_phoff + sizeof(*phdr) > IOBUF_SIZE) { + if (elf->e_phoff + sizeof(*phdr) > milo_open_fs->blocksize) { printk("ELF program header not in first block (%ld)\n", (long) elf->e_phoff); return -1; @@ -500,7 +500,7 @@ /* no, it wasn't a compressed kernel, carry on as normal Allocate an iobuf for the transfers and read the first block of the file into it (the section headers). Make it 512 bytes aligned. */ - iobuf = kmalloc(IOBUF_SIZE + 512, 0) + 512; + iobuf = kmalloc(milo_open_fs->blocksize + 512, 0) + 512; iobuf = (char *) ((unsigned long) iobuf & (~(512 - 1))); #ifdef DEBUG_BOOT printk("...allocated iobuf at 0x%p\n", iobuf); @@ -509,8 +509,8 @@ blkno = 0; /* logical block number */ while (__bread(fd, blkno++, iobuf) == 0) { printk("#"); - memcpy((char *) ptr, iobuf, IOBUF_SIZE); - ptr += IOBUF_SIZE; + memcpy((char *) ptr, iobuf, milo_open_fs->blocksize); + ptr += milo_open_fs->blocksize; if ((ptr - where) > MAX_KERNEL_SIZE) break; } @@ -1112,7 +1112,7 @@ return; initdisk_size = __fdsize(fd); - where = (char *) (LOADER_AT - initdisk_size - IOBUF_SIZE); + where = (char *) (LOADER_AT - initdisk_size - milo_open_fs->blocksize); if (where < (char *) (kernel_at + kernel_memsize)) { printk("initdisk too large, would overwrite kernel.\n"); printk("aborting.\n"); @@ -1134,7 +1134,7 @@ while (1) { __bread(fd, blkno++, ptr); // printk("#"); - ptr += IOBUF_SIZE; + ptr += milo_open_fs->blocksize; if ((ptr - where) > initdisk_size) break; } diff -aurN milo-2.2-18-patched/fs/dos.c milo-2.2-18/fs/dos.c --- milo-2.2-18-patched/fs/dos.c 1999-11-23 10:36:25.000000000 +0900 +++ milo-2.2-18/fs/dos.c 2025-02-24 16:49:38.000000000 +0900 @@ -59,7 +59,7 @@ struct bootfs msdosfs = { "msdos", 0, - 0, + IOBUF_SIZE, msdos_mount, msdos_open, diff -aurN milo-2.2-18-patched/fs/ext2.c milo-2.2-18/fs/ext2.c --- milo-2.2-18-patched/fs/ext2.c 1999-09-07 02:43:14.000000000 +0900 +++ milo-2.2-18/fs/ext2.c 2025-02-24 16:49:20.000000000 +0900 @@ -37,25 +37,58 @@ #include "milo.h" #include "fs.h" -#include "ext2.h" + +#ifdef __KERNEL__ +# undef __KERNEL__ +# include +# define __KERNEL__ +#else +# include +#endif + +/* endian checking stuff */ +#ifndef EXT2_ENDIAN_H_ +#define EXT2_ENDIAN_H_ + +#ifdef __CHECKER__ +# ifndef __bitwise +# define __bitwise __attribute__((bitwise)) +# endif +#define __force __attribute__((force)) +#else +# ifndef __bitwise +# define __bitwise +# endif +#define __force +#endif + +typedef __u16 __bitwise __le16; +typedef __u32 __bitwise __le32; +typedef __u64 __bitwise __le64; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __be32; +typedef __u64 __bitwise __be64; + +#endif /* EXT2_ENDIAN_H_ */ + +#include "ext4.h" #define MAX_OPEN_FILES 4 int fd = -1; -struct ext2_super_block sb; -struct ext2_group_desc *gds = NULL; -int ngroups = 0; -int blocksize; /* Block size of this fs */ -int directlim; /* Maximum direct blkno */ -int ind1lim; /* Maximum single-indir blkno */ -int ind2lim; /* Maximum double-indir blkno */ -int ptrs_per_blk; /* ptrs/indirect block */ -char filename[256]; -char blkbuf[EXT2_MAX_BLOCK_SIZE]; -long cached_iblkno = -1; -char iblkbuf[EXT2_MAX_BLOCK_SIZE]; -long cached_diblkno = -1; -char diblkbuf[EXT2_MAX_BLOCK_SIZE]; +static struct ext2_super_block sb; +static struct ext2_group_desc *gds = NULL; +static struct ext2_inode *root_inode = NULL; +static int ngroups = 0; +static int directlim; /* Maximum direct blkno */ +static int ind1lim; /* Maximum single-indir blkno */ +static int ind2lim; /* Maximum double-indir blkno */ +static int ptrs_per_blk; /* ptrs/indirect block */ +static char *blkbuf; +static long cached_iblkno = -1; +static char *iblkbuf; +static long cached_diblkno = -1; +static char *diblkbuf; static struct inode_table_entry { struct ext2_inode inode; @@ -73,7 +106,6 @@ /* forward declarations */ static int ext2_bread(int fd, long blkno, char *buffer); -static void ext2_breadi(struct ext2_inode *ip, long blkno, char *buffer); static int ext2_mount(long device, int quiet); static int ext2_open(char *filename); static void ext2_ls(char *dirname, char *devname); @@ -108,6 +140,8 @@ inode_table[i].free = 1; inode_table[i].inumber = 0; } + /* clear the root inode pointer (very important!) */ + root_inode = NULL; /* set the device's block size */ set_blocksize(device, EXT2_MIN_BLOCK_SIZE); @@ -143,8 +177,9 @@ /* read in the EXT2 block groups */ ngroups = (sb.s_blocks_count - sb.s_first_data_block + - sb.s_blocks_per_group - 1) - / sb.s_blocks_per_group; + EXT2_BLOCKS_PER_GROUP(&sb) - 1) + / EXT2_BLOCKS_PER_GROUP(&sb); + #ifdef DEBUG_EXT2 printk("...ngroups is %d\n", ngroups); #endif @@ -162,17 +197,22 @@ return (-1); } + ext2fs.blocksize = EXT2_BLOCK_SIZE(&sb); + blkbuf = vmalloc(ext2fs.blocksize); + iblkbuf = vmalloc(ext2fs.blocksize); + diblkbuf = vmalloc(ext2fs.blocksize); + /* Read in the group descriptors (immediately follows superblock) */ #ifdef DEBUG_EXT2 printk ("...reading in the group descriptors (%d) at offset 0x%lx\n", - ngroups, sb_offset + sizeof(sb)); + ngroups, ext2fs.blocksize * (EXT2_MIN_BLOCK_SIZE/ext2fs.blocksize + 1)); printk(" size is %lu\n", ngroups * sizeof(struct ext2_group_desc)); #endif if (device_read (fd, (char *) gds, ngroups * sizeof(struct ext2_group_desc), - sb_offset + sizeof(sb)) != + ext2fs.blocksize * (EXT2_MIN_BLOCK_SIZE/ext2fs.blocksize + 1)) != ngroups * sizeof(struct ext2_group_desc)) { printk("ext2_mount: could not read groups\n"); device_close(fd); @@ -191,9 +231,9 @@ /* Calculate direct/indirect block limits for this file system (blocksize * dependent) */ - blocksize = EXT2_BLOCK_SIZE(&sb); + ext2fs.blocksize = EXT2_BLOCK_SIZE(&sb); directlim = EXT2_NDIR_BLOCKS - 1; - ptrs_per_blk = blocksize / sizeof(unsigned int); + ptrs_per_blk = ext2fs.blocksize / sizeof(unsigned int); ind1lim = ptrs_per_blk + directlim; ind2lim = (ptrs_per_blk * ptrs_per_blk) + directlim; @@ -223,6 +263,10 @@ ip = NULL; itp = NULL; for (i = 0; i < MAX_OPEN_FILES; i++) { +#ifdef DEBUG_EXT2 + printk("ext2_iget: looping, entry %d inode %d free %d\n", + i, inode_table[i].inumber, inode_table[i].free); +#endif if (inode_table[i].free) { itp = &(inode_table[i]); ip = &(itp->inode); @@ -235,15 +279,21 @@ } group = (ino - 1) / sb.s_inodes_per_group; - offset = ((unsigned long) gds[group].bg_inode_table * blocksize) - + - (((ino - 1) % sb.s_inodes_per_group) * - sizeof(struct ext2_inode)); +#ifdef DEBUG_EXT2 + printk("group is %d\n", group); +#endif + offset = ((unsigned long) gds[group].bg_inode_table * ext2fs.blocksize) + + (((ino - 1) % EXT2_INODES_PER_GROUP(&sb)) + * EXT2_INODE_SIZE(&sb)); #ifdef DEBUG_EXT2 - printk("...group = %d, gds[group].bg_inode_table = %d\n", group, - gds[group].bg_inode_table); - printk("...reading inode at offset 0x%lx\n", offset); + printk("ext2_iget: reading %ld bytes at offset %ld " + "((%d * %d) + ((%d) %% %d) * %d) " + "(inode %d -> table %d)\n", + sizeof(struct ext2_inode), offset, + gds[group].bg_inode_table, ext2fs.blocksize, + ino - 1, EXT2_INODES_PER_GROUP(&sb), EXT2_INODE_SIZE(&sb), + ino, (int) (itp - inode_table)); #endif if (device_read(fd, (char *) ip, sizeof(struct ext2_inode), offset) != sizeof(struct ext2_inode)) { @@ -285,9 +335,8 @@ * The "allocate" argument is set if we want to *allocate* a block * and we don't already have one allocated. */ -static int ext2_blkno(struct ext2_inode *ip, int blkoff, int allocate) +static int ext2_blkno(struct ext2_inode *ip, int blkoff) { - unsigned int *lp; unsigned int *ilp; unsigned int *dlp; int blkno; @@ -298,15 +347,6 @@ ilp = (unsigned int *) iblkbuf; dlp = (unsigned int *) diblkbuf; - if (allocate) { - printk - ("ext2_blkno: Cannot allocate on a readonly file system!\n"); - return (0); - } - - lp = (unsigned int *) blkbuf; - - /* If it's a direct block, it's easy! */ if (blkoff <= directlim) { return (ip->i_block[blkoff]); } @@ -323,11 +363,11 @@ if (cached_iblkno != iblkno) { #ifdef DEBUG_EXT2 printk("Reading indirect block at 0x%lx\n", - (iblkno * blocksize)); + (iblkno * ext2fs.blocksize)); #endif if (device_read - (fd, iblkbuf, blocksize, - (iblkno * blocksize)) != blocksize) { + (fd, iblkbuf, ext2fs.blocksize, + (iblkno * ext2fs.blocksize)) != ext2fs.blocksize) { printk("ext2_blkno: error on iblk read\n"); return (0); } @@ -352,11 +392,11 @@ if (cached_diblkno != diblkno) { #ifdef DEBUG_EXT2 printk("Reading double indirect block at 0x%lx\n", - (diblkno * blocksize)); + (diblkno * ext2fs.blocksize)); #endif if (device_read - (fd, diblkbuf, blocksize, - (diblkno * blocksize)) != blocksize) { + (fd, diblkbuf, ext2fs.blocksize, + (diblkno * ext2fs.blocksize)) != ext2fs.blocksize) { printk ("ext2_blkno: err reading dindr blk\n"); return (0); @@ -376,8 +416,8 @@ if (cached_iblkno != iblkno) { if (device_read - (fd, iblkbuf, blocksize, - (iblkno * blocksize)) != blocksize) { + (fd, iblkbuf, ext2fs.blocksize, + (iblkno * ext2fs.blocksize)) != ext2fs.blocksize) { printk("ext2_blkno: err on iblk read\n"); return (0); } @@ -406,59 +446,161 @@ return ip->i_size; } -/* Read block number "blkno" from the specified file */ -static int ext2_bread(int fd, long blkno, char *buffer) +static int ext4_breadi(struct ext2_inode *ip, long blkno, long nblks, char *buffer) { - struct ext2_inode *ip; + long tot_bytes = 0; - ip = &(inode_table[fd].inode); - ext2_breadi(ip, blkno, buffer); - return 0; + struct ext4_extent_header *hdr; + hdr = (struct ext4_extent_header *)&ip->i_block[0]; + + if (hdr->eh_magic != EXT4_EXT_MAGIC) { + printk("ext4_breadi: Extent header magic wrong.\n"); + return -1; + } + + if (hdr->eh_entries != 1) { + printk("ext4_breadi: Extent entries must be 1.\n"); + return -1; + } + + struct ext4_extent *ext; + ext = (struct ext4_extent *)&ip->i_block[3]; + + if (ext->ee_block != 0) { + printk("ext4_breadi: First logical block must be 0.\n"); + return -1; + } + + if (nblks > ext->ee_len) { + printk("ext4_breadi: Request nblks greater than extent len.\n"); + return -1; + } + + long ee_start = ((long)ext->ee_start_hi << 32) + ext->ee_start_lo; + + if (blkno + nblks > ext->ee_len) { + nblks = ext->ee_len - blkno; + } + + long offset = (ee_start + blkno) * ext2fs.blocksize; + long nbytes = nblks * ext2fs.blocksize; + + tot_bytes = device_read(fd, buffer, nbytes, offset); + if (tot_bytes != nbytes) { + printk("ext4_breadi: device_read failed.\n"); + return -1; + } + + return tot_bytes; } -static void ext2_breadi(struct ext2_inode *ip, long blkno, char *buffer) +static int ext2_breadi(struct ext2_inode *ip, long blkno, long nblks, char *buffer) { - long dev_blkno; + long dev_blkno, ncontig, offset, nbytes, tot_bytes; + if (ip->i_flags & EXT4_EXTENTS_FL) { + printk("ext2_breadi: This function does not handle ext4 extents\n"); + return -1; + } -#ifdef DEBUG_EXT2 - printk("ext2_breadi(): called for block %ld\n", blkno); -#endif + tot_bytes = 0; + if ((blkno+nblks)*ext2fs.blocksize > ip->i_size) + nblks = (ip->i_size + ext2fs.blocksize) / ext2fs.blocksize - blkno; - dev_blkno = ext2_blkno(ip, blkno, 0); -#ifdef DEBUG_EXT2 - printk("ext2_breadi(): dev_blkno = %ld\n", dev_blkno); -#endif - if (dev_blkno == 0) { + while (nblks) { + /* + * Contiguous reads are a lot faster, so we try to group + * as many blocks as possible: + */ + ncontig = 0; nbytes = 0; + dev_blkno = ext2_blkno(ip, blkno); + do { + ++blkno; ++ncontig; --nblks; + nbytes += ext2fs.blocksize; + } while (nblks && + ext2_blkno(ip, blkno) == dev_blkno + ncontig); + + if (dev_blkno == 0) { + /* This is a "hole" */ + memset(buffer, 0, nbytes); + } else { + /* Read it for real */ + offset = (long) dev_blkno* (long) ext2fs.blocksize; +#ifdef DEBUG_EXT2 + printk("ext2_bread: reading %ld bytes at offset %ld\n", + nbytes, offset); +#endif + if (device_read(fd, buffer, nbytes, offset) + != nbytes) + { + printk("ext2_bread: read error\n"); + return -1; + } + } + buffer += nbytes; + tot_bytes += nbytes; + } + return tot_bytes; +} - /* This is a "hole" */ - memset(buffer, 0, blocksize); +static int extn_breadi(struct ext2_inode *ip, long blkno, long nblks, char *buffer) { + if (ip->i_flags & EXT4_EXTENTS_FL) { + return ext4_breadi(ip, blkno, nblks, buffer); } else { + return ext2_breadi(ip, blkno, nblks, buffer); + } +} + +static struct ext2_dir_entry_2 *ext2_readdiri(struct ext2_inode *dir_inode, + int rewind) +{ + struct ext2_dir_entry_2 *dp; + static int diroffset = 0, blockoffset = 0; + + /* Reading a different directory, invalidate previous state */ + if (rewind) { + diroffset = 0; + blockoffset = 0; + /* read first block */ + if (extn_breadi(dir_inode, 0, 1, blkbuf) < 0) + return NULL; + } - /* Read it for real */ #ifdef DEBUG_EXT2 - printk - ("ext2_breadi(): reading block %ld at offset 0x%lx\n", - blkno, (dev_blkno * blocksize)); + printk("ext2_readdiri: blkoffset %d diroffset %d len %d\n", + blockoffset, diroffset, dir_inode->i_size); #endif - if (device_read - (fd, buffer, blocksize, - (dev_blkno * blocksize)) != blocksize) { - printk("ext2_bread: read error"); - } + if (blockoffset >= ext2fs.blocksize) { + diroffset += ext2fs.blocksize; + if (diroffset >= dir_inode->i_size) + return NULL; +#ifdef DEBUG_EXT2 + printk("ext2_readdiri: reading block at %d\n", + diroffset); +#endif + /* assume that this will read the whole block */ + if (extn_breadi(dir_inode, + diroffset / ext2fs.blocksize, + 1, blkbuf) < 0) + return NULL; + blockoffset = 0; } -} + dp = (struct ext2_dir_entry_2 *) (blkbuf + blockoffset); + blockoffset += dp->rec_len; +#ifdef DEBUG_EXT2 + printk("ext2_readdiri: returning %p = %.*s\n", dp, dp->name_len, dp->name); +#endif + return dp; +} static struct ext2_inode *ext2_namei(char *name) { char namebuf[256]; char *component; - struct ext2_inode *dir_inode = NULL, *file_inode; - struct ext2_dir_entry *dp; + struct ext2_inode *dir_inode; + struct ext2_dir_entry_2 *dp; int next_ino; - int link_count = 0; - #ifdef DEBUG_EXT2 printk("ext2_namei(): called for %s\n", name); @@ -467,175 +609,89 @@ /* Squirrel away a copy of "namebuf" that we can molest */ strcpy(namebuf, name); - /* Start at the root... */ - /* We'll get back here to these nifty labels if we encounter a symlink */ - abs: - file_inode = ext2_iget(EXT2_ROOT_INO); - rel: - if (!file_inode) - return NULL; + /* start at the root: */ + if (!root_inode) + root_inode = ext2_iget(EXT2_ROOT_INO); + dir_inode = root_inode; + if (!dir_inode) + return NULL; component = strtok(namebuf, "/"); while (component) { - int diroffset; - int blockoffset; int component_length; - - /* Search for the specified component in the current directory inode. + int rewind = 0; + /* + * Search for the specified component in the current + * directory inode. */ + next_ino = -1; + component_length = strlen(component); -#ifdef MILO_SYMLINK_DIRS - if (S_ISLNK(file_inode->i_mode)) { - if (++link_count > 10) - printk("%s: possibly circular symlink\n", - name); - else { - char *t; - - /* Set blkbuf to symbolic link content */ - if (file_inode->i_blocks) - ext2_breadi(file_inode, 0, blkbuf); - else - strcpy(blkbuf, - (char *) file_inode-> - i_block); - - /* Add rest of the path to it */ - t = blkbuf + strlen(blkbuf); - while (component != NULL) { - t = - stpcpy(stpcpy(t, "/"), - component); - component = strtok(NULL, "/"); - } - - /* Put it back to namebuf */ - strcpy(namebuf, blkbuf); + /* rewind the first time through */ + while ((dp = ext2_readdiri(dir_inode, !rewind++))) { + if ((dp->name_len == component_length) && + (strncmp(component, dp->name, + component_length) == 0)) + { + /* Found it! */ #ifdef DEBUG_EXT2 - printk - ("substituted symlink + rest of path: %s\n", - namebuf); + printk("ext2_namei: found entry %s\n", + component); #endif - - if (*namebuf == '/') { - /* Absolute symlink */ - if (dir_inode) - ext2_iput(dir_inode); - if (file_inode) - ext2_iput(file_inode); - goto abs; - } else { - /* Relative symlink */ - if (file_inode) - ext2_iput(file_inode); - file_inode = dir_inode; - goto rel; - } + next_ino = dp->inode; + break; } - } -#endif /* MILO_SYMLINK_DIRS */ - - if (dir_inode) - ext2_iput(dir_inode); - dir_inode = file_inode; - file_inode = NULL; - next_ino = -1; - - if (!S_ISDIR(dir_inode->i_mode)) { - printk("%s: path component is not a directory\n", - name); - break; - } - - component_length = strlen(component); - diroffset = 0; #ifdef DEBUG_EXT2 - printk("...dir_inode->i_size = %d\n", dir_inode->i_size); + printk("ext2_namei: looping\n"); #endif - while (diroffset < dir_inode->i_size) { - blockoffset = 0; + } + #ifdef DEBUG_EXT2 - printk("ext2_namei(): calling ext2_breadi\n"); + printk("ext2_namei: next_ino = %d\n", next_ino); #endif - ext2_breadi(dir_inode, diroffset / blocksize, - blkbuf); - while (blockoffset < blocksize) { - dp = - (struct ext2_dir_entry *) (blkbuf + - blockoffset); -#if DEBUG_EXT2 - { - int i; - - printk("...name is "); - for (i = 0; i < dp->name_len; i++) - printk("%c", dp->name[i]); - printk("\n"); - } -#endif - if ((dp->name_len == component_length) && - (strncmp(component, dp->name, - component_length) == 0)) { - - /* Found it! */ - next_ino = dp->inode; - break; - } - /* Go to next entry in this block */ - blockoffset += dp->rec_len; - } - if (next_ino >= 0) { - break; - } - - /* If we got here, then we didn't find the component. Try the next - * block in this directory... */ - diroffset += blocksize; - } /* end-while */ + /* + * At this point, we're done with this directory whether + * we've succeeded or failed... + */ + if (dir_inode != root_inode) + ext2_iput(dir_inode); - /* If next_ino is negative, then we've failed (gone all the way through - * without finding anything) */ + /* + * If next_ino is negative, then we've failed (gone + * all the way through without finding anything) + */ if (next_ino < 0) { -#ifdef DEBUG_EXT2 - printk("...we failed\n"); -#endif - break; + return NULL; } - /* Otherwise, we can get this inode and find the next component - * string... */ - file_inode = ext2_iget(next_ino); + /* + * Otherwise, we can get this inode and find the next + * component string... + */ + dir_inode = ext2_iget(next_ino); + if (!dir_inode) + return NULL; component = strtok(NULL, "/"); } - /* If we get here, then we got through all the components. Whatever we got - * must match up with the last one. */ - if (file_inode && S_ISLNK(file_inode->i_mode)) { /* Is it a symlink? */ - if (++link_count > 5) - printk("%s: possibly circular symlink\n", name); - else { - if (file_inode->i_blocks) { - ext2_breadi(dir_inode, 0, blkbuf); - strncpy(namebuf, blkbuf, - sizeof namebuf - 1); - } else - strncpy(namebuf, - (char *) file_inode->i_block, - sizeof namebuf - 1); - ext2_iput(file_inode); - if (*namebuf == '/') { /* absolute */ - ext2_iput(dir_inode); - goto abs; - } /* otherwise it's relative */ - file_inode = dir_inode; - goto rel; - } - } - if (dir_inode) - ext2_iput(dir_inode); - return (file_inode); + /* + * If we get here, then we got through all the components. + * Whatever we got must match up with the last one. + */ + return dir_inode; +} + +static int ext2_bread(int fd, long blkno, char *buffer) +{ + struct ext2_inode * ip; + ip = &inode_table[fd].inode; + + if (extn_breadi(ip, blkno, 1, buffer) > 0) + return 0; + else + return -1; } static void ext2_ls(char *dirname, char *devname) @@ -644,7 +700,7 @@ char format_string[16]; struct ext2_inode *dir_inode; struct ext2_inode *file_inode; - struct ext2_dir_entry *dp; + struct ext2_dir_entry_2 *dp; int diroffset; int blockoffset; int column_size = 0; @@ -679,10 +735,10 @@ diroffset = 0; while (diroffset < dir_inode->i_size) { blockoffset = 0; - ext2_breadi(dir_inode, diroffset / blocksize, blkbuf); - while (blockoffset < blocksize) { + extn_breadi(dir_inode, diroffset / ext2fs.blocksize, 1, blkbuf); + while (blockoffset < ext2fs.blocksize) { dp = - (struct ext2_dir_entry *) (blkbuf + + (struct ext2_dir_entry_2 *) (blkbuf + blockoffset); if (dp->name_len > column_size) { column_size = dp->name_len; @@ -691,7 +747,7 @@ } /* Go to the next block in this directory... */ - diroffset += blocksize; + diroffset += ext2fs.blocksize; } /* end-while */ /* Compute the format string for this listing... */ @@ -715,10 +771,10 @@ #endif while (diroffset < dir_inode->i_size) { blockoffset = 0; - ext2_breadi(dir_inode, diroffset / blocksize, blkbuf); - while (blockoffset < blocksize) { + extn_breadi(dir_inode, diroffset / ext2fs.blocksize, 1, blkbuf); + while (blockoffset < ext2fs.blocksize) { dp = - (struct ext2_dir_entry *) (blkbuf + + (struct ext2_dir_entry_2 *) (blkbuf + blockoffset); if (dp->name_len > 0) { strncpy(filename, dp->name, dp->name_len); @@ -755,7 +811,7 @@ } /* Go to the next block in this directory... */ - diroffset += blocksize; + diroffset += ext2fs.blocksize; } /* end-while */ if ((col % columns) != 0) { @@ -767,6 +823,46 @@ } +static struct ext2_inode * ext2_follow_link(struct ext2_inode * from, + const char * base) +{ + char *linkto; + + if (from->i_blocks) { + linkto = blkbuf; + if (extn_breadi(from, 0, 1, blkbuf) == -1) + return NULL; +#ifdef DEBUG_EXT2 + printk("long link!\n"); +#endif + } else { + linkto = (char*)from->i_block; + } +#ifdef DEBUG_EXT2 + printk("symlink to %s\n", linkto); +#endif + + /* Resolve relative links */ + if (linkto[0] != '/') { + char *end = strrchr(base, '/'); + if (end) { + char fullname[(end - base + 1) + strlen(linkto) + 1]; + strncpy(fullname, base, end - base + 1); + fullname[end - base + 1] = '\0'; + strcat(fullname, linkto); +#ifdef DEBUG_EXT2 + printk("resolved to %s\n", fullname); +#endif + return ext2_namei(fullname); + } else { + /* Assume it's in the root */ + return ext2_namei(linkto); + } + } else { + return ext2_namei(linkto); + } +} + static int ext2_open(char *filename) { @@ -785,6 +881,10 @@ if (ip) { struct inode_table_entry *itp; + while (S_ISLNK(ip->i_mode)) { + ip = ext2_follow_link(ip, filename); + if (!ip) return -1; + } itp = (struct inode_table_entry *) ip; return (itp - inode_table); } else { @@ -795,10 +895,12 @@ static void ext2_close(int fd) { - ext2_iput(&(inode_table[fd].inode)); + /* blah, hack, don't close the root inode ever */ + if (&inode_table[fd].inode != root_inode) { + ext2_iput(&inode_table[fd].inode); #ifdef DEBUG_EXT2 - printk("Closing device, fd=%d\n", fd); + printk("Closing device, fd=%d\n", fd); #endif - device_close(fd); + device_close(fd); + } } - diff -aurN milo-2.2-18-patched/fs/isofs.c milo-2.2-18/fs/isofs.c --- milo-2.2-18-patched/fs/isofs.c 2001-07-18 22:38:38.000000000 +0900 +++ milo-2.2-18/fs/isofs.c 2025-02-24 16:49:32.000000000 +0900 @@ -49,7 +49,7 @@ struct bootfs iso9660fs = { "iso9660", 0, - 0, + 1024, iso9660_mount, iso9660_open, iso9660_fdsize, diff -aurN milo-2.2-18-patched/fs/reiserfs.c milo-2.2-18/fs/reiserfs.c --- milo-2.2-18-patched/fs/reiserfs.c 2001-07-18 22:38:38.000000000 +0900 +++ milo-2.2-18/fs/reiserfs.c 2025-02-24 16:58:15.000000000 +0900 @@ -815,7 +815,7 @@ } blocksize = REISERFS_BLOCK_SIZE; sb.s_blocksize = REISERFS_BLOCK_SIZE; - reiserfs.blocksize = REISERFS_BLOCK_SIZE; + reiserfs.blocksize = IOBUF_SIZE; p_hash_function = hash_function (sb.s_hash_function_code); s_dev=device; j_tab_count=0; diff -aurN milo-2.2-18-patched/milo.c milo-2.2-18/milo.c --- milo-2.2-18-patched/milo.c 2001-07-18 22:38:38.000000000 +0900 +++ milo-2.2-18/milo.c 2025-02-24 16:49:51.000000000 +0900 @@ -692,11 +692,11 @@ chptr = buf = kmalloc(size + 2, 0); - iobuf = kmalloc(IOBUF_SIZE + 512, 0) + 512; + iobuf = kmalloc(milo_open_fs->blocksize + 512, 0) + 512; iobuf = (char *) ((unsigned long) iobuf & (~(512 - 1))); while ((rc = __bread(fd, blkno++, iobuf)) == 0) { - memcpy((char *) chptr, iobuf, IOBUF_SIZE); - chptr += IOBUF_SIZE; + memcpy((char *) chptr, iobuf, milo_open_fs->blocksize); + chptr += milo_open_fs->blocksize; if ((chptr - buf) >= size) break; } diff -aurN milo-2.2-18-patched/zip/misc.c milo-2.2-18/zip/misc.c --- milo-2.2-18-patched/zip/misc.c 1999-11-23 21:38:48.000000000 +0900 +++ milo-2.2-18/zip/misc.c 2025-02-24 16:49:58.000000000 +0900 @@ -129,7 +129,7 @@ __bread(input_fd, block_number++, inbuf); - insize = INBUFSIZ; + insize = milo_open_fs->blocksize; inptr = 1; return inbuf[0]; @@ -179,7 +179,7 @@ { input_fd = fd; - inbuf = (unsigned char *) kmalloc(INBUFSIZ, 0); + inbuf = (unsigned char *) kmalloc(milo_open_fs->blocksize, 0); window = (unsigned char *) kmalloc(WSIZE, 0); dest_addr = (char *) where;