[syslinux] [PATCH 05/12] core: modify disk cache to work with multidisk
Andre Ericson
de.ericson at gmail.com
Mon Aug 20 01:16:47 PDT 2012
Disk cache was modified to work with multidisk. Now fopen with
different disks/partitions should be fully working.
Signed-off-by: Andre Ericson <de.ericson at gmail.com>
Signed-off-by: Paulo Alcantara <pcacjr at zytor.com>
---
com32/modules/fopen_test.c | 34 +++++++++++++--------
core/fs/chdir.c | 44 +--------------------------
core/fs/diskio.c | 68 ++++++++++++++++++++++++++----------------
core/fs/fs.c | 74 +++++++++++++++++++++++-----------------------
core/include/multidisk.h | 1 -
core/multidisk.c | 5 ----
6 files changed, 103 insertions(+), 123 deletions(-)
diff --git a/com32/modules/fopen_test.c b/com32/modules/fopen_test.c
index a6a2ec1..37d98cd 100644
--- a/com32/modules/fopen_test.c
+++ b/com32/modules/fopen_test.c
@@ -4,27 +4,37 @@
* Created on: Jun 30, 2012
* Author: Andre Ericson <de.ericson at gmail.com>
*/
-
#include <stdio.h>
#include <stdlib.h>
#define FILENAME "(0 2):/andre/hello_mate"
+/* should have this syntax: (hd part):/path/to/file */
+const char *paths [] = {
+ "(0 2):/andre/fat_info",
+ "(0 3):/andre/ntfs_info",
+ NULL
+};
+
int main(int argc __unused, char **argv __unused)
{
- /* should have this syntax: (hd part):/path/to/file */
- FILE *f = fopen(FILENAME, "rt");
+ FILE *f;
char buff[50];
- int i = 0;
+ int i;
+ const char **c;
- if (!f)
- printf("File not found.\n"
- "For multidisk files use (hd part):/path/to/file\n");
- else {
- while ((buff[i++] = fgetc(f)) && i < 50);
- buff[i < 49 ?i : 49] = '\0';
+ for (c = paths; *c; c++) {
+ f = fopen(*c, "rt");
+ i = 0;
+ printf("Reading file: %s, content:\n", *c);
+ if (!f)
+ printf("File not found.\n"
+ "For multidisk files use (hd part):/path/to/file\n");
+ else {
+ while ((buff[i++] = fgetc(f)) && i < 50);
+ buff[i < 49 ? i : 49] = '\0';
- printf("read %s\n", buff);
+ printf("read: %s\n", buff);
+ }
}
-
return 0;
}
diff --git a/core/fs/chdir.c b/core/fs/chdir.c
index e42f0dd..96c19e0 100644
--- a/core/fs/chdir.c
+++ b/core/fs/chdir.c
@@ -85,49 +85,7 @@ size_t realpath(char *dst, const char *src, size_t bufsize)
int chdir(const char *src)
{
- int rv;
- struct file *file;
- char cwd_buf[CURRENTDIR_MAX];
- size_t s;
-
- dprintf("chdir: from %s (inode %p) add %s\n",
- this_fs->cwd_name, this_fs->cwd, src);
-
- if (this_fs->fs_ops->chdir)
- return this_fs->fs_ops->chdir(this_fs, src);
-
- /* Otherwise it is a "conventional filesystem" */
- rv = searchdir(src, NULL);
- if (rv < 0)
- return rv;
-
- file = handle_to_file(rv);
- if (file->inode->mode != DT_DIR) {
- _close_file(file);
- return -1;
- }
-
- put_inode(this_fs->cwd);
- this_fs->cwd = get_inode(file->inode);
- _close_file(file);
-
- /* Save the current working directory */
- s = generic_inode_to_path(this_fs->cwd, cwd_buf, CURRENTDIR_MAX-1);
-
- /* Make sure the cwd_name ends in a slash, it's supposed to be a prefix */
- if (s < 1 || cwd_buf[s-1] != '/')
- cwd_buf[s++] = '/';
-
- if (s >= CURRENTDIR_MAX)
- s = CURRENTDIR_MAX - 1;
-
- cwd_buf[s++] = '\0';
- memcpy(this_fs->cwd_name, cwd_buf, s);
-
- dprintf("chdir: final %s (inode %p)\n",
- this_fs->cwd_name, this_fs->cwd);
-
- return 0;
+ return multidisk_chdir(src, this_fs);
}
/* won't merge this and chdir(const char*) to not break compatibility
diff --git a/core/fs/diskio.c b/core/fs/diskio.c
index 6683816..81e8d9d 100644
--- a/core/fs/diskio.c
+++ b/core/fs/diskio.c
@@ -302,13 +302,17 @@ struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start,
uint16_t bsHeads, uint16_t bsSecPerTrack,
uint32_t MaxTransfer)
{
- static struct disk disk;
+ struct disk *disk;
static __lowmem struct edd_disk_params edd_params;
com32sys_t ireg, oreg;
bool ebios;
int sector_size;
unsigned int hard_max_transfer;
+ disk = malloc(sizeof(struct disk));
+ if (!disk)
+ return NULL;
+
memset(&ireg, 0, sizeof ireg);
ireg.edx.b[0] = devno;
@@ -326,8 +330,8 @@ struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start,
hard_max_transfer = 63;
/* CBIOS parameters */
- disk.h = bsHeads;
- disk.s = bsSecPerTrack;
+ disk->h = bsHeads;
+ disk->s = bsSecPerTrack;
if ((int8_t)devno < 0) {
/* Get hard disk geometry from BIOS */
@@ -336,8 +340,8 @@ struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start,
__intcall(0x13, &ireg, &oreg);
if (!(oreg.eflags.l & EFLAGS_CF)) {
- disk.h = oreg.edx.b[1] + 1;
- disk.s = oreg.ecx.b[0] & 63;
+ disk->h = oreg.edx.b[1] + 1;
+ disk->s = oreg.ecx.b[0] & 63;
}
}
@@ -356,7 +360,7 @@ struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start,
/* Query EBIOS parameters */
/* The memset() is needed once this function can be called
more than once */
- /* memset(&edd_params, 0, sizeof edd_params); */
+ memset(&edd_params, 0, sizeof edd_params);
edd_params.len = sizeof edd_params;
ireg.eax.b[1] = 0x48;
@@ -377,43 +381,57 @@ struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start,
}
- disk.disk_number = devno;
- disk.sector_size = sector_size;
- disk.sector_shift = ilog2(sector_size);
- disk.part_start = part_start;
- disk.secpercyl = disk.h * disk.s;
- disk.rdwr_sectors = ebios ? edd_rdwr_sectors : chs_rdwr_sectors;
+ disk->disk_number = devno;
+ disk->sector_size = sector_size;
+ disk->sector_shift = ilog2(sector_size);
+ disk->part_start = part_start;
+ disk->secpercyl = disk->h * disk->s;
+ disk->rdwr_sectors = ebios ? edd_rdwr_sectors : chs_rdwr_sectors;
if (!MaxTransfer || MaxTransfer > hard_max_transfer)
MaxTransfer = hard_max_transfer;
- disk.maxtransfer = MaxTransfer;
+ disk->maxtransfer = MaxTransfer;
dprintf("disk %02x cdrom %d type %d sector %u/%u offset %llu limit %u\n",
- devno, cdrom, ebios, sector_size, disk.sector_shift,
- part_start, disk.maxtransfer);
+ devno, cdrom, ebios, sector_size, disk->sector_shift,
+ part_start, disk->maxtransfer);
- return &disk;
+ return disk;
}
/*
* Initialize the device structure.
- *
- * NOTE: the disk cache needs to be revamped to support multiple devices...
*/
struct device * device_init(uint8_t devno, bool cdrom, sector_t part_start,
uint16_t bsHeads, uint16_t bsSecPerTrack,
uint32_t MaxTransfer)
{
- static struct device dev;
- static __hugebss char diskcache[128*1024];
+ struct device *dev;
+ char *diskcache;
+ int cachesize = 128 * 1024;
+
+ dev = malloc(sizeof(struct device));
+ if (!dev)
+ goto bail;
+
+ diskcache = malloc(cachesize);
+ if (!diskcache)
+ goto bail;
+
+ memset(diskcache, 0, cachesize);
+
+ dev->disk = disk_init(devno, cdrom, part_start,
+ bsHeads, bsSecPerTrack, MaxTransfer);
- dev.disk = disk_init(devno, cdrom, part_start,
- bsHeads, bsSecPerTrack, MaxTransfer);
+ dev->cache_data = diskcache;
+ dev->cache_size = cachesize;
- dev.cache_data = diskcache;
- dev.cache_size = sizeof diskcache;
+ return dev;
- return &dev;
+bail:
+ free(dev);
+ free(diskcache);
+ return NULL;
}
diff --git a/core/fs/fs.c b/core/fs/fs.c
index 225df05..0834d97 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -36,6 +36,19 @@ struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data)
return inode;
}
+extern const struct fs_ops vfat_fs_ops;
+extern const struct fs_ops ext2_fs_ops;
+extern const struct fs_ops btrfs_fs_ops;
+extern const struct fs_ops ntfs_fs_ops;
+
+const struct fs_ops *fs_ops_array [4] = {
+ &vfat_fs_ops,
+ &ext2_fs_ops,
+ /* TODO: add btrfs */
+ &ntfs_fs_ops,
+ NULL
+};
+
/*
* Free a refcounted inode
*/
@@ -204,29 +217,13 @@ size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors)
return bytes_read;
}
-extern const struct fs_ops vfat_fs_ops;
-extern const struct fs_ops ext2_fs_ops;
-extern const struct fs_ops btrfs_fs_ops;
-extern const struct fs_ops ntfs_fs_ops;
-
-const struct fs_ops *fs_ops_array [4] = {
- &vfat_fs_ops,
- &ext2_fs_ops,
- /* TODO: add btrfs */
- /*&btrfs_fs_ops,*/
- NULL,
- NULL
-};
-
struct fs_info *get_fs_info(uint8_t hdd, uint8_t partition)
{
struct fs_info *fsp;
- struct fs_info fs;
uint8_t disk_devno, disk_cdrom;
sector_t disk_offset;
uint16_t disk_heads, disk_sectors, maxtransfer;
struct part_iter *iter = NULL;
- uint8_t buff[512];
struct disk_info diskinfo;
const struct fs_ops **ops;
int blk_shift = -1;
@@ -236,16 +233,16 @@ struct fs_info *get_fs_info(uint8_t hdd, uint8_t partition)
if (fsp)
return fsp;
+ fsp = malloc(sizeof(struct fs_info));
+ if (!fsp)
+ return NULL;
+
disk_devno = 0x80 + hdd;
- /* For some unknown reason without this call to a "nop" function
- * an infinite loop happens, must investigate later
- * TODO: fix this */
- do_magic(buff);
if (find_partition(&iter, disk_devno, partition)) {
printf("Failed to get partition\n");
- return NULL;
+ goto bail;
}
else
dprintf("part_offset 0x%llx\n", iter->start_lba);
@@ -253,7 +250,7 @@ struct fs_info *get_fs_info(uint8_t hdd, uint8_t partition)
disk_offset = iter->start_lba;
if (disk_get_params(disk_devno, &diskinfo))
- return NULL;
+ goto bail;
disk_heads = diskinfo.head;
disk_sectors = diskinfo.spt;
@@ -267,26 +264,26 @@ struct fs_info *get_fs_info(uint8_t hdd, uint8_t partition)
/* Default name for the root directory */
- fs.cwd_name[0] = '/';
+ fsp->cwd_name[0] = '/';
while ((blk_shift < 0) && *ops) {
/* set up the fs stucture */
- fs.fs_ops = *ops;
+ fsp->fs_ops = *ops;
/*
* This boldly assumes that we don't mix FS_NODEV filesystems
* with FS_DEV filesystems...
*/
- if (fs.fs_ops->fs_flags & FS_NODEV) {
- fs.fs_dev = NULL;
+ if (fsp->fs_ops->fs_flags & FS_NODEV) {
+ fsp->fs_dev = NULL;
} else {
if (!dev)
dev = device_init(disk_devno, disk_cdrom, disk_offset,
disk_heads, disk_sectors, maxtransfer);
- fs.fs_dev = dev;
+ fsp->fs_dev = dev;
}
/* invoke the fs-specific init code */
- blk_shift = fs.fs_ops->fs_init(&fs);
+ blk_shift = fsp->fs_ops->fs_init(fsp);
ops++;
}
if (blk_shift < 0) {
@@ -294,24 +291,27 @@ struct fs_info *get_fs_info(uint8_t hdd, uint8_t partition)
while (1)
;
}
- add_fs(&fs, hdd, partition - 1);
- fsp = &fs;
+ add_fs(fsp, hdd, partition - 1);
/* initialize the cache */
- if (fs.fs_dev && fs.fs_dev->cache_data)
- cache_init(fs.fs_dev, blk_shift);
+ if (fsp->fs_dev && fsp->fs_dev->cache_data)
+ cache_init(fsp->fs_dev, blk_shift);
/* start out in the root directory */
- if (fs.fs_ops->iget_root) {
- fs.root = fs.fs_ops->iget_root(&fs);
- fs.cwd = get_inode(fs.root);
+ if (fsp->fs_ops->iget_root) {
+ fsp->root = fsp->fs_ops->iget_root(fsp);
+ fsp->cwd = get_inode(fsp->root);
}
- if (fs.fs_ops->chdir_start) {
- if (fs.fs_ops->chdir_start(fsp) < 0)
+ if (fsp->fs_ops->chdir_start) {
+ if (fsp->fs_ops->chdir_start(fsp) < 0)
printf("Failed to chdir to start directory\n");
}
return fsp;
+
+bail:
+ free(fsp);
+ return NULL;
}
diff --git a/core/include/multidisk.h b/core/include/multidisk.h
index ccf4ad0..fc5995b 100644
--- a/core/include/multidisk.h
+++ b/core/include/multidisk.h
@@ -2,7 +2,6 @@
#define MULTIDISK_H
#include "partiter.h"
-void do_magic(void *);
int find_partition(struct part_iter **_iter, int drive, int partition);
int add_fs(struct fs_info *fs, uint8_t disk, uint8_t partition);
struct fs_info *get_fs(uint8_t disk, uint8_t partition);
diff --git a/core/multidisk.c b/core/multidisk.c
index bcc24bc..78b751c 100644
--- a/core/multidisk.c
+++ b/core/multidisk.c
@@ -75,11 +75,6 @@ struct fs_info *get_fs(uint8_t disk, uint8_t partition)
return NULL;
}
-void do_magic(void *buff)
-{
-
-}
-
int find_partition(struct part_iter **_iter, int drive, int partition)
{
struct part_iter *iter = NULL;
--
1.7.11.3
More information about the Syslinux
mailing list