[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