summaryrefslogtreecommitdiff
path: root/kernel/fs
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fs')
-rw-r--r--kernel/fs/block.c9
-rw-r--r--kernel/fs/buffer.c82
-rw-r--r--kernel/fs/fs.c5
-rw-r--r--kernel/fs/mount.c6
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;
}