aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/include/nullfs.h1
-rw-r--r--src/kernel/include/vfs.h13
-rw-r--r--src/kernel/user/nullfs.c54
3 files changed, 53 insertions, 15 deletions
diff --git a/src/kernel/include/nullfs.h b/src/kernel/include/nullfs.h
index cfca023..265d41b 100644
--- a/src/kernel/include/nullfs.h
+++ b/src/kernel/include/nullfs.h
@@ -11,6 +11,7 @@ typedef struct {
void* (*open)(void* f, int mode, fs_handle_t *h);
size_t (*read)(void* f, size_t offset, size_t len, char* buf);
size_t (*write)(void* f, size_t offset, size_t len, const char* buf);
+ bool (*stat)(void* f, stat_t *st);
void (*close)(void* f);
void (*dispose)(void* f);
} nullfs_node_ops_t;
diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h
index 0a6a955..3ee4367 100644
--- a/src/kernel/include/vfs.h
+++ b/src/kernel/include/vfs.h
@@ -3,17 +3,7 @@
#include <stdbool.h>
#include <malloc.h>
-typedef struct {
- // TODO
- // (should also be moved to a user-visible header)
-} stat_t;
-
-#define FM_READ (0x01)
-#define FM_WRITE (0x02)
-#define FM_MMAP (0x04)
-#define FM_CREATE (0x10)
-#define FM_TRUNC (0x20)
-#define FM_APPEND (0x40)
+#include <fs.h> // common header
// How to use :
// - when using a filesystem : never call the operations in fs_*_ops_t directly, use
@@ -27,6 +17,7 @@ typedef struct {
typedef struct {
size_t (*read)(void* f, size_t offset, size_t len, char* buf);
size_t (*write)(void* f, size_t offset, size_t len, const char* buf);
+ bool (*stat)(void* f, stat_t *st);
void (*close)(void* f);
} fs_handle_ops_t;
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index 79611ab..382e30b 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -1,5 +1,6 @@
#include <hashtbl.h>
#include <string.h>
+#include <debug.h>
#include <nullfs.h>
@@ -8,7 +9,9 @@ static bool nullfs_i_make(fs_handle_t *source, char* opts, fs_t *d);
static bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s);
static bool nullfs_i_delete(void* fs, const char* file);
static void nullfs_i_shutdown(void* fs);
+static bool nullfs_i_fs_stat(void* fs, const char* file, stat_t *st);
+static bool nullfs_i_f_stat(void* f, stat_t *st);
static size_t nullfs_i_read(void* f, size_t offset, size_t len, char* buf);
static size_t nullfs_i_write(void* f, size_t offset, size_t len, const char* buf);
static void nullfs_i_close(void* f);
@@ -22,7 +25,7 @@ static fs_ops_t nullfs_ops = {
.open = nullfs_i_open,
.delete = nullfs_i_delete,
.rename = 0,
- .stat = 0,
+ .stat = nullfs_i_fs_stat,
.ioctl = 0,
.add_source = 0,
.shutdown = nullfs_i_shutdown
@@ -31,7 +34,8 @@ static fs_ops_t nullfs_ops = {
static fs_handle_ops_t nullfs_h_ops = {
.read = nullfs_i_read,
.write = nullfs_i_write,
- .close = nullfs_i_close
+ .close = nullfs_i_close,
+ .stat = nullfs_i_f_stat
};
// Internal nullfs structures
@@ -122,8 +126,19 @@ bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s) {
nullfs_t *f = (nullfs_t*)fs;
nullfs_item_t *x = (nullfs_item_t*)(hashtbl_find(f->items, file));
- if (x == 0) return false;
- // TODO : if null and can_create, then create.
+ if (x == 0) {
+ if (f->can_create) {
+ if (nullfs_add_ram_file(fs, file, 0, 0, false,
+ FM_READ | FM_WRITE | FM_APPEND | FM_TRUNC | FM_MMAP)) {
+ x = (nullfs_item_t*)(hashtbl_find(f->items, file));
+ ASSERT(x != 0);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
nullfs_handle_t *h = (nullfs_handle_t*)malloc(sizeof(nullfs_handle_t));
if (h == 0) return false;
@@ -140,6 +155,15 @@ bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s) {
return true;
}
+bool nullfs_i_fs_stat(void* fs, const char* file, stat_t *st) {
+ nullfs_t *f = (nullfs_t*)fs;
+
+ nullfs_item_t *x = (nullfs_item_t*)(hashtbl_find(f->items, file));
+ if (x == 0) return false;
+
+ return x->ops->stat && x->ops->stat(x->data, st);
+}
+
bool nullfs_i_delete(void* fs, const char* file) {
nullfs_t *f = (nullfs_t*)fs;
@@ -153,6 +177,11 @@ bool nullfs_i_delete(void* fs, const char* file) {
return true;
}
+bool nullfs_i_f_stat(void* f, stat_t *st) {
+ nullfs_handle_t *h = (nullfs_handle_t*)f;
+ return h->item->ops->stat && h->item->ops->stat(h->item->data, st);
+}
+
size_t nullfs_i_read(void* f, size_t offset, size_t len, char* buf) {
nullfs_handle_t *h = (nullfs_handle_t*)f;
if (!h->item->ops->read) return 0;
@@ -179,11 +208,13 @@ static void* nullfs_i_ram_open(void* f, int mode, fs_handle_t *h);
static size_t nullfs_i_ram_read(void* f, size_t offset, size_t len, char* buf);
static size_t nullfs_i_ram_write(void* f, size_t offset, size_t len, const char* buf);
static void nullfs_i_ram_dispose(void* f);
+static bool nullfs_i_ram_stat(void* f, stat_t *st);
static nullfs_node_ops_t nullfs_ram_ops = {
.open = nullfs_i_ram_open,
.read = nullfs_i_ram_read,
.write = nullfs_i_ram_write,
+ .stat = nullfs_i_ram_stat,
.close = 0,
.dispose = nullfs_i_ram_dispose
};
@@ -228,6 +259,14 @@ void* nullfs_i_ram_open(void* fi, int mode, fs_handle_t *h) {
if (mode & ~f->ok_modes) {
return 0;
}
+ mode &= ~FM_CREATE;
+
+ if (mode & FM_TRUNC) {
+ if (f->data_owned) free(f->data);
+ f->data = 0;
+ f->size = 0;
+ f->data_owned = 0;
+ }
h->mode = mode;
return fi;
@@ -272,6 +311,13 @@ void nullfs_i_ram_dispose(void* fi) {
free(f);
}
+bool nullfs_i_ram_stat(void* fi, stat_t *st) {
+ nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi;
+
+ st->size = f->size;
+ return true;
+}
+
/* vim: set ts=4 sw=4 tw=0 noet :*/