summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-16 12:01:19 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-16 12:01:19 -0800
commitff2842a13dd157691dbe9f0b1498c891bef76554 (patch)
tree45a1caf97130391df4eab6f381643afbebd1be6a
parent51933ae32e742a5a81b4b880c1e96a6faa1b3380 (diff)
downloadsyslinux-ff2842a13dd157691dbe9f0b1498c891bef76554.tar.gz
cache: update the metadata cache design
- instead of get_cache_block() returning a descriptor, have get_cache() returning const void *. - have a subfunction to allow getting a block without reading it from disk, and returning the cache descriptor. This will be used in ext2 to pre-seed block 0 with all zero. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs/btrfs/btrfs.c8
-rw-r--r--core/fs/cache.c142
-rw-r--r--core/fs/ext2/bmap.c96
-rw-r--r--core/fs/ext2/ext2.c70
-rw-r--r--core/fs/fat/fat.c47
-rw-r--r--core/fs/iso9660/iso9660.c46
-rw-r--r--core/include/cache.h17
-rw-r--r--core/include/fs.h6
8 files changed, 197 insertions, 235 deletions
diff --git a/core/fs/btrfs/btrfs.c b/core/fs/btrfs/btrfs.c
index 853287e5..5557c871 100644
--- a/core/fs/btrfs/btrfs.c
+++ b/core/fs/btrfs/btrfs.c
@@ -165,8 +165,8 @@ static int raw_read(char *buf, u64 offset, u64 count)
/* cache read from disk, offset and count are bytes */
static int cache_read(char *buf, u64 offset, u64 count)
{
+ const char *cd;
size_t block_size = fs->fs_dev->cache_block_size;
- struct cache_struct *cs;
size_t off, cnt, total;
block_t block;
@@ -174,13 +174,13 @@ static int cache_read(char *buf, u64 offset, u64 count)
while (count > 0) {
block = offset / block_size;
off = offset % block_size;
- cs = get_cache_block(fs->fs_dev, block);
- if (cs == NULL)/* no data */
+ cd = get_cache(fs->fs_dev, block);
+ if (!cd)
break;
cnt = block_size - off;
if (cnt > count)
cnt = count;
- memcpy(buf, cs->data + off, cnt);
+ memcpy(buf, cd + off, cnt);
count -= cnt;
buf += cnt;
offset += cnt;
diff --git a/core/fs/cache.c b/core/fs/cache.c
index 415becff..128a1248 100644
--- a/core/fs/cache.c
+++ b/core/fs/cache.c
@@ -17,118 +17,94 @@
*/
void cache_init(struct device *dev, int block_size_shift)
{
- struct cache_struct *prev, *cur;
+ struct cache *prev, *cur;
char *data = dev->cache_data;
- static __lowmem struct cache_struct cache_head, cache[MAX_CACHE_ENTRIES];
+ struct cache *cache_head, *cache;
int i;
- dev->cache_head = &cache_head;
dev->cache_block_size = 1 << block_size_shift;
dev->cache_entries = dev->cache_size >> block_size_shift;
- if (dev->cache_entries > MAX_CACHE_ENTRIES)
- dev->cache_entries = MAX_CACHE_ENTRIES;
-
- cache_head.prev = &cache[dev->cache_entries-1];
- cache_head.prev->next = &cache_head;
- prev = &cache_head;
+
+ if (dev->cache_size < dev->cache_block_size + 2*sizeof(struct cache)) {
+ dev->cache_head = NULL;
+ return; /* Cache unusably small */
+ }
+
+ while ((dev->cache_entries << block_size_shift) +
+ ((dev->cache_entries+1) * sizeof(struct cache))
+ > dev->cache_size)
+ dev->cache_entries--;
+
+ cache_head = (struct cache *)
+ (data + (dev->cache_entries << block_size_shift));
+ cache = cache_head + 1;
+
+ cache_head->prev = &cache[dev->cache_entries-1];
+ cache_head->next->prev = cache_head;
+ cache_head->block = (block_t)-1;
+ cache_head->data = NULL;
+
+ prev = cache_head;
for (i = 0; i < dev->cache_entries; i++) {
cur = &cache[i];
- cur->block = 0;
+ cur->data = data;
+ cur->block = (block_t)-1;
cur->prev = prev;
prev->next = cur;
- cur->data = data;
data += dev->cache_block_size;
prev = cur++;
}
}
-
/*
* Check for a particular BLOCK in the block cache,
* and if it is already there, just do nothing and return;
- * otherwise load it from disk and updata the LRU link.
- *
+ * otherwise pick a victim block and update the LRU link.
*/
-struct cache_struct* get_cache_block(struct device *dev, block_t block)
+struct cache *_get_cache_block(struct device *dev, block_t block)
{
- struct cache_struct *head = (struct cache_struct *)dev->cache_head;
- struct cache_struct *last = head->prev;
- /* let's find it from the end, 'cause the endest is the freshest */
- struct cache_struct *cs = head->prev;
+ struct cache *head = dev->cache_head;
+ struct cache *cs;
int i;
- static int total_read;
- static int missed;
-
-#if 0
- printf("we are looking for cache of %d\n", block);
-#endif
-
- if (!block) {
- printf("ERROR: we got a ZERO block number that's not we want!\n");
- return NULL;
- }
-
- /* it's aleardy the freshest, so nothing we need do , just return it */
- if (cs->block == block)
- goto out;
-
- for (i = 0; i < dev->cache_entries; i ++) {
- if (cs->block == block)
- break;
- else
- cs = cs->prev;
+
+ cs = dev->cache_head + 1;
+
+ for (i = 0; i < dev->cache_entries; i++) {
+ if (cs->block == block)
+ goto found;
+ cs++;
}
- /* missed, so we need to load it */
- if (i == dev->cache_entries) {
- /* store it at the head of real cache */
- cs = head->next;
- cs->block = block;
- getoneblk(dev->disk, cs->data, block, dev->cache_block_size);
+ /* Not found, pick a victim */
+ cs = head->next;
- missed ++;
- }
-
- /* remove cs from current position in list */
+ /* Add to just before head node */
+found:
cs->prev->next = cs->next;
- cs->next->prev = cs->prev;
-
- /* add to just before head node */
- last->next = cs;
- cs->prev = last;
+ cs->next->prev = cs->prev;
+
+ cs->prev = head->prev;
+ head->prev->next = cs;
+ cs->next = head;
head->prev = cs;
- cs->next = head;
-
- out:
- total_read ++;
-#if 0 /* testing how efficiency the cache is */
- if (total_read % 5 == 0)
- printf("total_read %d\tmissed %d\n", total_read, missed);
-#endif
-
- /* in fact, that would never be happened */
- if ((char *)(cs->data) > (char*)0x100000)
- printf("the buffer addres higher than 1M limit\n");
-
- return cs;
}
-
/*
- * Just print the sector, and according the LRU algorithm,
- * Left most value is the most least secotr, and Right most
- * value is the most Recent sector. I see it's a Left Right Used
- * (LRU) algorithm; Just kidding:)
+ * Check for a particular BLOCK in the block cache,
+ * and if it is already there, just do nothing and return;
+ * otherwise load it from disk and update the LRU link.
+ * Return the data pointer.
*/
-void print_cache(struct device *dev)
+const void *get_cache(struct device *dev, block_t block)
{
- int i = 0;
- struct cache_struct *cs = dev->cache_head;
- for (; i < dev->cache_entries; i++) {
- cs = cs->next;
- printf("%d(%p)\n", cs->block, cs->data);
- }
-
- printf("\n");
+ struct cache *cs;
+
+ cs = _get_cache_block(dev, block);
+ if (cs->block != block) {
+ cs->block = block;
+ getoneblk(dev->disk, cs->data, block, dev->cache_block_size);
+ }
+
+ return cs->data;
}
diff --git a/core/fs/ext2/bmap.c b/core/fs/ext2/bmap.c
index d943202b..f5747fce 100644
--- a/core/fs/ext2/bmap.c
+++ b/core/fs/ext2/bmap.c
@@ -12,12 +12,11 @@
#include <cache.h>
#include "ext2_fs.h"
-static struct ext4_extent_header *
-ext4_find_leaf(struct fs_info *fs, struct ext4_extent_header *eh,
+static const struct ext4_extent_header *
+ext4_find_leaf(struct fs_info *fs, const struct ext4_extent_header *eh,
block_t block)
{
struct ext4_extent_idx *index;
- struct cache_struct *cs;
block_t blk;
int i;
@@ -37,8 +36,7 @@ ext4_find_leaf(struct fs_info *fs, struct ext4_extent_header *eh,
blk = index[i].ei_leaf_hi;
blk = (blk << 32) + index[i].ei_leaf_lo;
- cs = get_cache_block(fs->fs_dev, blk);
- eh = (struct ext4_extent_header *)cs->data;
+ eh = get_cache(fs->fs_dev, blk);
}
}
@@ -46,12 +44,13 @@ ext4_find_leaf(struct fs_info *fs, struct ext4_extent_header *eh,
static block_t bmap_extent(struct inode *inode, block_t block)
{
struct fs_info *fs = inode->fs;
- struct ext4_extent_header *leaf;
- struct ext4_extent *ext;
+ const struct ext4_extent_header *leaf;
+ const struct ext4_extent *ext;
int i;
block_t start;
- leaf = ext4_find_leaf(fs, (struct ext4_extent_header *)inode->pvt, block);
+ leaf = ext4_find_leaf(fs, (const struct ext4_extent_header *)inode->pvt,
+ block);
if (!leaf) {
printf("ERROR, extent leaf not found\n");
return 0;
@@ -77,9 +76,29 @@ static block_t bmap_extent(struct inode *inode, block_t block)
return start + block;
}
+/*
+ * The actual indirect block map handling - the block passed in should
+ * be relative to the beginning of the particular block hierarchy.
+ */
+static block_t bmap_indirect(struct fs_info *fs, uint32_t start,
+ block_t block, int levels)
+{
+ int addr_shift = BLOCK_SHIFT(fs) - 2;
+ uint32_t addr_mask = (1 << addr_shift)-1;
+ uint32_t index;
+ const uint32_t *blk;
+
+ while (levels--) {
+ blk = get_cache(fs->fs_dev, start);
+ index = (block >> (levels * addr_shift)) & addr_mask;
+ blk = blk[index];
+ }
+
+ return blk;
+}
/*
- * handle the traditional block map, like indirect, double indirect
+ * Handle the traditional block map, like indirect, double indirect
* and triple indirect
*/
static block_t bmap_traditional(struct inode *inode, block_t block)
@@ -90,7 +109,10 @@ static block_t bmap_traditional(struct inode *inode, block_t block)
indirect_blocks = addr_per_block,
double_blocks = addr_per_block * addr_per_block,
triple_blocks = double_blocks * addr_per_block;
- struct cache_struct *cs;
+ int addr_shift = BLOCK_SHIFT(fs) - 2;
+ int indirect_shift = addr_shift,
+ double_shift = 2*addr_shift,
+ triple_shift = 3*addr_shift;
/* direct blocks */
if (block < direct_blocks)
@@ -98,57 +120,21 @@ static block_t bmap_traditional(struct inode *inode, block_t block)
/* indirect blocks */
block -= direct_blocks;
- if (block < indirect_blocks) {
- block_t ind_block = ((uint32_t *)inode->pvt)[EXT2_IND_BLOCK];
-
- if (!ind_block)
- return 0;
- cs = get_cache_block(fs->fs_dev, ind_block);
-
- return ((uint32_t *)cs->data)[block];
- }
-
+ if (block < indirect_blocks)
+ return bmap_indirect(fs, ((uint32_t *)inode->pvt)[EXT2_IND_BLOCK],
+ block, 1);
/* double indirect blocks */
block -= indirect_blocks;
- if (block < double_blocks) {
- block_t dou_block = ((uint32_t *)inode->pvt)[EXT2_DIND_BLOCK];
-
- if (!dou_block)
- return 0;
- cs = get_cache_block(fs->fs_dev, dou_block);
-
- dou_block = ((uint32_t *)cs->data)[block / indirect_blocks];
- if (!dou_block)
- return 0;
- cs = get_cache_block(fs->fs_dev, dou_block);
-
- return ((uint32_t *)cs->data)[block % addr_per_block];
- }
-
+ if (block < double_blocks)
+ return bmap_indirect(fs, ((uint32_t *)inode->pvt)[EXT2_DIND_BLOCK],
+ block, 2);
/* triple indirect block */
block -= double_blocks;
- if (block < triple_blocks) {
- block_t tri_block = ((uint32_t *)inode->pvt)[EXT2_TIND_BLOCK];
-
- if (!tri_block)
- return 0;
- cs = get_cache_block(fs->fs_dev, tri_block);
-
- tri_block = ((uint32_t *)cs->data)[block / double_blocks];
- if (!tri_block)
- return 0;
- cs = get_cache_block(fs->fs_dev, tri_block);
-
- tri_block = (block / addr_per_block) % addr_per_block;
- tri_block = ((uint32_t *)cs->data)[tri_block];
- if (!tri_block)
- return 0;
- cs = get_cache_block(fs->fs_dev, tri_block);
-
- return ((uint32_t *)cs->data)[block % addr_per_block];
- }
+ if (block < triple_blocks)
+ return bmap_indirect(fs, ((uint32_t *)inode->pvt)[EXT2_TIND_BLOCK],
+ block, 3);
/* This can't happen... */
return 0;
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
index 7e19cf39..020cefee 100644
--- a/core/fs/ext2/ext2.c
+++ b/core/fs/ext2/ext2.c
@@ -12,13 +12,12 @@
/*
* get the group's descriptor of group_num
*/
-struct ext2_group_desc * ext2_get_group_desc(struct fs_info *fs,
- uint32_t group_num)
+const struct ext2_group_desc *ext2_get_group_desc(struct fs_info *fs,
+ uint32_t group_num)
{
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;
+ const struct ext2_group_desc *desc_data_block;
if (group_num >= sbi->s_groups_count) {
printf ("ext2_get_group_desc"
@@ -34,9 +33,7 @@ struct ext2_group_desc * ext2_get_group_desc(struct fs_info *fs,
desc_block += sbi->s_first_data_block + 1;
- cs = get_cache_block(fs->fs_dev, desc_block);
- desc_data_block = cs->data;
-
+ desc_data_block = get_cache(fs->fs_dev, desc_block);
return &desc_data_block[desc_index];
}
@@ -159,7 +156,7 @@ static uint32_t ext2_getfssec(struct file *file, char *buf,
* Unlike strncmp, ext2_match_entry returns 1 for success, 0 for failure.
*/
static inline bool ext2_match_entry(const char *name, size_t len,
- struct ext2_dir_entry * de)
+ const struct ext2_dir_entry * de)
{
if (!de->d_inode)
return false;
@@ -180,26 +177,26 @@ static inline struct ext2_dir_entry *ext2_next_entry(struct ext2_dir_entry *p)
/*
* find a dir entry, return it if found, or return NULL.
*/
-static struct ext2_dir_entry *
+static const struct ext2_dir_entry *
ext2_find_entry(struct fs_info *fs, struct inode *inode, const char *dname)
{
block_t index = 0;
block_t block;
uint32_t i = 0, offset, maxoffset;
- struct ext2_dir_entry *de;
- struct cache_struct *cs;
+ const struct ext2_dir_entry *de;
+ const char *data;
size_t dname_len = strlen(dname);
while (i < inode->size) {
if (!(block = ext2_bmap(inode, index++)))
return NULL;
- cs = get_cache_block(fs->fs_dev, block);
+ data = get_cache(fs->fs_dev, block);
offset = 0;
maxoffset = min(BLOCK_SIZE(fs), i-inode->size);
/* The smallest possible size is 9 bytes */
while (offset < maxoffset-8) {
- de = (struct ext2_dir_entry *)((char *)cs->data + offset);
+ de = (const struct ext2_dir_entry *)(data + offset);
if (de->d_rec_len > maxoffset - offset)
break;
@@ -214,10 +211,11 @@ ext2_find_entry(struct fs_info *fs, struct inode *inode, const char *dname)
return NULL;
}
-static struct ext2_inode *ext2_get_inode(struct fs_info *fs, int inr)
+static const struct ext2_inode *
+ext2_get_inode(struct fs_info *fs, int inr)
{
- struct ext2_group_desc *desc;
- struct cache_struct *cs;
+ const struct ext2_group_desc *desc;
+ const char *data;
uint32_t inode_group, inode_offset;
uint32_t block_num, block_off;
@@ -232,9 +230,10 @@ static struct ext2_inode *ext2_get_inode(struct fs_info *fs, int inr)
inode_offset / EXT2_INODES_PER_BLOCK(fs);
block_off = inode_offset % EXT2_INODES_PER_BLOCK(fs);
- cs = get_cache_block(fs->fs_dev, block_num);
+ data = get_cache(fs->fs_dev, block_num);
- return cs->data + block_off * EXT2_SB(fs)->s_inode_size;
+ return (const struct ext2_inode *)
+ (data + block_off * EXT2_SB(fs)->s_inode_size);
}
static inline int get_inode_mode(int mode)
@@ -249,7 +248,7 @@ static inline int get_inode_mode(int mode)
return mode;
}
-static void fill_inode(struct inode *inode, struct ext2_inode *e_inode)
+static void fill_inode(struct inode *inode, const struct ext2_inode *e_inode)
{
inode->mode = get_inode_mode(e_inode->i_mode);
inode->size = e_inode->i_size;
@@ -265,7 +264,7 @@ static void fill_inode(struct inode *inode, struct ext2_inode *e_inode)
static struct inode *ext2_iget_by_inr(struct fs_info *fs, uint32_t inr)
{
- struct ext2_inode *e_inode;
+ const struct ext2_inode *e_inode;
struct inode *inode;
e_inode = ext2_get_inode(fs, inr);
@@ -283,23 +282,22 @@ static struct inode *ext2_iget_root(struct fs_info *fs)
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(fs, parent, dname);
- if (!de)
- return NULL;
+ const struct ext2_dir_entry *de;
+ struct fs_info *fs = parent->fs;
- return ext2_iget_by_inr(fs, de->d_inode);
+ de = ext2_find_entry(fs, parent, dname);
+ if (!de)
+ return NULL;
+
+ return ext2_iget_by_inr(fs, de->d_inode);
}
-
int ext2_readlink(struct inode *inode, char *buf)
{
struct fs_info *fs = inode->fs;
int sec_per_block = 1 << (fs->block_shift - fs->sector_shift);
bool fast_symlink;
- struct cache_struct *cs;
+ const char *data;
size_t bytes = inode->size;
if (inode->size > BLOCK_SIZE(fs))
@@ -309,8 +307,8 @@ int ext2_readlink(struct inode *inode, char *buf)
if (fast_symlink) {
memcpy(buf, inode->pvt, bytes);
} else {
- cs = get_cache_block(fs->fs_dev, *(uint32_t *)inode->pvt);
- memcpy(buf, cs->data, bytes);
+ data = get_cache(fs->fs_dev, *(uint32_t *)inode->pvt);
+ memcpy(buf, data, bytes);
}
return bytes;
@@ -324,15 +322,17 @@ static struct dirent * ext2_readdir(struct file *file)
struct fs_info *fs = file->fs;
struct inode *inode = file->inode;
struct dirent *dirent;
- struct ext2_dir_entry *de;
- struct cache_struct *cs;
+ const struct ext2_dir_entry *de;
+ const char *data;
block_t index = file->offset >> fs->block_shift;
block_t block;
if (!(block = ext2_bmap(inode, index)))
return NULL;
- cs = get_cache_block(fs->fs_dev, block);
- de = (struct ext2_dir_entry *)(cs->data + (file->offset & (BLOCK_SIZE(fs) - 1)));
+
+ data = get_cache(fs->fs_dev, block);
+ de = (const struct ext2_dir_entry *)
+ (data + (file->offset & (BLOCK_SIZE(fs) - 1)));
if (!(dirent = malloc(sizeof(*dirent)))) {
malloc_error("dirent structure in ext2_readdir");
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index 54993513..bea6a89e 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -22,9 +22,9 @@ static struct inode * new_fat_inode(struct fs_info *fs)
/*
* Check for a particular sector in the FAT cache
*/
-static struct cache_struct * get_fat_sector(struct fs_info *fs, sector_t sector)
+static const void *get_fat_sector(struct fs_info *fs, sector_t sector)
{
- return get_cache_block(fs->fs_dev, FAT_SB(fs)->fat + sector);
+ return get_cache(fs->fs_dev, FAT_SB(fs)->fat + sector);
}
static uint32_t get_next_cluster(struct fs_info *fs, uint32_t clust_num)
@@ -33,15 +33,15 @@ static uint32_t get_next_cluster(struct fs_info *fs, uint32_t clust_num)
sector_t fat_sector;
uint32_t offset;
int lo, hi;
- struct cache_struct *cs;
uint32_t sector_mask = SECTOR_SIZE(fs) - 1;
+ const uint8_t *data;
switch(FAT_SB(fs)->fat_type) {
case FAT12:
offset = clust_num + (clust_num >> 1);
fat_sector = offset >> SECTOR_SHIFT(fs);
offset &= sector_mask;
- cs = get_fat_sector(fs, fat_sector);
+ data = get_fat_sector(fs, fat_sector);
if (offset == sector_mask) {
/*
* we got the end of the one fat sector,
@@ -49,12 +49,12 @@ static uint32_t get_next_cluster(struct fs_info *fs, uint32_t clust_num)
* so store the low part, then read the next fat
* sector, read the high part, then combine it.
*/
- lo = *(uint8_t *)(cs->data + offset);
- cs = get_fat_sector(fs, fat_sector + 1);
- hi = *(uint8_t *)cs->data;
+ lo = data[offset];
+ data = get_fat_sector(fs, fat_sector + 1);
+ hi = data[0];
next_cluster = (hi << 8) + lo;
} else {
- next_cluster = *(uint16_t *)(cs->data + offset);
+ next_cluster = *(const uint16_t *)(data + offset);
}
if (clust_num & 0x0001)
@@ -67,16 +67,16 @@ static uint32_t get_next_cluster(struct fs_info *fs, uint32_t clust_num)
offset = clust_num << 1;
fat_sector = offset >> SECTOR_SHIFT(fs);
offset &= sector_mask;
- cs = get_fat_sector(fs, fat_sector);
- next_cluster = *(uint16_t *)(cs->data + offset);
+ data = get_fat_sector(fs, fat_sector);
+ next_cluster = *(const uint16_t *)(data + offset);
break;
case FAT32:
offset = clust_num << 2;
fat_sector = offset >> SECTOR_SHIFT(fs);
offset &= sector_mask;
- cs = get_fat_sector(fs, fat_sector);
- next_cluster = *(uint32_t *)(cs->data + offset);
+ data = get_fat_sector(fs, fat_sector);
+ next_cluster = *(const uint32_t *)(data + offset);
next_cluster &= 0x0fffffff;
break;
}
@@ -409,13 +409,13 @@ static void copy_long_chunk(uint16_t *buf, const struct fat_dir_entry *de)
memcpy(buf + 11, le->name3, 2 * 2);
}
-static uint8_t get_checksum(char *dir_name)
+static uint8_t get_checksum(const char *dir_name)
{
int i;
uint8_t sum = 0;
for (i = 11; i; i--)
- sum = ((sum & 1) << 7) + (sum >> 1) + *dir_name++;
+ sum = ((sum & 1) << 7) + (sum >> 1) + (uint8_t)*dir_name++;
return sum;
}
@@ -447,9 +447,8 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir)
{
struct fs_info *fs = dir->fs;
struct inode *inode;
- struct fat_dir_entry *de;
+ const struct fat_dir_entry *de;
struct fat_long_name_entry *long_de;
- struct cache_struct *cs;
char mangled_name[12];
uint16_t long_name[260]; /* == 20*13 */
@@ -475,8 +474,7 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir)
mangle_dos_name(mangled_name, dname);
while (dir_sector) {
- cs = get_cache_block(fs->fs_dev, dir_sector);
- de = (struct fat_dir_entry *)cs->data;
+ de = get_cache(fs->fs_dev, dir_sector);
entries = 1 << (fs->sector_shift - 5);
while (entries--) {
@@ -588,9 +586,9 @@ static struct dirent * vfat_readdir(struct file *file)
{
struct fs_info *fs = file->fs;
struct dirent *dirent;
- struct fat_dir_entry *de;
- struct fat_long_name_entry *long_de;
- struct cache_struct *cs;
+ const struct fat_dir_entry *de;
+ const char *data;
+ const struct fat_long_name_entry *long_de;
sector_t sector = get_the_right_sector(file);
@@ -604,8 +602,8 @@ static struct dirent * vfat_readdir(struct file *file)
int long_entry = 0;
int sec_off = file->offset & ((1 << fs->sector_shift) - 1);
- cs = get_cache_block(fs->fs_dev, sector);
- de = (struct fat_dir_entry *)(cs->data + sec_off);
+ data = get_cache(fs->fs_dev, sector);
+ de = (const struct fat_dir_entry *)(data + sec_off);
entries_left = ((1 << fs->sector_shift) - sec_off) >> 5;
vfat_next = vfat_csum = 0xff;
@@ -708,8 +706,7 @@ static struct dirent * vfat_readdir(struct file *file)
sector = next_sector(file);
if (!sector)
return NULL;
- cs = get_cache_block(fs->fs_dev, sector);
- de = (struct fat_dir_entry *)cs->data;
+ de = get_cache(fs->fs_dev, sector);
entries_left = 1 << (fs->sector_shift - 5);
}
diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index b8c790dc..a7c70a3f 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -63,7 +63,7 @@ static void iso_mangle_name(char *dst, const char *src)
*dst++ = '\0';
}
-static int iso_convert_name(char *dst, char *src, int len)
+static int iso_convert_name(char *dst, const char *src, int len)
{
int i = 0;
char c;
@@ -97,7 +97,8 @@ static int iso_convert_name(char *dst, char *src, int len)
/*
* Unlike strcmp, it does return 1 on match, or reutrn 0 if not match.
*/
-static int iso_compare_name(char *de_name, int len, char *file_name)
+static int iso_compare_name(const char *de_name, int len,
+ const char *file_name)
{
char iso_file_name[256];
char *p = iso_file_name;
@@ -162,26 +163,28 @@ static uint32_t iso_getfssec(struct file *file, char *buf,
/*
* Find a entry in the specified dir with name _dname_.
*/
-static struct iso_dir_entry *iso_find_entry(char *dname, struct inode *inode)
+static const struct iso_dir_entry *
+iso_find_entry(char *dname, struct inode *inode)
{
struct fs_info *fs = inode->fs;
block_t dir_block = *(uint32_t *)inode->pvt;
int i = 0, offset = 0;
- char *de_name;
+ const char *de_name;
int de_name_len, de_len;
- struct iso_dir_entry *de;
+ const struct iso_dir_entry *de;
struct iso_dir_entry tmpde;
+ const char *data = NULL;
struct cache_struct *cs = NULL;
while (1) {
- if (!cs) {
+ if (!data) {
if (++i > inode->blocks)
return NULL;
- cs = get_cache_block(fs->fs_dev, dir_block++);
- de = (struct iso_dir_entry *)cs->data;
+ data = get_cache(fs->fs_dev, dir_block++);
+ de = (const struct iso_dir_entry *)data;
offset = 0;
}
- de = (struct iso_dir_entry *)(cs->data + offset);
+ de = (const struct iso_dir_entry *)(data + offset);
de_len = de->length;
if (de_len == 0) { /* move on to the next block */
@@ -199,8 +202,8 @@ static struct iso_dir_entry *iso_find_entry(char *dname, struct inode *inode)
if (offset) {
if (++i > inode->blocks)
return NULL;
- cs = get_cache_block(fs->fs_dev, dir_block++);
- memcpy((void *)&tmpde + slop, cs->data, offset);
+ data = get_cache(fs->fs_dev, dir_block++);
+ memcpy((void *)&tmpde + slop, data, offset);
}
de = &tmpde;
}
@@ -234,7 +237,7 @@ static inline int get_inode_mode(uint8_t flags)
}
static struct inode *iso_get_inode(struct fs_info *fs,
- struct iso_dir_entry *de)
+ const struct iso_dir_entry *de)
{
struct inode *inode = new_iso_inode(fs);
if (!inode)
@@ -269,7 +272,7 @@ static struct inode *iso_iget_root(struct fs_info *fs)
static struct inode *iso_iget(char *dname, struct inode *parent)
{
- struct iso_dir_entry *de;
+ const struct iso_dir_entry *de;
de = iso_find_entry(dname, parent);
if (!de)
@@ -292,9 +295,10 @@ static struct dirent *iso_readdir(struct file *file)
{
struct fs_info *fs = file->fs;
struct inode *inode = file->inode;
- struct iso_dir_entry *de, tmpde;
+ const struct iso_dir_entry *de;
+ struct iso_dir_entry tmpde;
struct dirent *dirent;
- struct cache_struct *cs = NULL;
+ const char *data = NULL;
block_t block = *(uint32_t *)file->inode->pvt
+ (file->offset >> fs->block_shift);
int offset = file->offset & (BLOCK_SIZE(fs) - 1);
@@ -303,16 +307,16 @@ static struct dirent *iso_readdir(struct file *file)
char *de_name;
while (1) {
- if (!cs) {
+ if (!data) {
if (++i > inode->blocks)
return NULL;
- cs = get_cache_block(fs->fs_dev, block++);
+ data = get_cache(fs->fs_dev, block++);
}
- de = (struct iso_dir_entry *)(cs->data + offset);
+ de = (const struct iso_dir_entry *)(data + offset);
de_len = de->length;
if (de_len == 0) { /* move on to the next block */
- cs = NULL;
+ data = NULL;
file->offset = (file->offset + BLOCK_SIZE(fs) - 1)
>> fs->block_shift;
continue;
@@ -328,8 +332,8 @@ static struct dirent *iso_readdir(struct file *file)
if (offset) {
if (++i > inode->blocks)
return NULL;
- cs = get_cache_block(fs->fs_dev, block++);
- memcpy((void *)&tmpde + slop, cs->data, offset);
+ data = get_cache(fs->fs_dev, block++);
+ memcpy((char *)&tmpde + slop, data, offset);
}
de = &tmpde;
}
diff --git a/core/include/cache.h b/core/include/cache.h
index 7518bc84..0cf399af 100644
--- a/core/include/cache.h
+++ b/core/include/cache.h
@@ -6,20 +6,17 @@
#include "disk.h"
#include "fs.h"
-#define MAX_CACHE_ENTRIES 0x10 /* I find even this is enough:) */
-
/* The cache structure */
-struct cache_struct {
- block_t block;
- struct cache_struct *prev;
- struct cache_struct *next;
- void *data;
+struct cache {
+ block_t block;
+ struct cache *prev;
+ struct cache *next;
+ void *data;
};
-
/* functions defined in cache.c */
void cache_init(struct device *, int);
-struct cache_struct* get_cache_block(struct device *, block_t);
-void print_cache(struct device *);
+const void *get_cache(struct device *, block_t);
+struct cache *_get_cache_block(struct device *, block_t);
#endif /* cache.h */
diff --git a/core/include/fs.h b/core/include/fs.h
index cc9d21c4..8a173d9f 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -119,12 +119,14 @@ enum dev_type {CHS, EDD};
* the pointer points to the disk structure,
* the cache stuff.
*/
+struct cache;
+
struct device {
struct disk *disk;
/* the cache stuff */
- char* cache_data;
- void* cache_head;
+ char *cache_data;
+ struct cache *cache_head;
uint16_t cache_block_size;
uint16_t cache_entries;
uint32_t cache_size;