From ac904939fe2c09aa580ada2ab20eff8ee22131a4 Mon Sep 17 00:00:00 2001 From: YourBroDuke Date: Mon, 7 Jan 2019 12:22:48 +0800 Subject: [PATCH] class --- include/zjunix/mfs/fat32.h | 2 +- include/zjunix/mfs/fat32cache.h | 6 ++ kernel/mfs/fat32cache.c | 108 ++++++++++++++++++++++++++++++-- 3 files changed, 110 insertions(+), 6 deletions(-) diff --git a/include/zjunix/mfs/fat32.h b/include/zjunix/mfs/fat32.h index 44fede6..5f0d494 100644 --- a/include/zjunix/mfs/fat32.h +++ b/include/zjunix/mfs/fat32.h @@ -137,7 +137,7 @@ struct mem_page { u8 *p_data; u8 state; - u32 p_block_number; + u32 abs_sector_num; struct list_head p_hashlist; struct list_head p_LRU; }; diff --git a/include/zjunix/mfs/fat32cache.h b/include/zjunix/mfs/fat32cache.h index 4ea0c15..bef52a1 100644 --- a/include/zjunix/mfs/fat32cache.h +++ b/include/zjunix/mfs/fat32cache.h @@ -26,7 +26,13 @@ struct P_cache { }; u32 init_cache(); +struct mem_dentry * dcache_lookup(struct D_cache *dcache, u32 sector_num, u32 offset); +struct mem_page * pcache_lookup(struct P_cache *pcache, struct mem_page *data); void dcache_add(struct D_cache *dcache, struct mem_dentry *data); +void pcache_add(struct P_cache *pcache, struct mem_page* data); +void dcache_drop(struct D_cache *dcache); +void pcache_drop(struct P_cache *pcache); + u32 __intHash(u32 key, u32 size); #endif \ No newline at end of file diff --git a/kernel/mfs/fat32cache.c b/kernel/mfs/fat32cache.c index 2e115b9..d71aa15 100644 --- a/kernel/mfs/fat32cache.c +++ b/kernel/mfs/fat32cache.c @@ -28,20 +28,118 @@ u32 init_cache() { } } -void dcache_add(struct D_cache *dcache, struct mem_dentry *data) -{ - u32 hash = __intHash(data->abs_sector_num * 16 + data->sector_dentry_offset, C_TABLESIZE); +struct mem_dentry * dcache_lookup(struct D_cache *dcache, u32 sector_num, u32 offset) { + struct list_head *table_head; + struct list_head *crt_node; + struct mem_dentry *crt_entry; + + u32 hash = __intHash(sector_num * DENTRY_PER_SEC + offset, C_TABLESIZE); + + table_head = &(dcache->c_hashtable[hash]); + + list_for_each(crt_node, table_head) { + crt_entry = list_entry(crt_node, struct mem_dentry, d_hashlist); + if (crt_entry->abs_sector_num == sector_num && crt_entry->sector_dentry_offset == offset) { + break; + } + } + + // Update LRU list + if (crt_node != table_head) { + list_del(&(crt_entry->d_LRU)); + list_add(&(crt_entry->d_LRU), &(dcache->c_LRU)); + return crt_entry; + } else { + return 0; + } +} + +struct mem_page * pcache_lookup(struct P_cache *pcache, u32 sector_num) { + struct list_head *table_head; + struct list_head *crt_node; + struct mem_page *crt_page; + + u32 hash = __intHash(sector_num, C_TABLESIZE); + + table_head = &(pcache->c_hashtable[hash]); + + list_for_each(crt_node, table_head) { + crt_page = list_entry(crt_node, struct mem_page, p_hashlist); + if (crt_page->abs_sector_num == sector_num) { + break; + } + } + + // Update LRU list + if (crt_node != table_head) { + list_del(&(crt_page->p_LRU)); + list_add(&(crt_page->p_LRU), &(pcache->c_LRU)); + return crt_page; + } else { + return 0; + } +} + +void dcache_add(struct D_cache *dcache, struct mem_dentry *data) { + u32 hash = __intHash(data->abs_sector_num * DENTRY_PER_SEC + data->sector_dentry_offset, C_TABLESIZE); if (dcache->crt_size == dcache->max_capacity) { - // dcache_drop_LRU(dcache); + dcache_drop(dcache); } list_add(&(data->d_hashlist), dcache->c_hashtable+hash); - list_add(&(data->d_LRU), &(dcache->c_LRU)) + list_add(&(data->d_LRU), &(dcache->c_LRU)); dcache->crt_size++; } +void pcache_add(sruct P_cache *pcache, struct mem_page *data) { + u32 hash = __intHash(data->abs_sector_num, C_TABLESIZE); + + if (pcache->crt_size == pcache->max_capacity) { + pcache_drop(pcache) + } + + list_add(&(data->p_hashlist), pcache->c_hashtable+hash); + list_add(&(data->p_LRU), &(pcache->p_LRU)); + + pcache->crt_size++; +} + +void dcache_drop(struct D_cache *dcache) { + struct list_head *LRU_head = &(dcache->c_LRU); + struct list_head *victim = LRU_head->prev; + struct mem_dentry *crt_entry; + + if (dcache->crt_size == 0 || dcache->crt_size == 1) return; + else { + crt_entry = list_entry(victim, struct mem_dentry, d_LRU); + if (crt_entry->is_root == 1) { + victim = victim->prev; + crt_entry = list_entry(victim, struct mem_dentry, d_LRU); + } + list_del(victim); + list_del(&(crt_entry->d_hashlist)); + kfree(crt_entry); + dcache->crt_size--; + } +} + +void pcache_drop(struct P_cache *pcache) { + struct list_head *LRU_head = &(pcache->c_LRU); + struct list_head *victim = LRU_head->prev; + struct mem_page *crt_page; + + if (pcache->crt_size == 0) return; + else { + crt_page = list_entry(victim, struct mem_page, p_LRU); + list_del(victim); + list_del(&(crt_page->p_hashlist)); + kfree(crt_page->p_data); + pcache->crt_size--; + } +} + u32 __intHash(u32 key, u32 size) { u32 mask = size - 1; return key & mask;