From: acevest Date: Thu, 19 Oct 2023 13:23:19 +0000 (+0800) Subject: ... X-Git-Url: http://zhaoyanbai.com/repos/named.html?a=commitdiff_plain;h=b1f7fd80939193423888e11bd3ee614dd0d4748e;p=kernel.git ... --- diff --git a/fs/buffer.c b/fs/buffer.c index ecc4efd..3074b29 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3,20 +3,115 @@ * File Name: buffer.c * Author: Zhao Yanbai * 2023-06-20 19:30:33 Tuesday CST - * Description: none + * Description: 目前只支持只读,因此可以先写得简单一点 * ------------------------------------------------------------------------ */ #include +#define MAX_BBUFFER_CNT 985 + #define BLOCK_BUFFER_HASH_TABLE_SIZE 211 // atomic_t hash_cnt; -bbuffer_t *block_buffer_hash_table[BLOCK_BUFFER_HASH_TABLE_SIZE] = { +list_head_t block_buffer_hash_table[BLOCK_BUFFER_HASH_TABLE_SIZE] = { 0, }; -int hash(dev_t dev, uint32_t block) { return ((~dev) ^ block) % BLOCK_BUFFER_HASH_TABLE_SIZE; } +typedef struct bbuffer_store { + int blocksize; + list_head_t cache_list; + list_head_t free_list; +} bbuffer_store_t; + +// 1024, 2048, 4096 +bbuffer_store_t store[3] = {0}; + +int hashfn(dev_t dev, uint32_t block) { return ((dev) ^ block) % BLOCK_BUFFER_HASH_TABLE_SIZE; } bbuffer_t *get_hash_block_buffer(dev_t dev, uint32_t block, uint16_t size) {} -void init_buffer() {} +kmem_cache_t *bbufer_kmem_cache = 0; + +bbuffer_t *bread(dev_t dev, uint64_t block, uint32_t size) { + assert(size == 1024 || size == 2048 || size == 4096); + + // 暂时先只支持hard disk + assert(DEV_MAJOR(dev) == DEV_MAJOR_DISK); + + // 先尝试从hash里分配 + list_head_t *p = 0; + uint32_t hash = hashfn(dev, block); + list_for_each(p, block_buffer_hash_table + hash) { + bbuffer_t *b = list_entry(p, bbuffer_t, node); + if (b->dev != dev) { + continue; + } + if (b->block == block) { + continue; + } + + break; + } + + // 如果找到了就直接返回 + if (0 != p) { + bbuffer_t *b = list_entry(p, bbuffer_t, node); + assert(0 != b); + assert(0 != b->data); + return b; + } + + // 如果没找到,则从store的cached_list里尝试找 + + // 如果没找到,则尝试从store里的free_list里尝试分配 + + // 如果free_list为空,且cached_list不为空, +} + +void init_buffer() { + for (int i = 0; i < BLOCK_BUFFER_HASH_TABLE_SIZE; i++) { + list_init(block_buffer_hash_table + i); + } + + bbufer_kmem_cache = kmem_cache_create("bbuffer", sizeof(bbuffer_t), 4); + if (0 == bbufer_kmem_cache) { + panic("no memory for bbufer kmem cache"); + } + + printk("bbufer kmem cache %08x\n", bbufer_kmem_cache); + + for (int i = 0; i < 3; i++) { + int blocksize = 1 << (10 + i); + + store[i].blocksize = blocksize; + list_init(&store[i].cache_list); + list_init(&store[i].free_list); + + int page_left_space = 0; + void *data = 0; + page_t *page = 0; + for (int j = 0; j < MAX_BBUFFER_CNT; j++) { + if (page_left_space < blocksize) { + data = (void *)(alloc_one_page(0)); + page = va2page(data); + } + + bbuffer_t *b = kmem_cache_alloc(bbufer_kmem_cache, 0); + assert(b != 0); + + b->block = 0; + b->block_size = blocksize; + b->ref_count = 0; + b->data = data + j * blocksize; + b->dev = 0; + b->page = page; + list_init(&b->node); + + assert(0 != b->data); + + list_add(&b->node, &store[i].free_list); + + page_left_space -= blocksize; + } + } +} diff --git a/include/buffer.h b/include/buffer.h index 1299ba9..a15b5c1 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -10,13 +10,16 @@ #pragma once #include +#include +#include +#include typedef struct bbuffer { - uint32_t block; // block number - char *data; // - uint16_t block_size; // block size + uint32_t block; // block number + char *data; // + uint32_t ref_count; dev_t dev; page_t *page; - struct bbuffer *next; - struct bbuffer *hash_next; + list_head_t node; + uint16_t block_size; // block size } bbuffer_t; diff --git a/include/list.h b/include/list.h index 8ee3395..e995408 100644 --- a/include/list.h +++ b/include/list.h @@ -69,3 +69,5 @@ static inline void list_del_init(list_head_t *entry) { } static inline int list_empty(list_head_t *head) { return head->next == head; } + +static inline void list_init(list_head_t *head) { INIT_LIST_HEAD(head); } diff --git a/kernel/setup.c b/kernel/setup.c index d947589..12e2314 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -20,6 +20,7 @@ #include extern void init_mm(); +extern void init_buffer(); extern void setup_gdt(); extern void setup_idt(); extern void setup_gate(); @@ -55,6 +56,8 @@ void setup_kernel() { init_mm(); + init_buffer(); + // printk("kernel: %08x - %08x\n", system.kernel_begin, system.kernel_end); boot_delay(DEFAULT_BOOT_DELAY_TICKS);