diff options
| author | Matt Fleming <matt.fleming@intel.com> | 2013-01-29 14:01:07 +0000 |
|---|---|---|
| committer | Matt Fleming <matt.fleming@intel.com> | 2013-01-29 15:11:28 +0000 |
| commit | bf20364b582c383b4927f898de213b1cc0981a80 (patch) | |
| tree | 5412e0c14cf74df0d7ea29ff182e23d3281aac3e /core | |
| parent | afd985f6eec18a0f66a8fc55f9c5e3431128310f (diff) | |
| parent | a2d79191b501276026a0a16ec2fa664630a20476 (diff) | |
| download | syslinux-6.00-pre4.tar.gz | |
Merge tag 'syslinux-5.01' into firmwaresyslinux-6.00-pre4
Conflicts:
Makefile
NEWS
com32/cmenu/Makefile
com32/elflink/ldlinux/Makefile
com32/gfxboot/Makefile
com32/gpllib/Makefile
com32/include/sys/module.h
com32/lib/Makefile
com32/lib/sys/module/elf_module.c
com32/menu/Makefile
com32/rosh/Makefile
com32/samples/Makefile
core/init.c
mk/elf.mk
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'core')
| -rw-r--r-- | core/bios.c | 1 | ||||
| -rw-r--r-- | core/conio.c | 31 | ||||
| -rw-r--r-- | core/elflink/load_env32.c | 33 | ||||
| -rw-r--r-- | core/fs/fs.c | 118 | ||||
| -rw-r--r-- | core/fs/pxe/dnsresolv.c | 2 | ||||
| -rw-r--r-- | core/fs/pxe/pxe.c | 4 | ||||
| -rw-r--r-- | core/fs/xfs/xfs.c | 56 | ||||
| -rw-r--r-- | core/fs/xfs/xfs.h | 15 | ||||
| -rw-r--r-- | core/fs/xfs/xfs_dinode.c | 4 | ||||
| -rw-r--r-- | core/fs/xfs/xfs_dir2.c | 212 | ||||
| -rw-r--r-- | core/fs/xfs/xfs_dir2.h | 21 | ||||
| -rw-r--r-- | core/fs/xfs/xfs_readdir.c | 112 | ||||
| -rw-r--r-- | core/include/bios.h | 2 | ||||
| -rw-r--r-- | core/include/fs.h | 3 | ||||
| -rw-r--r-- | core/init.inc | 6 | ||||
| -rw-r--r-- | core/isolinux.asm | 3 | ||||
| -rw-r--r-- | core/lzo/enter.ash | 3 | ||||
| -rw-r--r-- | core/lzo/leave.ash | 3 | ||||
| -rw-r--r-- | core/lzo/lzo1c_d.ash | 3 | ||||
| -rw-r--r-- | core/lzo/lzo1f_d.ash | 3 | ||||
| -rw-r--r-- | core/lzo/lzo1x_d.ash | 3 | ||||
| -rw-r--r-- | core/lzo/lzo1x_f2.S (renamed from core/lzo/lzo1x_f1.S) | 13 | ||||
| -rw-r--r-- | core/lzo/lzo_asm.h | 23 | ||||
| -rw-r--r-- | core/mem/malloc.c | 2 | ||||
| -rw-r--r-- | core/pxelinux.asm | 4 |
25 files changed, 334 insertions, 346 deletions
diff --git a/core/bios.c b/core/bios.c index 1becd280..bd8b4d87 100644 --- a/core/bios.c +++ b/core/bios.c @@ -537,7 +537,6 @@ void bios_init(void) /* Init the memory subsystem */ bios_free_mem = (uint16_t *)0x413; - mem_init(); /* CPU-dependent initialization and related checks. */ check_escapes(); diff --git a/core/conio.c b/core/conio.c index a351fd14..5587203f 100644 --- a/core/conio.c +++ b/core/conio.c @@ -45,6 +45,8 @@ __export uint8_t FlowIgnore = 0; /* Ignore input unless these bits set */ __export uint16_t DisplayCon = 0x01; /* Display console enabled */ __export uint8_t FlowOutput = 0; /* Output to assert for serial flow */ +__export uint8_t DisplayMask = 0x07; /* Display modes mask */ + uint8_t ScrollAttribute = 0x07; /* Grey on white (normal text color) */ /* @@ -75,6 +77,9 @@ __export void write_serial(char data) if (!SerialPort) return; + if (!(DisplayMask & 0x04)) + return; + while (1) { char ch; @@ -162,21 +167,22 @@ int bios_pollchar(void) /* Already-queued input? */ if (SerialTail == SerialHead) { /* LSR */ - data = inb(SerialPort + 5) & 1; - if (data) { + data = !(inb(SerialPort + 5) & 1); + if (!data) { /* MSR */ data = inb(SerialPort + 6); /* Required status bits */ - if (data) { - data &= FlowIgnore; - if (data != FlowIgnore) - data = 0; - else - data = 1; - } - } - } + data &= FlowIgnore; + + if (data == FlowIgnore) + data = 1; + else + data = 0; + } else + data = 1; + } else + data = 1; sti(); } @@ -221,7 +227,8 @@ char bios_getchar(char *hi) sti(); /* We already know we'll consume data */ data = *SerialTail++; - SerialTail = (char *)((unsigned long)SerialTail & (serial_buf_size - 1)); + if (SerialTail > SerialHead + serial_buf_size) + SerialTail = SerialHead; } else { /* LSR */ data = inb(SerialPort + 5) & 1; diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c index 1fa43bd6..b277877a 100644 --- a/core/elflink/load_env32.c +++ b/core/elflink/load_env32.c @@ -48,10 +48,10 @@ struct elf_module core_module = { }; /* - Initializes the module subsystem by taking the core module ( shallow module ) and placing - it on top of the modules_head_list. Since the core module is initialized when declared - we technically don't need the exec_init() and module_load_shallow() procedures -*/ + * Initializes the module subsystem by taking the core module + * (preinitialized shallow module) and placing it on top of the + * modules_head_list. + */ void init_module_subsystem(struct elf_module *module) { list_add(&module->list, &modules_head); @@ -126,7 +126,7 @@ void load_env32(com32sys_t * regs __unused) PATH = malloc(strlen(CurrentDirName) + 1); if (!PATH) { printf("Couldn't allocate memory for PATH\n"); - return; + goto out; } strcpy(PATH, CurrentDirName); @@ -147,15 +147,36 @@ void load_env32(com32sys_t * regs __unused) * a bit harder to find LDLINUX. If search_dirs() succeeds * in finding LDLINUX it will set the cwd. */ + free(PATH); fd = opendev(&__file_dev, NULL, O_RDONLY); if (fd < 0) return; fp = &__file_info[fd]; - if (!search_dirs(&fp->i.fd, search_directories, filenames, realname)) + if (!search_dirs(&fp->i.fd, search_directories, filenames, realname)) { + char path[FILENAME_MAX]; + + /* + * search_dirs() sets the current working directory if + * it successfully opens the file. Set PATH to the + * directory in which we found ldlinux.c32. + */ + if (!core_getcwd(path, sizeof(path))) + goto out; + + PATH = malloc(strlen(path) + 1); + if (!PATH) { + printf("Couldn't allocate memory for PATH\n"); + goto out; + } + + strcpy(PATH, path); + start_ldlinux(argv); + } +out: writestr("\nFailed to load ldlinux.c32"); } diff --git a/core/fs/fs.c b/core/fs/fs.c index 40f97d5e..adcee916 100644 --- a/core/fs/fs.c +++ b/core/fs/fs.c @@ -40,9 +40,13 @@ struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data) */ void put_inode(struct inode *inode) { - while (inode && --inode->refcnt == 0) { + while (inode) { struct inode *dead = inode; - inode = inode->parent; + int refcnt = --(dead->refcnt); + dprintf("put_inode %p name %s refcnt %u\n", dead, dead->name, refcnt); + if (refcnt) + break; /* We still have references */ + inode = dead->parent; if (dead->name) free((char *)dead->name); free(dead); @@ -108,77 +112,11 @@ __export int open_config(void) return fd; } -void pm_mangle_name(com32sys_t *regs) -{ - const char *src = MK_PTR(regs->ds, regs->esi.w[0]); - char *dst = MK_PTR(regs->es, regs->edi.w[0]); - - mangle_name(dst, src); -} - __export void mangle_name(char *dst, const char *src) { this_fs->fs_ops->mangle_name(dst, src); } -void getfssec(com32sys_t *regs) -{ - int sectors; - bool have_more; - uint32_t bytes_read; - char *buf; - struct file *file; - uint16_t handle; - - sectors = regs->ecx.w[0]; - - handle = regs->esi.w[0]; - file = handle_to_file(handle); - - buf = MK_PTR(regs->es, regs->ebx.w[0]); - bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); - - /* - * If we reach EOF, the filesystem driver will have already closed - * the underlying file... this really should be cleaner. - */ - if (!have_more) { - _close_file(file); - regs->esi.w[0] = 0; - } - - regs->ecx.l = bytes_read; -} - -void getfsbytes(com32sys_t *regs) -{ - int sectors; - bool have_more; - uint32_t bytes_read; - char *buf; - struct file *file; - uint16_t handle; - - handle = regs->esi.w[0]; - file = handle_to_file(handle); - - sectors = regs->ecx.w[0] >> SECTOR_SHIFT(file->fs); - - buf = MK_PTR(regs->es, regs->ebx.w[0]); - bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); - - /* - * If we reach EOF, the filesystem driver will have already closed - * the underlying file... this really should be cleaner. - */ - if (!have_more) { - _close_file(file); - regs->esi.w[0] = 0; - } - - regs->ecx.l = bytes_read; -} - size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors) { bool have_more; @@ -200,23 +138,6 @@ size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors) return bytes_read; } -void pm_searchdir(com32sys_t *regs) -{ - char *name = MK_PTR(regs->ds, regs->edi.w[0]); - int rv; - - rv = searchdir(name); - if (rv < 0) { - regs->esi.w[0] = 0; - regs->eax.l = 0; - regs->eflags.l |= EFLAGS_ZF; - } else { - regs->esi.w[0] = rv; - regs->eax.l = handle_to_file(rv)->inode->size; - regs->eflags.l &= ~EFLAGS_ZF; - } -} - int searchdir(const char *name) { static char root_name[] = "/"; @@ -444,28 +365,6 @@ __export int open_file(const char *name, struct com32_filedata *filedata) return rv; } -void pm_open_file(com32sys_t *regs) -{ - int rv; - struct file *file; - const char *name = MK_PTR(regs->es, regs->esi.w[0]); - char mangled_name[FILENAME_MAX]; - - dprintf("pm_open_file %s\n", name); - - mangle_name(mangled_name, name); - rv = searchdir(mangled_name); - if (rv < 0) { - regs->eflags.l |= EFLAGS_CF; - } else { - file = handle_to_file(rv); - regs->eflags.l &= ~EFLAGS_CF; - regs->eax.l = file->inode->size; - regs->ecx.w[0] = SECTOR_SIZE(file->fs); - regs->esi.w[0] = rv; - } -} - __export void close_file(uint16_t handle) { struct file *file; @@ -476,11 +375,6 @@ __export void close_file(uint16_t handle) } } -void pm_close_file(com32sys_t *regs) -{ - close_file(regs->esi.w[0]); -} - /* * it will do: * initialize the memory management function; diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c index fda0f815..184bacbd 100644 --- a/core/fs/pxe/dnsresolv.c +++ b/core/fs/pxe/dnsresolv.c @@ -170,7 +170,7 @@ static char *dns_skiplabel(char *label) * * XXX: probably need some caching here. */ -uint32_t dns_resolv(const char *name) +__export uint32_t dns_resolv(const char *name) { static char __lowmem DNSSendBuf[PKTBUF_SIZE]; static char __lowmem DNSRecvBuf[PKTBUF_SIZE]; diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c index 11270044..ae44cffe 100644 --- a/core/fs/pxe/pxe.c +++ b/core/fs/pxe/pxe.c @@ -254,7 +254,7 @@ static const char *parse_dotquad(const char *ip_str, uint32_t *res) * the ASM pxenv function wrapper, return 1 if error, or 0 * */ -int pxe_call(int opcode, void *data) +__export int pxe_call(int opcode, void *data) { extern void pxenv(void); com32sys_t regs; @@ -1656,7 +1656,7 @@ int reset_pxe(void) * This function unloads the PXE and UNDI stacks and * unclaims the memory. */ -void unload_pxe(uint16_t flags) +__export void unload_pxe(uint16_t flags) { /* PXE unload sequences */ static const uint8_t new_api_unload[] = { diff --git a/core/fs/xfs/xfs.c b/core/fs/xfs/xfs.c index 89a9aef2..b6a396aa 100644 --- a/core/fs/xfs/xfs.c +++ b/core/fs/xfs/xfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com> + * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -38,29 +38,26 @@ #include "xfs_readdir.h" static inline int xfs_fmt_local_readdir(struct file *file, - struct dirent *dirent, xfs_dinode_t *core) + struct dirent *dirent, + xfs_dinode_t *core) { - return xfs_readdir_dir2_block(file, dirent, core); + return xfs_readdir_dir2_local(file, dirent, core); } static inline int xfs_fmt_extents_readdir(struct file *file, struct dirent *dirent, xfs_dinode_t *core) { - int retval; - if (be32_to_cpu(core->di_nextents) <= 1) { /* Single-block Directories */ - retval = xfs_readdir_dir2_block(file, dirent, core); + return xfs_readdir_dir2_block(file, dirent, core); } else if (xfs_dir2_isleaf(file->fs, core)) { /* Leaf Directory */ - retval = xfs_readdir_dir2_leaf(file, dirent, core); + return xfs_readdir_dir2_leaf(file, dirent, core); } else { /* Node Directory */ - retval = xfs_readdir_dir2_node(file, dirent, core); + return xfs_readdir_dir2_node(file, dirent, core); } - - return retval; } static int xfs_readdir(struct file *file, struct dirent *dirent) @@ -68,7 +65,8 @@ static int xfs_readdir(struct file *file, struct dirent *dirent) struct fs_info *fs = file->fs; xfs_dinode_t *core; struct inode *inode = file->inode; - int retval = -1; + + xfs_debug("file %p dirent %p"); core = xfs_dinode_get_core(fs, inode->ino); if (!core) { @@ -77,11 +75,11 @@ static int xfs_readdir(struct file *file, struct dirent *dirent) } if (core->di_format == XFS_DINODE_FMT_LOCAL) - retval = xfs_fmt_local_readdir(file, dirent, core); + return xfs_fmt_local_readdir(file, dirent, core); else if (core->di_format == XFS_DINODE_FMT_EXTENTS) - retval = xfs_fmt_extents_readdir(file, dirent, core); + return xfs_fmt_extents_readdir(file, dirent, core); - return retval; + return -1; } static uint32_t xfs_getfssec(struct file *file, char *buf, int sectors, @@ -106,6 +104,8 @@ static int xfs_next_extent(struct inode *inode, uint32_t lstart) (void)lstart; + xfs_debug("inode %p lstart %lu", inode, lstart); + core = xfs_dinode_get_core(fs, inode->ino); if (!core) { xfs_error("Failed to get dinode from disk (ino %llx)", inode->ino); @@ -190,20 +190,16 @@ static inline struct inode *xfs_fmt_extents_find_entry(const char *dname, struct inode *parent, xfs_dinode_t *core) { - struct inode *inode; - if (be32_to_cpu(core->di_nextents) <= 1) { - /* Single-block Directories */ - inode = xfs_dir2_block_find_entry(dname, parent, core); + /* Single-block Directories */ + return xfs_dir2_block_find_entry(dname, parent, core); } else if (xfs_dir2_isleaf(parent->fs, core)) { - /* Leaf Directory */ - inode = xfs_dir2_leaf_find_entry(dname, parent, core); + /* Leaf Directory */ + return xfs_dir2_leaf_find_entry(dname, parent, core); } else { - /* Node Directory */ - inode = xfs_dir2_node_find_entry(dname, parent, core); + /* Node Directory */ + return xfs_dir2_node_find_entry(dname, parent, core); } - - return inode; } static inline struct inode *xfs_fmt_btree_find_entry(const char *dname, @@ -233,11 +229,6 @@ static struct inode *xfs_iget(const char *dname, struct inode *parent) inode = xfs_fmt_extents_find_entry(dname, parent, core); } else if (core->di_format == XFS_DINODE_FMT_BTREE) { inode = xfs_fmt_btree_find_entry(dname, parent, core); - } else { - xfs_debug("format %hhu", core->di_format); - xfs_debug("TODO: format \"local\" and \"extents\" are the only " - "supported ATM"); - goto out; } if (!inode) { @@ -266,7 +257,9 @@ static int xfs_readlink(struct inode *inode, char *buf) int pathlen = -1; xfs_bmbt_irec_t rec; block_t db; - char *dir_buf; + const char *dir_buf; + + xfs_debug("inode %p buf %p", inode, buf); core = xfs_dinode_get_core(fs, inode->ino); if (!core) { @@ -289,7 +282,7 @@ static int xfs_readlink(struct inode *inode, char *buf) } else if (core->di_format == XFS_DINODE_FMT_EXTENTS) { bmbt_irec_get(&rec, (xfs_bmbt_rec_t *)&core->di_literal_area[0]); db = fsblock_to_bytes(fs, rec.br_startblock) >> BLOCK_SHIFT(fs); - dir_buf = xfs_dir2_get_dirblks(fs, db, rec.br_blockcount); + dir_buf = xfs_dir2_dirblks_get_cached(fs, db, rec.br_blockcount); /* * Syslinux only supports filesystem block size larger than or equal to @@ -297,7 +290,6 @@ static int xfs_readlink(struct inode *inode, char *buf) * symbolic link file content, which is only 1024 bytes long. */ memcpy(buf, dir_buf, pathlen); - free(dir_buf); } out: diff --git a/core/fs/xfs/xfs.h b/core/fs/xfs/xfs.h index da57221a..0d953d89 100644 --- a/core/fs/xfs/xfs.h +++ b/core/fs/xfs/xfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com> + * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com> * * Some parts borrowed from Linux kernel tree (linux/fs/xfs): * @@ -30,11 +30,16 @@ #include "xfs_types.h" #include "xfs_ag.h" -#define xfs_error(fmt, args...) \ - printf("xfs: " fmt "\n", ## args); +#define xfs_error(fmt, args...) \ + ({ \ + printf("%s:%u: xfs - [ERROR] " fmt "\n", __func__, __LINE__, ## args); \ + }) -#define xfs_debug(fmt, args...) \ - dprintf("%s: " fmt "\n", __func__, ## args); +#define xfs_debug(fmt, args...) \ + ({ \ + dprintf("%s:%u: xfs - [DEBUG] " fmt "\n", __func__, __LINE__, \ + ## args); \ + }) struct xfs_fs_info; diff --git a/core/fs/xfs/xfs_dinode.c b/core/fs/xfs/xfs_dinode.c index 8e2d8d04..55be6e2d 100644 --- a/core/fs/xfs/xfs_dinode.c +++ b/core/fs/xfs/xfs_dinode.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com> + * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -33,7 +33,7 @@ xfs_dinode_t *xfs_dinode_get_core(struct fs_info *fs, xfs_ino_t ino) xfs_dinode_t *core; uint64_t offset; - xfs_debug("ino %lu", ino); + xfs_debug("fs %p ino %lu", fs, ino); blk = ino_to_bytes(fs, ino) >> BLOCK_SHIFT(fs); offset = XFS_INO_TO_OFFSET(XFS_INFO(fs), ino) << XFS_INFO(fs)->inode_shift; diff --git a/core/fs/xfs/xfs_dir2.c b/core/fs/xfs/xfs_dir2.c index c52196ae..de37ef7c 100644 --- a/core/fs/xfs/xfs_dir2.c +++ b/core/fs/xfs/xfs_dir2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com> + * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,23 +28,16 @@ #include "xfs_dir2.h" -char *xfs_dir2_get_entry_name(uint8_t *start, uint8_t *end) -{ - char *s; - char *p; - - s = malloc(end - start + 1); - if (!s) - malloc_error("string"); +#define XFS_DIR2_DIRBLKS_CACHE_SIZE 128 - p = s; - while (start < end) - *p++ = *start++; +struct xfs_dir2_dirblks_cache { + block_t dc_startblock; + xfs_filblks_t dc_blkscount; + void *dc_area; +}; - *p = '\0'; - - return s; -} +static struct xfs_dir2_dirblks_cache dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE]; +static unsigned char dirblks_cached_count = 0; uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen) { @@ -73,8 +66,8 @@ uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen) } } -void *xfs_dir2_get_dirblks(struct fs_info *fs, block_t startblock, - xfs_filblks_t c) +static void *get_dirblks(struct fs_info *fs, block_t startblock, + xfs_filblks_t c) { int count = c << XFS_INFO(fs)->dirblklog; uint8_t *p; @@ -96,6 +89,85 @@ void *xfs_dir2_get_dirblks(struct fs_info *fs, block_t startblock, return buf; } +const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock, + xfs_filblks_t c) +{ + unsigned char i; + void *buf; + + xfs_debug("fs %p startblock %llu (0x%llx) blkscount %lu", fs, startblock, + startblock, c); + + if (!dirblks_cached_count) { + buf = get_dirblks(fs, startblock, c); + + dirblks_cache[dirblks_cached_count].dc_startblock = startblock; + dirblks_cache[dirblks_cached_count].dc_blkscount = c; + dirblks_cache[dirblks_cached_count].dc_area = buf; + + return dirblks_cache[dirblks_cached_count++].dc_area; + } else if (dirblks_cached_count == XFS_DIR2_DIRBLKS_CACHE_SIZE) { + for (i = 0; i < XFS_DIR2_DIRBLKS_CACHE_SIZE / 2; i++) { + unsigned char k = XFS_DIR2_DIRBLKS_CACHE_SIZE - (i + 1); + + free(dirblks_cache[i].dc_area); + dirblks_cache[i] = dirblks_cache[k]; + memset(&dirblks_cache[k], 0, sizeof(dirblks_cache[k])); + } + + buf = get_dirblks(fs, startblock, c); + + dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE / 2].dc_startblock = + startblock; + dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE / 2].dc_blkscount = c; + dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE / 2].dc_area = buf; + + dirblks_cached_count = XFS_DIR2_DIRBLKS_CACHE_SIZE / 2; + + return dirblks_cache[dirblks_cached_count++].dc_area; + } else { + block_t block; + xfs_filblks_t count; + + block = dirblks_cache[dirblks_cached_count - 1].dc_startblock; + count = dirblks_cache[dirblks_cached_count - 1].dc_blkscount; + + if (block == startblock && count == c) { + return dirblks_cache[dirblks_cached_count - 1].dc_area; + } else { + for (i = 0; i < dirblks_cached_count; i++) { + block = dirblks_cache[i].dc_startblock; + count = dirblks_cache[i].dc_blkscount; + + if (block == startblock && count == c) + return dirblks_cache[i].dc_area; + } + + buf = get_dirblks(fs, startblock, c); + + dirblks_cache[dirblks_cached_count].dc_startblock = startblock; + dirblks_cache[dirblks_cached_count].dc_blkscount = c; + dirblks_cache[dirblks_cached_count].dc_area = buf; + + return dirblks_cache[dirblks_cached_count++].dc_area; + } + } + + return NULL; +} + +void xfs_dir2_dirblks_flush_cache(void) +{ + unsigned char i; + + for (i = 0; i < dirblks_cached_count; i++) { + free(dirblks_cache[i].dc_area); + memset(&dirblks_cache[i], 0, sizeof(dirblks_cache[i])); + } + + dirblks_cached_count = 0; +} + struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent, xfs_dinode_t *core) { @@ -107,6 +179,7 @@ struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent, xfs_intino_t ino; xfs_dinode_t *ncore = NULL; + xfs_debug("dname %s parent %p core %p", dname, parent, core); xfs_debug("count %hhu i8count %hhu", sf->hdr.count, sf->hdr.i8count); sf_entry = (xfs_dir2_sf_entry_t *)((uint8_t *)&sf->list[0] - @@ -114,19 +187,12 @@ struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent, while (count--) { uint8_t *start_name = &sf_entry->name[0]; uint8_t *end_name = start_name + sf_entry->namelen; - char *name; - name = xfs_dir2_get_entry_name(start_name, end_name); - - xfs_debug("entry name: %s", name); - - if (!strncmp(name, dname, strlen(dname))) { - free(name); + if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) { + xfs_debug("Found entry %s", dname); goto found; } - free(name); - sf_entry = (xfs_dir2_sf_entry_t *)((uint8_t *)sf_entry + offsetof(struct xfs_dir2_sf_entry, name[0]) + @@ -184,7 +250,7 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent, xfs_bmbt_irec_t r; block_t dir_blk; struct fs_info *fs = parent->fs; - uint8_t *dirblk_buf; + const uint8_t *dirblk_buf; uint8_t *p, *endp; xfs_dir2_data_hdr_t *hdr; struct inode *inode = NULL; @@ -194,10 +260,12 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent, xfs_intino_t ino; xfs_dinode_t *ncore; + xfs_debug("dname %s parent %p core %p", dname, parent, core); + bmbt_irec_get(&r, (xfs_bmbt_rec_t *)&core->di_literal_area[0]); dir_blk = fsblock_to_bytes(fs, r.br_startblock) >> BLOCK_SHIFT(fs); - dirblk_buf = xfs_dir2_get_dirblks(fs, dir_blk, r.br_blockcount); + dirblk_buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, r.br_blockcount); hdr = (xfs_dir2_data_hdr_t *)dirblk_buf; if (be32_to_cpu(hdr->magic) != XFS_DIR2_BLOCK_MAGIC) { xfs_error("Block directory header's magic number does not match!"); @@ -213,7 +281,6 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent, while (p < endp) { uint8_t *start_name; uint8_t *end_name; - char *name; dup = (xfs_dir2_data_unused_t *)p; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { @@ -225,20 +292,16 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent, start_name = &dep->name[0]; end_name = start_name + dep->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); - if (!strncmp(name, dname, strlen(dname))) { - free(name); + if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) { + xfs_debug("Found entry %s", dname); goto found; } - free(name); p += xfs_dir2_data_entsize(dep->namelen); } out: - free(dirblk_buf); - return NULL; found: @@ -274,12 +337,10 @@ found: xfs_debug("entry inode's number %lu", ino); - free(dirblk_buf); return inode; failed: free(inode); - free(dirblk_buf); return NULL; } @@ -302,25 +363,26 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent, xfs_dir2_data_hdr_t *data_hdr; uint8_t *start_name; uint8_t *end_name; - char *name; xfs_intino_t ino; xfs_dinode_t *ncore; - uint8_t *buf = NULL; + const uint8_t *buf = NULL; + + xfs_debug("dname %s parent %p core %p", dname, parent, core); bmbt_irec_get(&irec, ((xfs_bmbt_rec_t *)&core->di_literal_area[0]) + be32_to_cpu(core->di_nextents) - 1); leaf_blk = fsblock_to_bytes(parent->fs, irec.br_startblock) >> BLOCK_SHIFT(parent->fs); - leaf = (xfs_dir2_leaf_t *)xfs_dir2_get_dirblks(parent->fs, leaf_blk, - irec.br_blockcount); + leaf = (xfs_dir2_leaf_t *)xfs_dir2_dirblks_get_cached(parent->fs, leaf_blk, + irec.br_blockcount); if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) { xfs_error("Single leaf block header's magic number does not match!"); goto out; } if (!leaf->hdr.count) - goto out; + goto out; hashwant = xfs_dir2_da_hashname((uint8_t *)dname, strlen(dname)); @@ -355,18 +417,16 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent, newdb = xfs_dir2_dataptr_to_db(parent->fs, be32_to_cpu(lep->address)); if (newdb != curdb) { - if (buf) - free(buf); - bmbt_irec_get(&irec, ((xfs_bmbt_rec_t *)&core->di_literal_area[0]) + newdb); dir_blk = fsblock_to_bytes(parent->fs, irec.br_startblock) >> + BLOCK_SHIFT(parent->fs); - buf = xfs_dir2_get_dirblks(parent->fs, dir_blk, irec.br_blockcount); + buf = xfs_dir2_dirblks_get_cached(parent->fs, dir_blk, irec.br_blockcount); data_hdr = (xfs_dir2_data_hdr_t *)buf; if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) { xfs_error("Leaf directory's data magic No. does not match!"); - goto out1; + goto out; } curdb = newdb; @@ -377,21 +437,14 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent, start_name = &dep->name[0]; end_name = start_name + dep->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); - if (!strncmp(name, dname, strlen(dname))) { - free(name); + if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) { + xfs_debug("Found entry %s", dname); goto found; } - - free(name); } -out1: - free(buf); out: - free(leaf); - return NULL; found: @@ -428,15 +481,10 @@ found: xfs_debug("entry inode's number %lu", ino); - free(buf); - free(leaf); - return ip; failed: free(ip); - free(buf); - free(leaf); return ip; } @@ -560,14 +608,15 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent, struct inode *ip; uint8_t *start_name; uint8_t *end_name; - char *name; int low; int high; int mid = 0; uint32_t newdb, curdb = -1; xfs_intino_t ino; xfs_dinode_t *ncore; - uint8_t *buf = NULL; + const uint8_t *buf = NULL; + + xfs_debug("dname %s parent %p core %p", dname, parent, core); hashwant = xfs_dir2_da_hashname((uint8_t *)dname, strlen(dname)); @@ -579,7 +628,8 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent, return NULL; } - node = (xfs_da_intnode_t *)xfs_dir2_get_dirblks(parent->fs, fsblkno, 1); + node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(parent->fs, fsblkno, + 1); if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { xfs_error("Node's magic number does not match!"); goto out; @@ -630,9 +680,8 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent, goto out; } - free(node); - node = (xfs_da_intnode_t *)xfs_dir2_get_dirblks(parent->fs, - fsblkno, 1); + node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(parent->fs, + fsblkno, 1); } while(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); leaf = (xfs_dir2_leaf_t*)node; @@ -675,20 +724,17 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent, newdb = xfs_dir2_dataptr_to_db(parent->fs, be32_to_cpu(lep->address)); if (newdb != curdb) { - if (buf) - free(buf); - fsblkno = xfs_dir2_get_right_blk(parent->fs, core, newdb, &error); if (error) { xfs_error("Cannot find data block!"); goto out; } - buf = xfs_dir2_get_dirblks(parent->fs, fsblkno, 1); + buf = xfs_dir2_dirblks_get_cached(parent->fs, fsblkno, 1); data_hdr = (xfs_dir2_data_hdr_t *)buf; if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) { xfs_error("Leaf directory's data magic No. does not match!"); - goto out1; + goto out; } curdb = newdb; @@ -699,21 +745,14 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent, start_name = &dep->name[0]; end_name = start_name + dep->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); - if (!strncmp(name, dname, strlen(dname))) { - free(name); - goto found; - } - free(name); + if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) { + xfs_debug("Found entry %s", dname); + goto found; + } } -out1: - free(buf); - out: - free(node); - return NULL; found: @@ -745,15 +784,10 @@ found: xfs_debug("entry inode's number %lu", ino); - free(buf); - free(node); - return ip; failed: free(ip); - free(buf); - free(node); return NULL; } diff --git a/core/fs/xfs/xfs_dir2.h b/core/fs/xfs/xfs_dir2.h index e1b96227..158cf44f 100644 --- a/core/fs/xfs/xfs_dir2.h +++ b/core/fs/xfs/xfs_dir2.h @@ -23,10 +23,12 @@ #include "xfs.h" -char *xfs_dir2_get_entry_name(uint8_t *start, uint8_t *end); -void *xfs_dir2_get_dirblks(struct fs_info *fs, block_t startblock, - xfs_filblks_t c); +const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock, + xfs_filblks_t c); +void xfs_dir2_dirblks_flush_cache(void); + uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen); + block_t xfs_dir2_get_right_blk(struct fs_info *fs, xfs_dinode_t *core, block_t fsblkno, int *error); @@ -51,4 +53,17 @@ static inline bool xfs_dir2_isleaf(struct fs_info *fs, xfs_dinode_t *dip) return (last == XFS_INFO(fs)->dirleafblk + (1 << XFS_INFO(fs)->dirblklog)); } +static inline int xfs_dir2_entry_name_cmp(uint8_t *start, uint8_t *end, + const char *name) +{ + if (!name || (strlen(name) != end - start)) + return -1; + + while (start < end) + if (*start++ != *name++) + return -1; + + return 0; +} + #endif /* XFS_DIR2_H_ */ diff --git a/core/fs/xfs/xfs_readdir.c b/core/fs/xfs/xfs_readdir.c index 0e013e55..86c8a77b 100644 --- a/core/fs/xfs/xfs_readdir.c +++ b/core/fs/xfs/xfs_readdir.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com> + * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -35,6 +35,9 @@ static int fill_dirent(struct fs_info *fs, struct dirent *dirent, { xfs_dinode_t *core; + xfs_debug("fs %p, dirent %p offset %lu ino %llu name %s namelen %llu", fs, + dirent, offset, ino, name, namelen); + dirent->d_ino = ino; dirent->d_off = offset; dirent->d_reclen = offsetof(struct dirent, d_name) + namelen + 1; @@ -52,7 +55,8 @@ static int fill_dirent(struct fs_info *fs, struct dirent *dirent, else if (be16_to_cpu(core->di_mode) & S_IFLNK) dirent->d_type = DT_LNK; - memcpy(dirent->d_name, name, namelen + 1); + memcpy(dirent->d_name, name, namelen); + dirent->d_name[namelen] = '\0'; return 0; } @@ -66,15 +70,15 @@ int xfs_readdir_dir2_local(struct file *file, struct dirent *dirent, uint32_t offset = file->offset; uint8_t *start_name; uint8_t *end_name; - char *name; xfs_ino_t ino; struct fs_info *fs = file->fs; int retval = 0; + xfs_debug("file %p dirent %p core %p", file, dirent, core); xfs_debug("count %hhu i8count %hhu", sf->hdr.count, sf->hdr.i8count); if (file->offset + 1 > count) - return -1; + goto out; file->offset++; @@ -96,22 +100,23 @@ int xfs_readdir_dir2_local(struct file *file, struct dirent *dirent, start_name = &sf_entry->name[0]; end_name = start_name + sf_entry->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); - ino = xfs_dir2_sf_get_inumber(sf, (xfs_dir2_inou_t *)( (uint8_t *)sf_entry + offsetof(struct xfs_dir2_sf_entry, name[0]) + sf_entry->namelen)); - retval = fill_dirent(fs, dirent, file->offset, ino, (char *)name, + retval = fill_dirent(fs, dirent, file->offset, ino, (char *)start_name, end_name - start_name); if (retval) xfs_error("Failed to fill in dirent structure"); - free(name); - return retval; + +out: + xfs_dir2_dirblks_flush_cache(); + + return -1; } int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent, @@ -120,7 +125,7 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent, xfs_bmbt_irec_t r; block_t dir_blk; struct fs_info *fs = file->fs; - uint8_t *dirblk_buf; + const uint8_t *dirblk_buf; uint8_t *p; uint32_t offset; xfs_dir2_data_hdr_t *hdr; @@ -129,28 +134,26 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent, xfs_dir2_data_entry_t *dep; uint8_t *start_name; uint8_t *end_name; - char *name; xfs_ino_t ino; int retval = 0; + xfs_debug("file %p dirent %p core %p", file, dirent, core); + bmbt_irec_get(&r, (xfs_bmbt_rec_t *)&core->di_literal_area[0]); dir_blk = fsblock_to_bytes(fs, r.br_startblock) >> BLOCK_SHIFT(fs); - dirblk_buf = xfs_dir2_get_dirblks(fs, dir_blk, r.br_blockcount); + dirblk_buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, r.br_blockcount); hdr = (xfs_dir2_data_hdr_t *)dirblk_buf; if (be32_to_cpu(hdr->magic) != XFS_DIR2_BLOCK_MAGIC) { xfs_error("Block directory header's magic number does not match!"); xfs_debug("hdr->magic: 0x%lx", be32_to_cpu(hdr->magic)); - - free(dirblk_buf); - - return -1; + goto out; } btp = xfs_dir2_block_tail_p(XFS_INFO(fs), hdr); if (file->offset + 1 > be32_to_cpu(btp->count)) - return -1; + goto out; file->offset++; @@ -175,19 +178,20 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent, start_name = &dep->name[0]; end_name = start_name + dep->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); ino = be64_to_cpu(dep->inumber); - retval = fill_dirent(fs, dirent, file->offset, ino, name, + retval = fill_dirent(fs, dirent, file->offset, ino, (char *)start_name, end_name - start_name); if (retval) xfs_error("Failed to fill in dirent structure"); - free(dirblk_buf); - free(name); - return retval; + +out: + xfs_dir2_dirblks_flush_cache(); + + return -1; } int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent, @@ -204,18 +208,19 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent, xfs_dir2_data_hdr_t *data_hdr; uint8_t *start_name; uint8_t *end_name; - char *name; xfs_intino_t ino; - uint8_t *buf = NULL; + const uint8_t *buf = NULL; int retval = 0; + xfs_debug("file %p dirent %p core %p", file, dirent, core); + bmbt_irec_get(&irec, ((xfs_bmbt_rec_t *)&core->di_literal_area[0]) + be32_to_cpu(core->di_nextents) - 1); leaf_blk = fsblock_to_bytes(fs, irec.br_startblock) >> BLOCK_SHIFT(file->fs); - leaf = (xfs_dir2_leaf_t *)xfs_dir2_get_dirblks(fs, leaf_blk, - irec.br_blockcount); + leaf = (xfs_dir2_leaf_t *)xfs_dir2_dirblks_get_cached(fs, leaf_blk, + irec.br_blockcount); if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) { xfs_error("Single leaf block header's magic number does not match!"); goto out; @@ -239,11 +244,11 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent, dir_blk = fsblock_to_bytes(fs, irec.br_startblock) >> BLOCK_SHIFT(fs); - buf = xfs_dir2_get_dirblks(fs, dir_blk, irec.br_blockcount); + buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, irec.br_blockcount); data_hdr = (xfs_dir2_data_hdr_t *)buf; if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) { xfs_error("Leaf directory's data magic number does not match!"); - goto out1; + goto out; } offset = xfs_dir2_dataptr_to_off(fs, be32_to_cpu(lep->address)); @@ -252,26 +257,18 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent, start_name = &dep->name[0]; end_name = start_name + dep->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); ino = be64_to_cpu(dep->inumber); - retval = fill_dirent(fs, dirent, file->offset, ino, name, + retval = fill_dirent(fs, dirent, file->offset, ino, (char *)start_name, end_name - start_name); if (retval) xfs_error("Failed to fill in dirent structure"); - free(name); - free(buf); - free(leaf); - return retval; -out1: - free(buf); - out: - free(leaf); + xfs_dir2_dirblks_flush_cache(); return -1; } @@ -293,11 +290,12 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent, xfs_dir2_data_entry_t *dep; uint8_t *start_name; uint8_t *end_name; - char *name; uint32_t db; - uint8_t *buf = NULL; + const uint8_t *buf = NULL; int retval = 0; + xfs_debug("file %p dirent %p core %p", file, dirent, core); + do { bmbt_irec_get(&irec, (xfs_bmbt_rec_t *)&core->di_literal_area[0] + ++node_off); @@ -305,7 +303,7 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent, fsblkno = fsblock_to_bytes(fs, irec.br_startblock) >> BLOCK_SHIFT(fs); - node = (xfs_da_intnode_t *)xfs_dir2_get_dirblks(fs, fsblkno, 1); + node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(fs, fsblkno, 1); if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { xfs_error("Node's magic number does not match!"); goto out; @@ -314,7 +312,7 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent, try_next_btree: if (!node->hdr.count || XFS_PVT(inode)->i_btree_offset >= be16_to_cpu(node->hdr.count)) - goto out; + goto out; fsblkno = be32_to_cpu(node->btree[XFS_PVT(inode)->i_btree_offset].before); fsblkno = xfs_dir2_get_right_blk(fs, core, fsblkno, &error); @@ -323,17 +321,16 @@ try_next_btree: goto out; } - leaf = (xfs_dir2_leaf_t*)xfs_dir2_get_dirblks(fs, fsblkno, 1); + leaf = (xfs_dir2_leaf_t*)xfs_dir2_dirblks_get_cached(fs, fsblkno, 1); if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) { xfs_error("Leaf's magic number does not match!"); - goto out1; + goto out; } if (!leaf->hdr.count || XFS_PVT(inode)->i_leaf_ent_offset >= be16_to_cpu(leaf->hdr.count)) { XFS_PVT(inode)->i_btree_offset++; XFS_PVT(inode)->i_leaf_ent_offset = 0; - free(leaf); goto try_next_btree; } @@ -347,7 +344,6 @@ try_next_btree: if (XFS_PVT(inode)->i_leaf_ent_offset == be16_to_cpu(leaf->hdr.count)) { XFS_PVT(inode)->i_btree_offset++; XFS_PVT(inode)->i_leaf_ent_offset = 0; - free(leaf); goto try_next_btree; } else { XFS_PVT(inode)->i_leaf_ent_offset++; @@ -358,14 +354,14 @@ try_next_btree: fsblkno = xfs_dir2_get_right_blk(fs, core, db, &error); if (error) { xfs_error("Cannot find data block!"); - goto out1; + goto out; } - buf = xfs_dir2_get_dirblks(fs, fsblkno, 1); + buf = xfs_dir2_dirblks_get_cached(fs, fsblkno, 1); data_hdr = (xfs_dir2_data_hdr_t *)buf; if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) { xfs_error("Leaf directory's data magic No. does not match!"); - goto out2; + goto out; } offset = xfs_dir2_dataptr_to_off(fs, be32_to_cpu(lep->address)); @@ -374,28 +370,16 @@ try_next_btree: start_name = &dep->name[0]; end_name = start_name + dep->namelen; - name = xfs_dir2_get_entry_name(start_name, end_name); - retval = fill_dirent(fs, dirent, 0, be64_to_cpu(dep->inumber), name, - end_name - start_name); + retval = fill_dirent(fs, dirent, 0, be64_to_cpu(dep->inumber), + (char *)start_name, end_name - start_name); if (retval) xfs_error("Failed to fill in dirent structure"); - free(name); - free(buf); - free(leaf); - free(node); - return retval; -out2: - free(buf); - -out1: - free(leaf); - out: - free(node); + xfs_dir2_dirblks_flush_cache(); XFS_PVT(inode)->i_btree_offset = 0; XFS_PVT(inode)->i_leaf_ent_offset = 0; diff --git a/core/include/bios.h b/core/include/bios.h index 9334c41a..7bbd274c 100644 --- a/core/include/bios.h +++ b/core/include/bios.h @@ -20,6 +20,8 @@ #ifndef _BIOS_H #define _BIOS_H +#include <sys/io.h> + /* * Interrupt vectors */ diff --git a/core/include/fs.h b/core/include/fs.h index 554dc97f..560458b6 100644 --- a/core/include/fs.h +++ b/core/include/fs.h @@ -7,6 +7,7 @@ #include <com32.h> #include <stdio.h> #include <sys/dirent.h> +#include <dprintf.h> #include "core.h" #include "disk.h" @@ -158,6 +159,8 @@ static inline void free_inode(struct inode * inode) static inline struct inode *get_inode(struct inode *inode) { inode->refcnt++; + dprintf("get_inode %p name %s refcnt %d\n", + inode, inode->name, inode->refcnt); return inode; } diff --git a/core/init.inc b/core/init.inc index 995f9825..b74cf30b 100644 --- a/core/init.inc +++ b/core/init.inc @@ -47,17 +47,17 @@ common_init: ; ; The code to decompress the PM code and initialize other segments. ; - extern _lzo1x_decompress_asm_fast + extern _lzo1x_decompress_asm_fast_safe section .textnr bits 32 pm_decompress: - push 0 ; Space for decompressed size + push __pm_code_len + 16 ; Space for decompressed size push esp ; Pointer to previous word push __pm_code_start ; Target address push dword [lzo_data_size] ; Compressed size push dword __pm_code_lma - call _lzo1x_decompress_asm_fast + call _lzo1x_decompress_asm_fast_safe add esp,16 pop RM_EAX ; Decompressed size diff --git a/core/isolinux.asm b/core/isolinux.asm index 673134b0..b54beb4a 100644 --- a/core/isolinux.asm +++ b/core/isolinux.asm @@ -433,7 +433,9 @@ MaxLMA equ 384*1024 ; Reasonable limit (384K) .ok: xor bx,bx push bp + push eax call getlinsec + pop eax pop cx mov dx,cx pop bp @@ -441,6 +443,7 @@ MaxLMA equ 384*1024 ; Reasonable limit (384K) shl cx,SECTOR_SHIFT - 4 add bx,cx + add eax,edx sub bp,dx jnz .more diff --git a/core/lzo/enter.ash b/core/lzo/enter.ash index e865c4cb..dc7782fd 100644 --- a/core/lzo/enter.ash +++ b/core/lzo/enter.ash @@ -2,6 +2,9 @@ This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer diff --git a/core/lzo/leave.ash b/core/lzo/leave.ash index f77e2efd..cc48ce6b 100644 --- a/core/lzo/leave.ash +++ b/core/lzo/leave.ash @@ -2,6 +2,9 @@ This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer diff --git a/core/lzo/lzo1c_d.ash b/core/lzo/lzo1c_d.ash index 9969c86a..56622ab5 100644 --- a/core/lzo/lzo1c_d.ash +++ b/core/lzo/lzo1c_d.ash @@ -2,6 +2,9 @@ This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer diff --git a/core/lzo/lzo1f_d.ash b/core/lzo/lzo1f_d.ash index aa9279e0..97a103c0 100644 --- a/core/lzo/lzo1f_d.ash +++ b/core/lzo/lzo1f_d.ash @@ -2,6 +2,9 @@ This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer diff --git a/core/lzo/lzo1x_d.ash b/core/lzo/lzo1x_d.ash index aa138354..782b47fe 100644 --- a/core/lzo/lzo1x_d.ash +++ b/core/lzo/lzo1x_d.ash @@ -2,6 +2,9 @@ This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer diff --git a/core/lzo/lzo1x_f1.S b/core/lzo/lzo1x_f2.S index 8360e34a..8cc26b8b 100644 --- a/core/lzo/lzo1x_f1.S +++ b/core/lzo/lzo1x_f2.S @@ -1,7 +1,10 @@ -/* lzo1x_f1.S -- fast LZO1X decompression in assembler (i386 + gcc) +/* lzo1x_f2.S -- fast LZO1X decompression in assembler (i386 + gcc) This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer @@ -44,17 +47,21 @@ #define LZO_FAST +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + #include "lzo_asm.h" .section ".textnr","ax" - LZO_PUBLIC(lzo1x_decompress_asm_fast) + LZO_PUBLIC(lzo1x_decompress_asm_fast_safe) #include "enter.ash" #include "lzo1x_d.ash" #include "leave.ash" - LZO_PUBLIC_END(lzo1x_decompress_asm_fast) + LZO_PUBLIC_END(lzo1x_decompress_asm_fast_safe) /* diff --git a/core/lzo/lzo_asm.h b/core/lzo/lzo_asm.h index 5e870b85..663ca1a0 100644 --- a/core/lzo/lzo_asm.h +++ b/core/lzo/lzo_asm.h @@ -2,6 +2,9 @@ This file is part of the LZO real-time data compression library. + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer @@ -54,17 +57,17 @@ #else /* manual configuration - see defaults below */ # if defined(__ELF__) -# define MFX_ASM_HAVE_TYPE -# define MFX_ASM_NAME_NO_UNDERSCORES +# define MFX_ASM_HAVE_TYPE 1 +# define MFX_ASM_NAME_NO_UNDERSCORES 1 # elif defined(__linux__) /* Linux a.out */ -# define MFX_ASM_ALIGN_PTWO +# define MFX_ASM_ALIGN_PTWO 1 # elif defined(__DJGPP__) -# define MFX_ASM_ALIGN_PTWO +# define MFX_ASM_ALIGN_PTWO 1 # elif defined(__GO32__) /* djgpp v1 */ -# define MFX_ASM_CANNOT_USE_EBP +# define MFX_ASM_CANNOT_USE_EBP 1 # elif defined(__EMX__) -# define MFX_ASM_ALIGN_PTWO -# define MFX_ASM_CANNOT_USE_EBP +# define MFX_ASM_ALIGN_PTWO 1 +# define MFX_ASM_CANNOT_USE_EBP 1 # endif #endif #endif @@ -125,7 +128,7 @@ ************************************************************************/ #if !defined(MFX_ASM_ALIGN_BYTES) && !defined(MFX_ASM_ALIGN_PTWO) -# define MFX_ASM_ALIGN_BYTES +# define MFX_ASM_ALIGN_BYTES 1 #endif #if !defined(LZO_ASM_ALIGN) @@ -147,10 +150,10 @@ #if !defined(MFX_ASM_CANNOT_USE_EBP) # if 1 && !defined(N_3_EBP) && !defined(N_255_EBP) -# define N_3_EBP +# define N_3_EBP 1 # endif # if 0 && !defined(N_3_EBP) && !defined(N_255_EBP) -# define N_255_EBP +# define N_255_EBP 1 # endif #endif diff --git a/core/mem/malloc.c b/core/mem/malloc.c index a3d6b45d..c439dcbb 100644 --- a/core/mem/malloc.c +++ b/core/mem/malloc.c @@ -175,6 +175,8 @@ void *bios_realloc(void *ptr, size_t size) ARENA_TYPE_SET(nah->a.attrs, ARENA_TYPE_FREE); ARENA_SIZE_SET(nah->a.attrs, xsize - newsize); ARENA_SIZE_SET(ah->a.attrs, newsize); + ARENA_HEAP_SET(nah->a.attrs, ARENA_HEAP_GET(ah->a.attrs)); + //nah->a.type = ARENA_TYPE_FREE; //nah->a.size = xsize - newsize; //ah->a.size = newsize; diff --git a/core/pxelinux.asm b/core/pxelinux.asm index 95f76617..841f69f5 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -289,10 +289,12 @@ KernelType resb 1 ; Kernel type, from vkernel, if known global KernelName KernelName resb FILENAME_MAX ; Mangled name for kernel section .data16 - extern IPOption + extern IPOption, BOOTIFStr, SYSUUIDStr global IPAppends, numIPAppends alignz 2 IPAppends dw IPOption + dw BOOTIFStr + dw SYSUUIDStr numIPAppends equ ($-IPAppends)/2 section .text16 |
