summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-01-25 14:53:32 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-01-25 14:53:32 -0800
commit413a70918e18bcdf1922583ed7a1c79ccbe4a4b7 (patch)
treedc65df10d14154cbf4f51ce2b6088143f4f4c90f /core
parent1f89ba5debfd8f0d535dba41be7d7dde247de704 (diff)
downloadsyslinux-413a70918e18bcdf1922583ed7a1c79ccbe4a4b7.tar.gz
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@zytor.com>
Diffstat (limited to 'core')
-rw-r--r--core/dir.c6
-rw-r--r--core/fs.c17
-rw-r--r--core/fs/ext2/bmap.c10
-rw-r--r--core/fs/ext2/ext2.c125
-rw-r--r--core/fs/ext2/ext2_fs.h8
-rw-r--r--core/fs/fat/fat.c48
-rw-r--r--core/fs/iso9660/iso9660.c69
-rw-r--r--core/include/core.h3
-rw-r--r--core/include/fs.h17
-rw-r--r--core/malloc.c10
10 files changed, 142 insertions, 171 deletions
diff --git a/core/dir.c b/core/dir.c
index 37d92ed2..4013280a 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 37808812..3d6652dd 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 e38bcd2c..e4698d0c 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 01f32f84..b8c4e104 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 0249ee16..b74038ea 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 405e43a8..db72bd28 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 dc9d0906..e6911644 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 1a9e1b96..cdf92446 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 c90c2152..394b2ae1 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 a033ff03..da4a3430 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);