diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-16 12:01:19 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-16 12:01:19 -0800 |
commit | ff2842a13dd157691dbe9f0b1498c891bef76554 (patch) | |
tree | 45a1caf97130391df4eab6f381643afbebd1be6a | |
parent | 51933ae32e742a5a81b4b880c1e96a6faa1b3380 (diff) | |
download | syslinux-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.c | 8 | ||||
-rw-r--r-- | core/fs/cache.c | 142 | ||||
-rw-r--r-- | core/fs/ext2/bmap.c | 96 | ||||
-rw-r--r-- | core/fs/ext2/ext2.c | 70 | ||||
-rw-r--r-- | core/fs/fat/fat.c | 47 | ||||
-rw-r--r-- | core/fs/iso9660/iso9660.c | 46 | ||||
-rw-r--r-- | core/include/cache.h | 17 | ||||
-rw-r--r-- | 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 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; |