[syslinux:fsc] core/fs: abstract filesystem, use cache for ext2 group descriptors

syslinux-bot for H. Peter Anvin hpa at zytor.com
Mon Jan 25 14:57:09 PST 2010


Commit-ID:  413a70918e18bcdf1922583ed7a1c79ccbe4a4b7
Gitweb:     http://syslinux.zytor.com/commit/413a70918e18bcdf1922583ed7a1c79ccbe4a4b7
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Mon, 25 Jan 2010 14:53:32 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Mon, 25 Jan 2010 14:53:32 -0800

core/fs: abstract filesystem, use cache for ext2 group descriptors

Abstract out the filesystem, remove all references to "this_fs" in the
main filesystem drivers. There is still some in the core (dir.c, fs.c)
which eventually need to be replaced by a properly defined device
marker and root.

The inode structure now contains a reference to its parent filesystem.

The inode structure can now contain additional data at the end of the
structure, this is used for filesystem private data.

TODO: move the filesystem private data into proper structures.

Finally, use the block cache for ext2 block group descriptors.  Trying
to allocate them all at filesystem mount time doesn't work for large
filesystems.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/dir.c                |    6 +--
 core/fs.c                 |   17 +++++-
 core/fs/ext2/bmap.c       |   10 ++--
 core/fs/ext2/ext2.c       |  125 +++++++++++++++++++--------------------------
 core/fs/ext2/ext2_fs.h    |    8 +---
 core/fs/fat/fat.c         |   48 +++++++----------
 core/fs/iso9660/iso9660.c |   69 ++++++++++---------------
 core/include/core.h       |    3 +-
 core/include/fs.h         |   17 +++---
 core/malloc.c             |   10 +++-
 10 files changed, 142 insertions(+), 171 deletions(-)

diff --git a/core/dir.c b/core/dir.c
index 37d92ed..4013280 100644
--- a/core/dir.c
+++ b/core/dir.c
@@ -1,10 +1,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/dirent.h>
-#include <fs.h>
-#include <core.h>
-
-extern struct fs_info *this_fs;
+#include "fs.h"
+#include "core.h"
 
 /* 
  * open dir, return the file structure pointer in _eax_, or NULL if failed 
diff --git a/core/fs.c b/core/fs.c
index 3780881..3d6652d 100644
--- a/core/fs.c
+++ b/core/fs.c
@@ -13,6 +13,19 @@ struct inode *this_inode = NULL;
 struct file files[MAX_OPEN];
 
 /*
+ * Get a new inode structure
+ */
+struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data)
+{
+    struct inode *inode = zalloc(sizeof(struct inode) + data);
+    if (inode) {
+	inode->fs = fs;
+	inode->ino = ino;
+    }
+    return inode;
+}
+
+/*
  * Get an empty file structure
  */
 static struct file *alloc_file(void)
@@ -152,7 +165,7 @@ void searchdir(com32sys_t *regs)
 
     /* else, try the generic-path-lookup method */
     if (*name == '/') {
-	inode = this_fs->fs_ops->iget_root();
+	inode = this_fs->fs_ops->iget_root(this_fs);
 	while(*name == '/')
 	    name++;
     } else {
@@ -280,5 +293,5 @@ void fs_init(com32sys_t *regs)
         cache_init(fs.fs_dev, blk_shift);
 
     if (fs.fs_ops->iget_current)
-	this_inode = fs.fs_ops->iget_current();
+	this_inode = fs.fs_ops->iget_current(&fs);
 }
diff --git a/core/fs/ext2/bmap.c b/core/fs/ext2/bmap.c
index e38bcd2..e4698d0 100644
--- a/core/fs/ext2/bmap.c
+++ b/core/fs/ext2/bmap.c
@@ -51,7 +51,7 @@ static uint64_t bmap_extent(struct fs_info *fs,
     int i;
     block_t start;
     
-    leaf = ext4_find_leaf(fs, (struct ext4_extent_header *)inode->data, block);
+    leaf = ext4_find_leaf(fs, (struct ext4_extent_header *)inode->pvt, block);
     if (!leaf) {
 	printf("ERROR, extent leaf not found\n");
 	return 0;
@@ -95,12 +95,12 @@ static unsigned int bmap_traditional(struct fs_info *fs,
     
     /* direct blocks */
     if (block < direct_blocks)
-	return inode->data[block];
+	return ((uint32_t *)inode->pvt)[block];
     
     /* indirect blocks */
     block -= direct_blocks;
     if (block < indirect_blocks) {
-	block_t ind_block = inode->data[EXT2_IND_BLOCK];
+	block_t ind_block = ((uint32_t *)inode->pvt)[EXT2_IND_BLOCK];
         
 	if (!ind_block)
 	    return 0;
@@ -113,7 +113,7 @@ static unsigned int bmap_traditional(struct fs_info *fs,
     /* double indirect blocks */
     block -= indirect_blocks;
     if (block < double_blocks) {
-	block_t dou_block = inode->data[EXT2_DIND_BLOCK];
+	block_t dou_block = ((uint32_t *)inode->pvt)[EXT2_DIND_BLOCK];
         
 	if (!dou_block)
 	    return 0;                
@@ -131,7 +131,7 @@ static unsigned int bmap_traditional(struct fs_info *fs,
     /* triple indirect block */
     block -= double_blocks;
     if (block < triple_blocks) {
-	block_t tri_block = inode->data[EXT2_TIND_BLOCK];
+	block_t tri_block = ((uint32_t *)inode->pvt)[EXT2_TIND_BLOCK];
         
 	if (!tri_block)
 	    return 0;
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
index 01f32f8..b8c4e10 100644
--- a/core/fs/ext2/ext2.c
+++ b/core/fs/ext2/ext2.c
@@ -34,10 +34,14 @@ static void ext2_close_file(struct file *file)
 /*
  * get the group's descriptor of group_num
  */
-struct ext2_group_desc * ext2_get_group_desc(uint32_t group_num)
+struct ext2_group_desc * ext2_get_group_desc(struct fs_info *fs,
+					     uint32_t group_num)
 {
-    struct ext2_sb_info *sbi = EXT2_SB(this_fs);
-    
+    struct ext2_sb_info *sbi = EXT2_SB(fs);
+    uint32_t desc_block, desc_index;
+    struct ext2_group_desc *desc_data_block;
+    struct cache_struct *cs;
+
     if (group_num >= sbi->s_groups_count) {
 	printf ("ext2_get_group_desc"
 		"block_group >= groups_count - "
@@ -46,8 +50,16 @@ struct ext2_group_desc * ext2_get_group_desc(uint32_t group_num)
 	
 	return NULL;
     }        
-    
-    return sbi->s_group_desc[group_num];
+ 
+    desc_block = group_num / sbi->s_desc_per_block;
+    desc_index = group_num % sbi->s_desc_per_block;
+   
+    desc_block += sbi->s_first_data_block + 1;
+
+    cs = get_cache_block(fs->fs_dev, desc_block);
+    desc_data_block = cs->data;
+
+    return &desc_data_block[desc_index];
 }
 
 
@@ -64,10 +76,9 @@ struct ext2_group_desc * ext2_get_group_desc(uint32_t group_num)
  * 
  * @return: physic sector number
  */
-static sector_t linsector(struct fs_info *fs, 
-			  struct inode *inode, 
-			  uint32_t lin_sector)
+static sector_t linsector(struct inode *inode, uint32_t lin_sector)
 {
+    struct fs_info *fs = inode->fs;
     int blk_bits = fs->block_shift - fs->sector_shift;
     block_t block = bmap(fs, inode, lin_sector >> blk_bits);
     
@@ -129,7 +140,7 @@ static uint32_t ext2_getfssec(struct file *file, char *buf,
         /*
          * get the frament
          */
-	next_sector = frag_start = linsector(fs, inode, sector_idx);
+	next_sector = frag_start = linsector(inode, sector_idx);
         con_sec_cnt = 0;                
         
         /* get the consective sectors count */
@@ -143,9 +154,9 @@ static uint32_t ext2_getfssec(struct file *file, char *buf,
             if (sectors >= (((~(uint32_t)buf&0xffff)|((uint32_t)buf&0xffff0000)) + 1))
                 break;
             
-            sector_idx ++;
-            next_sector ++;
-        } while (next_sector == linsector(fs, inode, sector_idx));                
+            sector_idx++;
+            next_sector++;
+        } while (next_sector == linsector(inode, sector_idx));                
         
 #if 0  
         printf("You are reading data stored at sector --0x%x--0x%x\n", 
@@ -225,7 +236,7 @@ ext2_find_entry(struct fs_info *fs, struct inode *inode, char *dname)
     return NULL;
 }
 
-static struct ext2_inode * get_inode(int inr)
+static struct ext2_inode * get_inode(struct fs_info *fs, int inr)
 {
     struct ext2_group_desc *desc;
     struct cache_struct *cs;
@@ -233,19 +244,19 @@ static struct ext2_inode * get_inode(int inr)
     uint32_t block_num, block_off;
     
     inr--;
-    inode_group  = inr / EXT2_INODES_PER_GROUP(this_fs);
-    inode_offset = inr % EXT2_INODES_PER_GROUP(this_fs);
-    desc = ext2_get_group_desc (inode_group);
+    inode_group  = inr / EXT2_INODES_PER_GROUP(fs);
+    inode_offset = inr % EXT2_INODES_PER_GROUP(fs);
+    desc = ext2_get_group_desc(fs, inode_group);
     if (!desc)
 	return NULL;
     
     block_num = desc->bg_inode_table + 
-	inode_offset / EXT2_INODES_PER_BLOCK(this_fs);
-    block_off = inode_offset % EXT2_INODES_PER_BLOCK(this_fs);
-    
-    cs = get_cache_block(this_fs->fs_dev, block_num);
+	inode_offset / EXT2_INODES_PER_BLOCK(fs);
+    block_off = inode_offset % EXT2_INODES_PER_BLOCK(fs);
     
-    return cs->data + block_off * EXT2_SB(this_fs)->s_inode_size;
+    cs = get_cache_block(fs->fs_dev, block_num);
+
+    return cs->data + block_off * EXT2_SB(fs)->s_inode_size;
 }
 
 static inline int get_inode_mode(int mode)
@@ -261,7 +272,7 @@ static inline int get_inode_mode(int mode)
 }
 
 static void fill_inode(struct inode *inode, struct ext2_inode *e_inode)
-{     
+{
     inode->mode    = get_inode_mode(e_inode->i_mode);
     inode->size    = e_inode->i_size;
     inode->atime   = e_inode->i_atime;
@@ -271,78 +282,73 @@ static void fill_inode(struct inode *inode, struct ext2_inode *e_inode)
     inode->blocks  = e_inode->i_blocks;
     inode->flags   = e_inode->i_flags;
     inode->file_acl = e_inode->i_file_acl;
-    
-    inode->data = malloc(EXT2_N_BLOCKS * sizeof(uint32_t *));
-    if (!inode->data) {
-	malloc_error("inode data filed");
-	return ;
-    }
-    memcpy(inode->data, e_inode->i_block, EXT2_N_BLOCKS * sizeof(uint32_t *));
+    memcpy(inode->pvt, e_inode->i_block, EXT2_N_BLOCKS * sizeof(uint32_t *));
 }
 
-static struct inode *ext2_iget_by_inr(uint32_t inr)
+static struct inode *ext2_iget_by_inr(struct fs_info *fs, uint32_t inr)
 {
         struct ext2_inode *e_inode;
         struct inode *inode;
 
-        e_inode = get_inode(inr);
-        if (!(inode = malloc(sizeof(*inode))))
+        e_inode = get_inode(fs, inr);
+        if (!(inode = alloc_inode(fs, inr, EXT2_N_BLOCKS*sizeof(uint32_t *))))
 	    return NULL;
         fill_inode(inode, e_inode);
-        inode->ino = inr;
 	
         return inode;
 }
 
-static struct inode *ext2_iget_root()
+static struct inode *ext2_iget_root(struct fs_info *fs)
 {
-        return ext2_iget_by_inr(EXT2_ROOT_INO);
+    return ext2_iget_by_inr(fs, EXT2_ROOT_INO);
 }
 
-static struct inode *ext2_iget_current()
+static struct inode *ext2_iget_current(struct fs_info *fs)
 {
     extern int CurrentDir;
     
-    return ext2_iget_by_inr(CurrentDir);
+    return ext2_iget_by_inr(fs, CurrentDir);
 }
 
 static struct inode *ext2_iget(char *dname, struct inode *parent)
 {
         struct ext2_dir_entry *de;
+	struct fs_info *fs = parent->fs;
         
-        de = ext2_find_entry(this_fs, parent, dname);
+        de = ext2_find_entry(fs, parent, dname);
         if (!de)
                 return NULL;
         
-        return ext2_iget_by_inr(de->d_inode);
+        return ext2_iget_by_inr(fs, de->d_inode);
 }
 
 
 static char * ext2_follow_symlink(struct inode *inode, const char *name_left)
 {
-    int sec_per_block = 1 << (this_fs->block_shift - this_fs->sector_shift);
+    struct fs_info *fs = inode->fs;
+    int sec_per_block = 1 << (fs->block_shift - fs->sector_shift);
     int fast_symlink;
     char *symlink_buf;
     char *p;
     struct cache_struct *cs;
     
-    symlink_buf = malloc(BLOCK_SIZE(this_fs));
+    symlink_buf = malloc(BLOCK_SIZE(fs));
     if (!symlink_buf) {
 	malloc_error("symlink buffer");
 	return NULL;
     }
     fast_symlink = (inode->file_acl ? sec_per_block : 0) == inode->blocks;
     if (fast_symlink) {
-	memcpy(symlink_buf, inode->data, inode->size);
+	memcpy(symlink_buf, inode->pvt, inode->size);
     } else {
-	cs = get_cache_block(this_fs->fs_dev, *(uint32_t *)inode->data);
+	cs = get_cache_block(fs->fs_dev, *(uint32_t *)inode->pvt);
 	memcpy(symlink_buf, cs->data, inode->size);
     }
     p = symlink_buf + inode->size;
     
     if (*name_left)
 	*p++ = '/';
-    if (strecpy(p, name_left, symlink_buf + BLOCK_SIZE(this_fs))) {
+    if (strecpy(p, name_left, symlink_buf + BLOCK_SIZE(fs))) {
 	free(symlink_buf);
 	return NULL;
     }
@@ -412,11 +418,6 @@ static int ext2_fs_init(struct fs_info *fs)
     struct disk *disk = fs->fs_dev->disk;
     struct ext2_sb_info *sbi;
     struct ext2_super_block sb;
-    int blk_bits;
-    int db_count;
-    int i;
-    int desc_block;
-    char *desc_buffer;
     
     /* read the super block */
     disk->rdwr_sectors(disk, &sb, 2, 2, 0);
@@ -451,31 +452,9 @@ static int ext2_fs_init(struct fs_info *fs)
     sbi->s_groups_count     = (sb.s_blocks_count - sb.s_first_data_block 
 			       + EXT2_BLOCKS_PER_GROUP(fs) - 1) 
 	                      / EXT2_BLOCKS_PER_GROUP(fs);
-    db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
-	        EXT2_DESC_PER_BLOCK(fs);
+    sbi->s_first_data_block = sb.s_first_data_block;
     sbi->s_inode_size = sb.s_inode_size;
-    
-    /* read the descpritors */
-    desc_block = sb.s_first_data_block + 1;
-    desc_buffer = malloc(db_count * BLOCK_SIZE(fs));
-    if (!desc_buffer) {
-	malloc_error("desc_buffer");
-	return -1;
-    }    
-    blk_bits = fs->block_shift - fs->sector_shift;
-    disk->rdwr_sectors(disk, desc_buffer, desc_block << blk_bits, 
-		       db_count << blk_bits, 0);
-    sbi->s_group_desc = malloc(sizeof(struct ext2_group_desc *) 
-			       * sbi->s_groups_count);
-    if (!sbi->s_group_desc) {
-	malloc_error("sbi->s_group_desc");
-	return -1;
-    }
-    for (i = 0; i < (int)sbi->s_groups_count; i++) {
-	sbi->s_group_desc[i] = (struct ext2_group_desc *)desc_buffer;
-	desc_buffer += sb.s_desc_size;
-    }
-    
+
     return fs->block_shift;
 }
 
diff --git a/core/fs/ext2/ext2_fs.h b/core/fs/ext2/ext2_fs.h
index 0249ee1..b74038e 100644
--- a/core/fs/ext2/ext2_fs.h
+++ b/core/fs/ext2/ext2_fs.h
@@ -275,14 +275,8 @@ struct ext2_sb_info {
     uint32_t s_blocks_per_group;/* Number of blocks in a group */
     uint32_t s_desc_per_block;  /* Number of group descriptors per block */
     uint32_t s_groups_count;    /* Number of groups in the fs */
+    uint32_t s_first_data_block;	/* First Data Block */
     int      s_inode_size;
-    
-    /* 
-     * Here did not like Linux Kernel did; the group descriptor cache
-     * here is based on ext2_group_desc structure, instead of buffer
-     * head structure in Linux Kernel, where cache one block data.
-     */
-    struct ext2_group_desc ** s_group_desc;
 };
 
 static inline struct ext2_sb_info *EXT2_SB(struct fs_info *fs)
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index 405e43a..db72bd2 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -7,22 +7,11 @@
 #include <fs.h>
 #include "fat_fs.h"
 
-
-static struct inode * new_fat_inode(void)
+static struct inode * new_fat_inode(struct fs_info *fs)
 {
-    struct inode *inode = malloc(sizeof(*inode));
-    if (!inode) 
+    struct inode *inode = alloc_inode(fs, 0, sizeof(sector_t));
+    if (!inode)
 	malloc_error("inode structure");		
-    memset(inode, 0, sizeof(*inode));
-    
-    /* 
-     * We just need allocate one uint32_t data to store the 
-     * first cluster number.
-     */
-    inode->data = malloc(sizeof(uint32_t));
-    if (!inode->data) 
-	malloc_error("inode->data");
-    
     return inode;
 }
 
@@ -143,7 +132,7 @@ static sector_t get_the_right_sector(struct file *file)
 {
     int i = 0;
     int sector_pos  = file->offset >> SECTOR_SHIFT(file->fs);
-    sector_t sector = *file->inode->data;
+    sector_t sector = *(sector_t *)file->inode->pvt;
     
     for (; i < sector_pos; i++) 
 	sector = get_next_sector(file->fs, sector);
@@ -369,9 +358,10 @@ static uint8_t get_checksum(char *dir_name)
 
 
 /* compute the first sector number of one dir where the data stores */
-static inline sector_t first_sector(struct fat_dir_entry *dir)
+static inline sector_t first_sector(struct fs_info *fs,
+				    struct fat_dir_entry *dir)
 {
-    struct fat_sb_info *sbi = FAT_SB(this_fs);
+    struct fat_sb_info *sbi = FAT_SB(fs);
     uint32_t first_clust;
     sector_t sector;
     
@@ -392,13 +382,14 @@ static inline int get_inode_mode(uint8_t attr)
  
 static struct inode *vfat_find_entry(char *dname, struct inode *dir)
 {
-    struct inode *inode = new_fat_inode();
+    struct fs_info *fs = dir->fs;
+    struct inode *inode = new_fat_inode(fs);
     struct fat_dir_entry *de;
     struct fat_long_name_entry *long_de;
     struct cache_struct *cs;
     
     char mangled_name[12] = {0, };
-    sector_t dir_sector = *dir->data;
+    sector_t dir_sector = *(sector_t *)dir->pvt;
     
     uint8_t vfat_init, vfat_next, vfat_csum = 0;
     uint8_t id;
@@ -412,9 +403,9 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir)
     vfat_init = vfat_next = slots;
     
     while (1) {
-	cs = get_cache_block(this_fs->fs_dev, dir_sector);
+	cs = get_cache_block(fs->fs_dev, dir_sector);
 	de = (struct fat_dir_entry *)cs->data;
-	entries = 1 << (this_fs->sector_shift - 5);
+	entries = 1 << (fs->sector_shift - 5);
 	
 	while(entries--) {
 	    if (de->name[0] == 0)
@@ -495,26 +486,26 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir)
 	}
 	
 	/* Try with the next sector */
-	dir_sector = get_next_sector(this_fs, dir_sector);
+	dir_sector = get_next_sector(fs, dir_sector);
 	if (!dir_sector)
 	    return NULL;
     }
     
 found:
     inode->size = de->file_size;
-    *inode->data = first_sector(de);
+    *(sector_t *)inode->pvt = first_sector(fs, de);
     inode->mode = get_inode_mode(de->attr);
     
     return inode;
 }
 
-static struct inode *vfat_iget_root(void)
+static struct inode *vfat_iget_root(struct fs_info *fs)
 {
-    struct inode *inode = new_fat_inode();
-    int root_size = FAT_SB(this_fs)->root_size;
+    struct inode *inode = new_fat_inode(fs);
+    int root_size = FAT_SB(fs)->root_size;
     
-    inode->size = root_size << this_fs->sector_shift;
-    *inode->data = FAT_SB(this_fs)->root;
+    inode->size = root_size << fs->sector_shift;
+    *(sector_t *)inode->pvt = FAT_SB(fs)->root;
     inode->mode = I_DIR;
     
     return inode;
@@ -721,7 +712,6 @@ static int vfat_fs_init(struct fs_info *fs)
     if (!sbi)
 	malloc_error("fat_sb_info structure");
     fs->fs_info = sbi;
-    this_fs = fs;
     
     sectors_per_fat = fat.bxFATsecs ? : fat.fat32.bxFATsecs_32;
     total_sectors   = fat.bxSectors ? : fat.bsHugeSectors;
diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index dc9d090..e691164 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -7,24 +7,9 @@
 #include <fs.h>
 #include "iso9660_fs.h"
 
-static struct inode *new_iso_inode(void)
+static struct inode *new_iso_inode(struct fs_info *fs)
 {
-    struct inode *inode = malloc(sizeof(*inode));
-    
-    if (!inode) {
-	malloc_error("inode structure in new_iso_inode");
-	return NULL;
-    }
-    memset(inode, 0, sizeof(*inode));
-    
-    inode->data = malloc(sizeof(uint32_t));
-    if (!inode) {
-	malloc_error("inode->data in new_iso_inode");
-	free(inode);
-	return NULL;
-    }
-    
-    return inode;
+    return alloc_inode(fs, 0, sizeof(uint32_t));
 }
 
 
@@ -165,8 +150,9 @@ static uint32_t iso_getfssec(struct file *file, char *buf,
     uint32_t bytes_left = file->inode->size - file->offset;
     uint32_t blocks_left = (bytes_left + BLOCK_SIZE(file->fs) - 1) 
 	>> file->fs->block_shift;
-    block_t block = *file->inode->data + (file->offset >> fs->block_shift);    
-    
+    block_t block = *(uint32_t *)file->inode->pvt
+	+ (file->offset >> fs->block_shift);    
+
     if (blocks > blocks_left)
         blocks = blocks_left;
     cdrom_read_blocks(disk, buf, block, blocks);
@@ -187,7 +173,8 @@ static uint32_t iso_getfssec(struct file *file, char *buf,
  */
 static struct iso_dir_entry *iso_find_entry(char *dname, struct inode *inode)
 {
-    block_t dir_block = *inode->data;
+    struct fs_info *fs = inode->fs;
+    block_t dir_block = *(uint32_t *)inode->pvt;
     int i = 0, offset = 0;
     char *de_name;
     int de_name_len, de_len;
@@ -199,7 +186,7 @@ static struct iso_dir_entry *iso_find_entry(char *dname, struct inode *inode)
 	if (!cs) {
 	    if (++i > inode->blocks)
 		return NULL;
-	    cs = get_cache_block(this_fs->fs_dev, dir_block++);
+	    cs = get_cache_block(fs->fs_dev, dir_block++);
 	    de = (struct iso_dir_entry *)cs->data;
 	    offset = 0;
 	}
@@ -213,15 +200,15 @@ static struct iso_dir_entry *iso_find_entry(char *dname, struct inode *inode)
 	offset += de_len;
 	
 	/* Make sure we have a full directory entry */
-	if (offset >= BLOCK_SIZE(this_fs)) {
-	    int slop = de_len + BLOCK_SIZE(this_fs) - offset;
+	if (offset >= BLOCK_SIZE(fs)) {
+	    int slop = de_len + BLOCK_SIZE(fs) - offset;
 	    
 	    memcpy(&tmpde, de, slop);
-	    offset &= BLOCK_SIZE(this_fs) - 1;
+	    offset &= BLOCK_SIZE(fs) - 1;
 	    if (offset) {
 		if (++i > inode->blocks)
 		    return NULL;
-		cs = get_cache_block(this_fs->fs_dev, dir_block++);
+		cs = get_cache_block(fs->fs_dev, dir_block++);
 		memcpy((void *)&tmpde + slop, cs->data, offset);
 	    }
 	    de = &tmpde;
@@ -255,35 +242,36 @@ static inline int get_inode_mode(uint8_t flags)
 	return I_FILE;
 }
 
-static struct inode *iso_get_inode(struct iso_dir_entry *de)
+static struct inode *iso_get_inode(struct fs_info *fs,
+				   struct iso_dir_entry *de)
 {
-    struct inode *inode = new_iso_inode();
-    
+    struct inode *inode = new_iso_inode(fs);
     if (!inode)
 	return NULL;
+
     inode->mode   = get_inode_mode(de->flags);
     inode->size   = *(uint32_t *)de->size;
-    *inode->data  = *(uint32_t *)de->extent;
-    inode->blocks = (inode->size + BLOCK_SIZE(this_fs) - 1) 
-	>> this_fs->block_shift;
+    *(uint32_t *)inode->pvt = *(uint32_t *)de->extent;
+    inode->blocks = (inode->size + BLOCK_SIZE(fs) - 1) 
+	>> fs->block_shift;
     
     return inode;
 }
 
 
-static struct inode *iso_iget_root(void)
+static struct inode *iso_iget_root(struct fs_info *fs)
 {
-    struct inode *inode = new_iso_inode();
-    struct iso_dir_entry *root = &ISO_SB(this_fs)->root;
+    struct inode *inode = new_iso_inode(fs);
+    struct iso_dir_entry *root = &ISO_SB(fs)->root;
     
     if (!inode) 
 	return NULL;
     
     inode->mode   = I_DIR;
     inode->size   = *(uint32_t *)root->size;
-    *inode->data  = *(uint32_t *)root->extent;
-    inode->blocks = (inode->size + BLOCK_SIZE(this_fs) - 1)
-	>> this_fs->block_shift;
+    *(uint32_t *)inode->pvt = *(uint32_t *)root->extent;
+    inode->blocks = (inode->size + BLOCK_SIZE(fs) - 1)
+	>> fs->block_shift;
     
     return inode;
 }	
@@ -296,7 +284,7 @@ static struct inode *iso_iget(char *dname, struct inode *parent)
     if (!de)
 	return NULL;
     
-    return iso_get_inode(de);
+    return iso_get_inode(parent->fs, de);
 }
 
 /* Convert to lower case string */
@@ -316,7 +304,8 @@ static struct dirent *iso_readdir(struct file *file)
     struct iso_dir_entry *de, tmpde;
     struct dirent *dirent;
     struct cache_struct *cs = NULL;
-    block_t block =  *file->inode->data + (file->offset >> fs->block_shift);
+    block_t block =  *(uint32_t *)file->inode->pvt
+	+ (file->offset >> fs->block_shift);
     int offset = file->offset & (BLOCK_SIZE(fs) - 1);
     int i = 0;
     int de_len, de_name_len;
@@ -427,8 +416,6 @@ static int iso_fs_init(struct fs_info *fs)
 {
     struct iso_sb_info *sbi;
     
-    this_fs = fs;    
-        
     sbi = malloc(sizeof(*sbi));
     if (!sbi) {
 	malloc_error("iso_sb_info structure");
diff --git a/core/include/core.h b/core/include/core.h
index 1a9e1b9..cdf9244 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -24,7 +24,8 @@ extern void (*idle_hook_func)(void);
 extern void myputs(const char*);
 
 /* malloc.c */
-extern void *malloc(int);
+extern void *malloc(size_t);
+extern void *zalloc(size_t);
 extern void free(void *);
 extern void mem_init(void);
 
diff --git a/core/include/fs.h b/core/include/fs.h
index c90c215..394b2ae 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -62,8 +62,8 @@ struct fs_ops {
     char *   (*unmangle_name)(char *, const char *);
     int      (*load_config)(void);
 
-    struct inode * (*iget_root)(void);
-    struct inode * (*iget_current)(void);
+    struct inode * (*iget_root)(struct fs_info *);
+    struct inode * (*iget_current)(struct fs_info *);
     struct inode * (*iget)(char *, struct inode *);
     char * (*follow_symlink)(struct inode *, const char *);
 
@@ -77,6 +77,7 @@ enum inode_mode {I_FILE, I_DIR, I_SYMLINK};
  * The inode structure, including the detail file information 
  */
 struct inode {
+    struct fs_info *fs;	 /* The filesystem this inode is associated with */
     int          mode;   /* FILE , DIR or SYMLINK */
     uint32_t     size;
     uint32_t     ino;    /* Inode number */
@@ -85,9 +86,9 @@ struct inode {
     uint32_t     ctime;  /* Create time */
     uint32_t     dtime;  /* Delete time */
     int          blocks; /* How many blocks the file take */
-    uint32_t *   data;   /* The block address array where the file stored */
     uint32_t     flags;
     uint32_t     file_acl;
+    char         pvt[0]; /* Private filesystem data */
 };
 
 extern struct inode *this_inode;
@@ -144,13 +145,13 @@ static inline bool not_whitespace(char c)
   return (unsigned char)c > ' ';
 }
 
+/*
+ * Inode allocator/deallocator
+ */
+struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data);
 static inline void free_inode(struct inode * inode)
 {
-    if (inode) {
-	if (inode->data)
-	    free(inode->data);
-	free(inode);
-    }
+    free(inode);
 }
 
 static inline void malloc_error(char *obj)
diff --git a/core/malloc.c b/core/malloc.c
index a033ff0..da4a343 100644
--- a/core/malloc.c
+++ b/core/malloc.c
@@ -104,7 +104,7 @@ static inline struct mem_struct *  try_merge_back(struct mem_struct *mm)
  * of size _size_. Returns NULL if failed, or the address newly allocated.
  * 
  */
-void *malloc(int size)
+void *malloc(size_t size)
 {
     struct mem_struct *next = next_start;
     struct mem_struct *good = next, *prev;
@@ -164,6 +164,14 @@ out:
     return (void *)((uint32_t)good + sizeof(struct mem_struct));
 }
 
+void *zalloc(size_t size)
+{
+    void *p = malloc(size);
+    if (p)
+	memset(p, 0, size);
+    return p;
+}
+
 void free(void *ptr)
 {
     struct mem_struct *mm = ptr - sizeof(*mm);



More information about the Syslinux-commits mailing list