[syslinux:pathbased] cache: update the metadata cache design

syslinux-bot for H. Peter Anvin hpa at zytor.com
Tue Feb 16 12:03:24 PST 2010


Commit-ID:  ff2842a13dd157691dbe9f0b1498c891bef76554
Gitweb:     http://syslinux.zytor.com/commit/ff2842a13dd157691dbe9f0b1498c891bef76554
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Tue, 16 Feb 2010 12:01:19 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Tue, 16 Feb 2010 12:01:19 -0800

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 at zytor.com>


---
 core/fs/btrfs/btrfs.c     |    8 +-
 core/fs/cache.c           |  142 +++++++++++++++++++--------------------------
 core/fs/ext2/bmap.c       |   96 +++++++++++++-----------------
 core/fs/ext2/ext2.c       |   70 +++++++++++-----------
 core/fs/fat/fat.c         |   47 +++++++--------
 core/fs/iso9660/iso9660.c |   46 ++++++++-------
 core/include/cache.h      |   17 ++---
 core/include/fs.h         |    6 +-
 8 files changed, 197 insertions(+), 235 deletions(-)

diff --git a/core/fs/btrfs/btrfs.c b/core/fs/btrfs/btrfs.c
index 853287e..5557c87 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 415becf..128a124 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 d943202..f5747fc 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 7e19cf3..020cefe 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 5499351..bea6a89 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 b8c790d..a7c70a3 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 7518bc8..0cf399a 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 cc9d21c..8a173d9 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;



More information about the Syslinux-commits mailing list