diff options
Diffstat (limited to 'kernel/fs')
| -rw-r--r-- | kernel/fs/block.c | 9 | ||||
| -rw-r--r-- | kernel/fs/buffer.c | 82 | ||||
| -rw-r--r-- | kernel/fs/fs.c | 5 | ||||
| -rw-r--r-- | kernel/fs/mount.c | 6 |
4 files changed, 92 insertions, 10 deletions
diff --git a/kernel/fs/block.c b/kernel/fs/block.c index b3f7386..caf97d2 100644 --- a/kernel/fs/block.c +++ b/kernel/fs/block.c @@ -1,10 +1,9 @@ -#include <kernel/hd.h> #include <sys/types.h> -size_t block_read(void *buf, size_t block, size_t len) { - return hd_read_block(buf, block, len); +int block_read(void *buf, size_t block) { + return -1; } -size_t block_write(void *buf, size_t block, size_t len) { - return hd_write_block(buf, block, len); +int block_write(void *buf, size_t block) { + return -1; } diff --git a/kernel/fs/buffer.c b/kernel/fs/buffer.c new file mode 100644 index 0000000..7405738 --- /dev/null +++ b/kernel/fs/buffer.c @@ -0,0 +1,82 @@ +#include <kernel/con.h> +#include <kernel/fs.h> +#include <stdint.h> +#include <string.h> + +/* memory dedicated to the block cache */ +#define BSTART 0x80000 +#define BEND 0xA0000 + +static struct buffer *lru; +static struct buffer *mru; + +struct buffer *buffer_get_block(uint16_t device, uint16_t block); + +void buffer_init(void) { + int c = 0; + struct buffer *last = NULL; + struct buffer *b = (struct buffer*) BSTART; + void *d = (void*) (BEND - BLOCK_SIZE); + + while(d > (void*) b) { + memset(b, 0, sizeof(struct buffer)); + + b->b_data = d; + b->b_prev = last; + + if(last) + last->b_next = b; + + last = b; + + b = (struct buffer*) ((void*) b + sizeof(struct buffer)); + d = (void*) (d - (void*) BLOCK_SIZE); + + c++; + } + + lru = (struct buffer*) BSTART; + mru = last; + + printk("[buf] Buffers initialized (0x%x buffers in pool)\n", c); +} + +struct buffer *buffer_get_block(uint16_t device, uint16_t block) { + int ret; + struct buffer **p = &mru; + struct buffer *b; + + /* check if the requested block is already in the cache */ + while(*p) { + if((*p)->b_device == device && (*p)->b_block == block) { + /* put the buffer back at the MRU end of the list */ + (*p)->b_next = NULL; + (*p)->b_prev = mru; + mru = *p; + return *p; + } + p = &(*p)->b_prev; + } + + /* find a buffer at the end of the LRU list */ + b = lru; + lru = lru->b_next; + lru->b_prev = NULL; + ret = block_read(b->b_data, block); + /* abort if we failed to read in the block */ + if(ret < 0) { + /* release the allocated buffer to the pool */ + lru->b_prev = b; + b->b_next = lru; + b->b_prev = NULL; + lru = b; + return NULL; + } + b->b_device = device; + b->b_block = block; + /* put the buffer back at the MRU end of the list */ + b->b_next = NULL; + b->b_prev = mru; + mru = b; + return b; +} diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c index 792668e..e0d9205 100644 --- a/kernel/fs/fs.c +++ b/kernel/fs/fs.c @@ -1,6 +1,5 @@ #include <kernel/con.h> #include <kernel/fs.h> -#include <kernel/hd.h> #include <kernel/kernel.h> #include <kernel/sched.h> #include <kernel/tty.h> @@ -22,7 +21,9 @@ void fs_init(void) { memset(&sblocks, 0, sizeof(sblocks)); memset(&ftable, 0, sizeof(ftable)); - hd_init(); + buffer_init(); + + /* hd_init(); */ mount_root(); } diff --git a/kernel/fs/mount.c b/kernel/fs/mount.c index 47911fb..9cdf49b 100644 --- a/kernel/fs/mount.c +++ b/kernel/fs/mount.c @@ -6,12 +6,12 @@ struct super_block sblocks[NRSUPER]; void mount_root(void) { - size_t ret; + int ret; char buf[BLOCK_SIZE]; struct super_block *s = (void*) buf; - ret = block_read(buf, 1, 1); - if(ret < 1) { + ret = block_read(buf, 1); + if(ret < 0) { printk("[fs] Failed to read super block\n"); return; } |
