aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-02 23:02:59 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-02 23:02:59 +0100
commite356371f09df87ebab2d7e3d816de1147768dfa9 (patch)
tree4932209fc8799bb63006c3ebb11b9a438ae34342
parent969c8cacc50e8c39ddbc19e05f3f5b98c34bde01 (diff)
downloadkogata-e356371f09df87ebab2d7e3d816de1147768dfa9.tar.gz
kogata-e356371f09df87ebab2d7e3d816de1147768dfa9.zip
Change VFS interface : handles no longer visible to underlying FS.
-rw-r--r--src/apps/init/main.c58
-rw-r--r--src/common/include/syscallproto.h2
-rw-r--r--src/kernel/dev/pciide.c31
-rw-r--r--src/kernel/fs/iso9660.c113
-rw-r--r--src/kernel/include/vfs.h33
-rw-r--r--src/kernel/user/nullfs.c149
-rw-r--r--src/kernel/user/process.c5
-rw-r--r--src/kernel/user/syscall.c4
-rw-r--r--src/kernel/user/vfs.c37
-rw-r--r--src/lib/include/syscall.h2
-rw-r--r--src/lib/libkogata/syscall.c4
11 files changed, 179 insertions, 259 deletions
diff --git a/src/apps/init/main.c b/src/apps/init/main.c
index 368322c..b351615 100644
--- a/src/apps/init/main.c
+++ b/src/apps/init/main.c
@@ -9,31 +9,45 @@
int main(int argc, char **argv) {
dbg_print("Hello, world! from user process.\n");
- fd_t f = open("io:/", FM_READDIR);
- dbg_printf("openned /: %d\n", f);
- dirent_t x;
- while (readdir(f, &x)) {
- dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size);
- if (x.st.type == FT_REGULAR) {
- char buf[256];
- strcpy(buf, "io:/");
- strcpy(buf+4, x.name);
- dbg_printf("trying to open %s...\n", buf);
- fd_t ff = open(buf, FM_READ);
- if (ff != 0) {
- dbg_printf("ok, open as %d\n", ff);
- char* cont = malloc(x.st.size + 1);
- dbg_print_region_info();
- read(ff, 0, x.st.size, cont);
- cont[x.st.size] = 0;
- dbg_printf("> '%s'\n", cont);
- close(ff);
- } else {
- dbg_printf("Could not open '%s'\n", buf);
+ {
+ fd_t f = open("io:/", FM_READDIR);
+ dbg_printf("openned io:/ as %d\n", f);
+ dirent_t x;
+ size_t ent_no = 0;
+ while (readdir(f, ent_no++, &x)) {
+ dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size);
+ if (x.st.type == FT_REGULAR) {
+ char buf[256];
+ strcpy(buf, "io:/");
+ strcpy(buf+4, x.name);
+ dbg_printf("trying to open %s...\n", buf);
+ fd_t ff = open(buf, FM_READ);
+ if (ff != 0) {
+ dbg_printf("ok, open as %d\n", ff);
+ char* cont = malloc(x.st.size + 1);
+ dbg_print_region_info();
+ read(ff, 0, x.st.size, cont);
+ cont[x.st.size] = 0;
+ dbg_printf("> '%s'\n", cont);
+ close(ff);
+ } else {
+ dbg_printf("Could not open '%s'\n", buf);
+ }
}
}
+ close(f);
+ }
+
+ {
+ fd_t f = open("root:/", FM_READDIR);
+ dbg_printf("openned root:/ as %d\n", f);
+ dirent_t x;
+ size_t ent_no = 0;
+ while (readdir(f, ent_no++, &x)) {
+ dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size);
+ }
+ close(f);
}
- close(f);
return 0;
}
diff --git a/src/common/include/syscallproto.h b/src/common/include/syscallproto.h
index 507bc2b..7b85a49 100644
--- a/src/common/include/syscallproto.h
+++ b/src/common/include/syscallproto.h
@@ -22,7 +22,7 @@
#define SC_CLOSE 31 // args: fd
#define SC_READ 32 // args: fd, offset, size, out char* data
#define SC_WRITE 33 // args: fd, offset, size, data
-#define SC_READDIR 34 // args: fd, out dirent_t *data
+#define SC_READDIR 34 // args: fd, ent_no, out dirent_t *data
#define SC_STAT_OPEN 35 // args: fd, out stat_t *data -- stat on open file handle
#define SC_IOCTL 36 // args: fd, command, out void* data
#define SC_GET_MODE 37 // args: fd -- get mode for open file handle
diff --git a/src/kernel/dev/pciide.c b/src/kernel/dev/pciide.c
index 927e9da..05c0b28 100644
--- a/src/kernel/dev/pciide.c
+++ b/src/kernel/dev/pciide.c
@@ -645,13 +645,13 @@ typedef struct {
uint8_t type;
} ide_vfs_dev_t;
-static bool ide_vfs_open(fs_node_ptr n, int mode, fs_handle_t *s);
+static bool ide_vfs_open(fs_node_ptr n, int mode);
static bool ide_vfs_stat(fs_node_ptr n, stat_t *st);
-static size_t ide_vfs_read(fs_handle_ptr f, size_t offset, size_t len, char* buf);
-static size_t ide_vfs_write(fs_handle_ptr f, size_t offset, size_t len, const char* buf);
-static int ide_vfs_ioctl(fs_handle_ptr f, int command, void* data);
-static void ide_vfs_close(fs_handle_ptr f);
+static size_t ide_vfs_read(fs_node_ptr f, size_t offset, size_t len, char* buf);
+static size_t ide_vfs_write(fs_node_ptr f, size_t offset, size_t len, const char* buf);
+static int ide_vfs_ioctl(fs_node_ptr f, int command, void* data);
+static void ide_vfs_close(fs_node_ptr f);
static fs_node_ops_t ide_vfs_node_ops = {
.open = ide_vfs_open,
@@ -660,17 +660,12 @@ static fs_node_ops_t ide_vfs_node_ops = {
.delete = 0,
.move = 0,
.create = 0,
- .dispose = 0
-};
-
-static fs_handle_ops_t ide_vfs_handle_ops = {
+ .dispose = 0,
.read = ide_vfs_read,
.write = ide_vfs_write,
.ioctl = ide_vfs_ioctl,
.close = ide_vfs_close,
.readdir = 0,
- .get_page = 0,
- .commit_page = 0
};
void ide_register_device(ide_controller_t *c, uint8_t device, fs_t *iofs) {
@@ -700,7 +695,7 @@ void ide_register_device(ide_controller_t *c, uint8_t device, fs_t *iofs) {
}
}
-bool ide_vfs_open(fs_node_ptr n, int mode, fs_handle_t *s) {
+bool ide_vfs_open(fs_node_ptr n, int mode) {
ide_vfs_dev_t *d = (ide_vfs_dev_t*)n;
int ok_modes = (FM_READ
@@ -708,10 +703,6 @@ bool ide_vfs_open(fs_node_ptr n, int mode, fs_handle_t *s) {
| FM_IOCTL);
if (mode & ~ok_modes) return false;
- s->ops = &ide_vfs_handle_ops;
- s->data = d;
- s->mode = mode;
-
return true;
}
@@ -725,7 +716,7 @@ bool ide_vfs_stat(fs_node_ptr n, stat_t *st) {
return true;
}
-size_t ide_vfs_read(fs_handle_ptr f, size_t offset, size_t len, char* buf) {
+size_t ide_vfs_read(fs_node_ptr f, size_t offset, size_t len, char* buf) {
ide_vfs_dev_t *d = (ide_vfs_dev_t*)f;
if (offset % d->block_size != 0) return 0;
@@ -737,7 +728,7 @@ size_t ide_vfs_read(fs_handle_ptr f, size_t offset, size_t len, char* buf) {
return len;
}
-size_t ide_vfs_write(fs_handle_ptr f, size_t offset, size_t len, const char* buf) {
+size_t ide_vfs_write(fs_node_ptr f, size_t offset, size_t len, const char* buf) {
ide_vfs_dev_t *d = (ide_vfs_dev_t*)f;
if (offset % d->block_size != 0) return 0;
@@ -749,7 +740,7 @@ uint8_t err = ide_write_sectors(d->c, d->device,
return len;
}
-int ide_vfs_ioctl(fs_handle_ptr f, int command, void* data) {
+int ide_vfs_ioctl(fs_node_ptr f, int command, void* data) {
ide_vfs_dev_t *d = (ide_vfs_dev_t*)f;
int ret = 0;
@@ -762,7 +753,7 @@ int ide_vfs_ioctl(fs_handle_ptr f, int command, void* data) {
return ret;
}
-void ide_vfs_close(fs_handle_ptr f) {
+void ide_vfs_close(fs_node_ptr f) {
// nothing to do
}
diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c
index 958bd9a..192f8ae 100644
--- a/src/kernel/fs/iso9660.c
+++ b/src/kernel/fs/iso9660.c
@@ -8,14 +8,14 @@ static void iso9660_fs_shutdown(fs_ptr f);
static bool iso9660_node_stat(fs_node_ptr n, stat_t *st);
static void iso9660_node_dispose(fs_node_ptr n);
-static bool iso9660_dir_open(fs_node_ptr n, int mode, fs_handle_t *s);
+static void iso9660_node_close(fs_node_ptr f);
+
+static bool iso9660_dir_open(fs_node_ptr n, int mode);
static bool iso9660_dir_walk(fs_node_ptr n, const char* file, struct fs_node *node_d);
-static bool iso9660_file_open(fs_node_ptr n, int mode, fs_handle_t *s);
+static bool iso9660_dir_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d);
-static size_t iso9660_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf);
-static void iso9660_fh_close(fs_handle_ptr f);
-static bool iso9660_dh_readdir(fs_handle_ptr f, dirent_t *d);
-static void iso9660_dh_close(fs_handle_ptr f);
+static bool iso9660_file_open(fs_node_ptr n, int mode);
+static size_t iso9660_file_read(fs_node_ptr f, size_t offset, size_t len, char* buf);
static fs_driver_ops_t iso9660_driver_ops = {
.make = iso9660_make,
@@ -34,6 +34,11 @@ static fs_node_ops_t iso9660_dir_ops = {
.delete = 0,
.move = 0,
.create = 0,
+ .readdir = iso9660_dir_readdir,
+ .close = iso9660_node_close,
+ .read = 0,
+ .write = 0,
+ .ioctl = 0,
};
static fs_node_ops_t iso9660_file_ops = {
@@ -44,26 +49,11 @@ static fs_node_ops_t iso9660_file_ops = {
.delete = 0,
.move = 0,
.create = 0,
-};
-
-static fs_handle_ops_t iso9660_dh_ops = {
- .readdir = iso9660_dh_readdir,
- .close = iso9660_dh_close,
- .read = 0,
- .write = 0,
- .ioctl = 0,
- .get_page = 0,
- .commit_page = 0,
-};
-
-static fs_handle_ops_t iso9660_fh_ops = {
.readdir = 0,
- .close = iso9660_fh_close,
- .read = iso9660_fh_read,
+ .close = iso9660_node_close,
+ .read = iso9660_file_read,
.write = 0,
.ioctl = 0,
- .get_page = 0,
- .commit_page = 0,
};
void register_iso9660_driver() {
@@ -144,7 +134,7 @@ static void dr_stat(iso9660_dr_t *dr, stat_t *st) {
if (dr->flags & ISO9660_DR_FLAG_DIR) {
st->type = FT_DIR;
st->access = FM_READDIR;
- st->size = (dr->size.lsb / 256);
+ st->size = dr->size.lsb; // TODO: precise item count ?
} else {
st->type = FT_REGULAR;
st->access = FM_READ;
@@ -166,21 +156,13 @@ void iso9660_node_dispose(fs_node_ptr n) {
free(node);
}
-bool iso9660_dir_open(fs_node_ptr n, int mode, fs_handle_t *s) {
- iso9660_node_t *node = (iso9660_node_t*)n;
+void iso9660_node_close(fs_node_ptr f) {
+ // nothing to do
+}
+bool iso9660_dir_open(fs_node_ptr n, int mode) {
if (mode != FM_READDIR) return false;
- iso9660_dh_t *handle = (iso9660_dh_t*)malloc(sizeof(iso9660_dh_t));
- if (handle == 0) return false;
-
- handle->n = node;
- handle->pos = 0;
-
- s->mode = mode;
- s->data = handle;
- s->ops = &iso9660_dh_ops;
-
return true;
}
@@ -220,7 +202,11 @@ bool iso9660_dir_walk(fs_node_ptr n, const char* search_for, struct fs_node *nod
n->fs = node->fs;
node_d->data = n;
- node_d->ops = (dr->flags & ISO9660_DR_FLAG_DIR ? &iso9660_dir_ops : &iso9660_file_ops);
+ if (dr->flags & ISO9660_DR_FLAG_DIR) {
+ node_d->ops = &iso9660_dir_ops;
+ } else {
+ node_d->ops = &iso9660_file_ops;
+ }
return true;
}
@@ -228,18 +214,13 @@ bool iso9660_dir_walk(fs_node_ptr n, const char* search_for, struct fs_node *nod
return false; // not found
}
-bool iso9660_file_open(fs_node_ptr n, int mode, fs_handle_t *s) {
- iso9660_node_t *node = (iso9660_node_t*)n;
-
+bool iso9660_file_open(fs_node_ptr n, int mode) {
if (mode != FM_READ) return false;
- s->data = node;
- s->ops = &iso9660_fh_ops;
- s->mode = mode;
return true;
}
-size_t iso9660_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf) {
+size_t iso9660_file_read(fs_node_ptr f, size_t offset, size_t len, char* buf) {
iso9660_node_t *node = (iso9660_node_t*)f;
if (offset >= node->dr.size.lsb) return 0;
@@ -277,43 +258,49 @@ size_t iso9660_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf) {
return ret;
}
-void iso9660_fh_close(fs_handle_ptr f) {
+void iso9660_file_close(fs_node_ptr f) {
// nothing to do
}
-bool iso9660_dh_readdir(fs_handle_ptr f, dirent_t *d) {
- iso9660_dh_t *handle = (iso9660_dh_t*)f;
- iso9660_node_t *node = handle->n;
+bool iso9660_dir_readdir(fs_node_ptr n, size_t ent_no, dirent_t *d) {
+ // Very nonefficient !!
- while (true) {
- if (handle->pos >= node->dr.size.lsb) return false;
+ iso9660_node_t *node = (iso9660_node_t*)n;
- if (handle->pos % 2048 == 0) {
- if (file_read(node->fs->disk, node->dr.lba_loc.lsb * 2048 + handle->pos, 2048, handle->buffer) != 2048)
+ char buffer[2048];
+ size_t dr_len = 0;
+ size_t idx = 0;
+ for (size_t pos = 0; pos < node->dr.size.lsb; pos += dr_len) {
+ if (pos % 2048 == 0) {
+ if (file_read(node->fs->disk, node->dr.lba_loc.lsb * 2048 + pos, 2048, buffer) != 2048)
return false;
}
- iso9660_dr_t *dr = (iso9660_dr_t*)(handle->buffer + (handle->pos % 2048));
- if (node->fs->use_lowercase) convert_dr_to_lowercase(dr);
+ iso9660_dr_t *dr = (iso9660_dr_t*)(buffer + (pos % 2048));
+ dr_len = dr->len;
+ if (dr_len == 0) return false;
- handle->pos += dr->len;
+ if (node->fs->use_lowercase) convert_dr_to_lowercase(dr);
+ char* name = dr->name;
size_t len = dr->name_len - 2;
- if (dr->name_len > 0 && dr->name[len] == ';') {
+
+ if (name[len] != ';') continue;
+
+ if (idx == ent_no) {
+ // Found the node we are interested in
if (len >= DIR_MAX) len = DIR_MAX - 1;
- memcpy(d->name, dr->name, len);
+ memcpy(d->name, name, len);
d->name[len] = 0;
+
dr_stat(dr, &d->st);
return true;
+ } else {
+ idx++;
}
- // else skip this record
}
-}
-
-void iso9660_dh_close(fs_handle_ptr f) {
- iso9660_dh_t* handle = (iso9660_dh_t*)f;
- free(handle);
+ return false; // not found
}
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h
index 066211b..6372850 100644
--- a/src/kernel/include/vfs.h
+++ b/src/kernel/include/vfs.h
@@ -32,42 +32,25 @@
// - The VFS does not implement any locking mechanism on filesystems themselves (e.g. the add_source
// implementation must have its own locking system)
-typedef void* fs_handle_ptr;
typedef void* fs_node_ptr;
typedef void* fs_ptr;
// usefull forward declarations
struct fs;
struct fs_node;
-struct fs_handle;
typedef struct user_region user_region_t;
// -------------------------------------------
// Structure defining a handle to an open file
-
-typedef struct {
- // Standard read-write architecture
- size_t (*read)(fs_handle_ptr f, size_t offset, size_t len, char* buf);
- size_t (*write)(fs_handle_ptr f, size_t offset, size_t len, const char* buf);
- bool (*readdir)(fs_handle_ptr f, dirent_t *d);
- int (*ioctl)(fs_handle_ptr f, int command, void* data);
- void (*close)(fs_handle_ptr f);
- // Page cache architecture, must be implemented by all files opened with FM_MMAP
- uint32_t (*get_page)(fs_handle_ptr f, size_t offset);
- void (*commit_page)(fs_handle_ptr f, size_t offset, uint64_t time); // notifies change
-} fs_handle_ops_t;
+// This structure is entirely managed by the VFS, the underlying filesystem does not see it
typedef struct fs_handle {
- // These field are filled by the VFS's generic open() code
struct fs *fs;
struct fs_node *node;
int refs;
- // These fields are filled by the FS's specific open() code
- fs_handle_ops_t *ops;
- fs_handle_ptr data;
int mode;
} fs_handle_t;
@@ -89,8 +72,15 @@ typedef struct fs_handle {
// - delete() is not expected to delete recursively : it should fail on a non-empty directory
typedef struct {
- bool (*open)(fs_node_ptr n, int mode, fs_handle_t *s); // open current node
+ bool (*open)(fs_node_ptr n, int mode);
+ size_t (*read)(fs_node_ptr f, size_t offset, size_t len, char* buf);
+ size_t (*write)(fs_node_ptr f, size_t offset, size_t len, const char* buf);
+ bool (*readdir)(fs_node_ptr f, size_t ent_no, dirent_t *d);
+ void (*close)(fs_node_ptr f);
+
bool (*stat)(fs_node_ptr n, stat_t *st);
+ int (*ioctl)(fs_node_ptr f, int command, void* data);
+
bool (*walk)(fs_node_ptr n, const char* file, struct fs_node *node_d);
bool (*delete)(fs_node_ptr n, const char* file);
bool (*move)(fs_node_ptr dir, const char* old_name, struct fs_node *new_parent, const char *new_name);
@@ -180,9 +170,6 @@ bool file_stat(fs_handle_t *f, stat_t *st);
size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf);
size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf);
int file_ioctl(fs_handle_t *f, int command, void* data);
-bool file_readdir(fs_handle_t *f, dirent_t *d);
-
-uint32_t file_get_page(fs_handle_t *f, size_t offset);
-void file_commit_page(fs_handle_t *f, size_t offset, uint64_t time);
+bool file_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d);
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index 534b0ba..77bc3e8 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -12,27 +12,23 @@ static bool nullfs_fs_make(fs_handle_t *source, const char* opts, fs_t *d);
static void nullfs_fs_shutdown(fs_ptr fs);
// nullfs directory node
-static bool nullfs_d_open(fs_node_ptr n, int mode, fs_handle_t *s);
+static bool nullfs_d_open(fs_node_ptr n, int mode);
static bool nullfs_d_stat(fs_node_ptr n, stat_t *st);
static bool nullfs_d_walk(fs_node_ptr n, const char* file, struct fs_node *node_d);
static bool nullfs_d_delete(fs_node_ptr n, const char* file);
static bool nullfs_d_move(fs_node_ptr n, const char* old_name, fs_node_t *new_parent, const char *new_name);
static bool nullfs_d_create(fs_node_ptr n, const char* file, int type);
static void nullfs_d_dispose(fs_node_ptr n);
-
-// nullfs directory handle
-static bool nullfs_dh_readdir(fs_handle_ptr f, dirent_t *d);
-static void nullfs_dh_close(fs_handle_ptr f);
+static bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d);
+static void nullfs_d_close(fs_node_ptr f);
// nullfs ram file node
-static bool nullfs_f_open(fs_node_ptr n, int mode, fs_handle_t *s);
+static bool nullfs_f_open(fs_node_ptr n, int mode);
static bool nullfs_f_stat(fs_node_ptr n, stat_t *st);
static void nullfs_f_dispose(fs_node_ptr n);
-
-// nullfs ram file handle
-static size_t nullfs_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf);
-static size_t nullfs_fh_write(fs_handle_ptr f, size_t offset, size_t len, const char* buf);
-static void nullfs_fh_close(fs_handle_ptr f);
+static size_t nullfs_f_read(fs_node_ptr f, size_t offset, size_t len, char* buf);
+static size_t nullfs_f_write(fs_node_ptr f, size_t offset, size_t len, const char* buf);
+static void nullfs_f_close(fs_node_ptr f);
// VTables that go with it
static fs_driver_ops_t nullfs_driver_ops = {
@@ -52,11 +48,8 @@ static fs_node_ops_t nullfs_d_ops = {
.move = nullfs_d_move,
.create = nullfs_d_create,
.dispose = nullfs_d_dispose,
-};
-
-static fs_handle_ops_t nullfs_dh_ops = {
- .readdir = nullfs_dh_readdir,
- .close = nullfs_dh_close,
+ .readdir = nullfs_d_readdir,
+ .close = nullfs_d_close,
.read = 0,
.write = 0,
.ioctl = 0,
@@ -70,12 +63,9 @@ static fs_node_ops_t nullfs_f_ops = {
.create = 0,
.delete = 0,
.move = 0,
-};
-
-static fs_handle_ops_t nullfs_fh_ops = {
- .read = nullfs_fh_read,
- .write = nullfs_fh_write,
- .close = nullfs_fh_close,
+ .read = nullfs_f_read,
+ .write = nullfs_f_write,
+ .close = nullfs_f_close,
.readdir = 0,
.ioctl =0,
};
@@ -104,13 +94,9 @@ typedef struct {
mutex_t lock;
nullfs_t *fs;
-} nullfs_dir_t;
-typedef struct {
- nullfs_dir_t *d;
- int nitems, i;
- dirent_t *items;
-} nullfs_dh_t;
+ fs_node_t *vfs_node;
+} nullfs_dir_t;
typedef struct {
char* data;
@@ -119,6 +105,8 @@ typedef struct {
int ok_modes;
mutex_t lock; // locked on open
+
+ fs_node_t *vfs_node;
} nullfs_file_t;
// No nullfs_file_handle_t struct, we don't need it. The handle's data
@@ -235,54 +223,10 @@ bool nullfs_add_ram_file(fs_t *fs, const char* name, char* data, size_t init_sz,
// -- Directory node --
-bool nullfs_d_open(fs_node_ptr n, int mode, fs_handle_t *s) {
+bool nullfs_d_open(fs_node_ptr n, int mode) {
if (mode != FM_READDIR) return false;
- nullfs_dir_t* d = (nullfs_dir_t*)n;
-
- bool got_lock = mutex_try_lock(&d->lock);
- if (!got_lock) return false;
-
- nullfs_dh_t *h = (nullfs_dh_t*)malloc(sizeof(nullfs_dh_t));
- if (h == 0) goto fail;
-
- h->nitems = hashtbl_count(d->items_idx);
- if (h->nitems > 0) {
- h->items = (dirent_t*)malloc(h->nitems * sizeof(dirent_t));
- if (h->nitems == 0) goto fail;
-
- int i = 0;
- for (nullfs_item_t *it = d->items_list; it != 0; it = it->next) {
- strncpy(h->items[i].name, it->name, DIR_MAX);
- h->items[i].name[DIR_MAX-1] = 0; // make sur it's null-terminated
- if (it->ops->stat) {
- it->ops->stat(it->data, &h->items[i].st);
- } else {
- // no stat operation : should we do something else ?
- memset(&h->items[i].st, 0, sizeof(stat_t));
- }
-
- i++;
- }
- ASSERT(i == h->nitems);
- }
-
- h->d = d;
- h->i = 0;
-
- s->data = h;
- s->ops = &nullfs_dh_ops;
- s->mode = FM_READDIR;
-
- mutex_unlock(&d->lock);
-
return true;
-
-fail:
- mutex_unlock(&d->lock);
- if (h && h->items) free(h->items);
- if (h) free(h);
- return false;
}
bool nullfs_d_stat(fs_node_ptr n, stat_t *st) {
@@ -296,9 +240,7 @@ bool nullfs_d_stat(fs_node_ptr n, stat_t *st) {
| (d->fs->can_move ? FM_DMOVE : 0)
| (d->fs->can_delete ? FM_DDELETE : 0);
- st->size = 0;
- for (nullfs_item_t *i = d->items_list; i != 0; i = i->next)
- st->size++;
+ st->size = hashtbl_count(d->items_idx);
mutex_unlock(&d->lock);
@@ -468,32 +410,45 @@ void nullfs_d_dispose(fs_node_ptr n) {
// nothing to do
}
+bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d) {
+ // Very nonefficient !!
-// -- Directory handle --
+ nullfs_dir_t *h = (nullfs_dir_t*)f;
-bool nullfs_dh_readdir(fs_handle_ptr f, dirent_t *d) {
- nullfs_dh_t *h = (nullfs_dh_t*)f;
+ mutex_lock(&h->lock);
- int i = h->i;
- if (i >= h->nitems) {
- return false;
- } else {
- memcpy(d, &h->items[i], sizeof(dirent_t));
- h->i++;
- return true;
+ bool ok = false;
+ size_t idx = 0;
+ for (nullfs_item_t *i = h->items_list; i != 0; i = i->next) {
+ if (idx == ent_no) {
+ ok = true;
+
+ strncpy(d->name, i->name, DIR_MAX);
+ d->name[DIR_MAX-1] = 0;
+ if (i->ops->stat) {
+ i->ops->stat(i->data, &d->st);
+ } else {
+ // no stat operation : should we do something else ?
+ memset(&d->st, 0, sizeof(stat_t));
+ }
+
+ break;
+ }
+ idx++;
}
-}
-void nullfs_dh_close(fs_handle_ptr f) {
- nullfs_dh_t *h = (nullfs_dh_t*)f;
+ mutex_unlock(&h->lock);
- if (h->items) free(h->items);
- free(h);
+ return ok;
+}
+
+void nullfs_d_close(fs_node_ptr f) {
+ // Nothing to do
}
// -- File node --
-bool nullfs_f_open(fs_node_ptr n, int mode, fs_handle_t *s) {
+bool nullfs_f_open(fs_node_ptr n, int mode) {
nullfs_file_t *f = (nullfs_file_t*)n;
if (mode & ~f->ok_modes) return false;
@@ -510,10 +465,6 @@ bool nullfs_f_open(fs_node_ptr n, int mode, fs_handle_t *s) {
mutex_unlock(&f->lock);
}
- s->mode = mode;
- s->data = f;
- s->ops = &nullfs_fh_ops;
-
return true;
}
@@ -535,7 +486,7 @@ void nullfs_f_dispose(fs_node_ptr n) {
// -- File handle --
-static size_t nullfs_fh_read(fs_handle_ptr h, size_t offset, size_t len, char* buf) {
+static size_t nullfs_f_read(fs_node_ptr h, size_t offset, size_t len, char* buf) {
nullfs_file_t *f = (nullfs_file_t*)h;
mutex_lock(&f->lock);
@@ -552,7 +503,7 @@ end_read:
return ret;
}
-static size_t nullfs_fh_write(fs_handle_ptr h, size_t offset, size_t len, const char* buf) {
+static size_t nullfs_f_write(fs_node_ptr h, size_t offset, size_t len, const char* buf) {
nullfs_file_t *f = (nullfs_file_t*)h;
mutex_lock(&f->lock);
@@ -581,7 +532,7 @@ end_write:
return ret;
}
-static void nullfs_fh_close(fs_handle_ptr h) {
+static void nullfs_f_close(fs_node_ptr h) {
// nothing to do
}
diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c
index 4dea882..3f8da08 100644
--- a/src/kernel/user/process.c
+++ b/src/kernel/user/process.c
@@ -290,7 +290,7 @@ bool munmap(process_t *proc, void* addr) {
if (ent & PTE_PRESENT) {
if ((ent & PTE_DIRTY) && (r->mode & MM_WRITE) && r->file != 0) {
- file_commit_page(r->file, it - r->addr + r->file_offset, proc->last_ran);
+ // TODO COMMIT PAGE!!
}
pd_unmap_page(it);
if (r->file != 0) {
@@ -343,7 +343,8 @@ static void proc_usermem_pf(void* p, registers_t *regs, void* addr) {
if (r->file == 0) {
frame = frame_alloc(1);
} else {
- frame = file_get_page(r->file, addr - r->addr + r->file_offset);
+ PANIC("Not implemented mmap (AWFUL TODO)");
+ // Here we must get the page from the cache
}
if (frame == 0) {
free_some_memory();
diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c
index 3def3b5..3041c6d 100644
--- a/src/kernel/user/syscall.c
+++ b/src/kernel/user/syscall.c
@@ -237,9 +237,9 @@ static uint32_t readdir_sc(sc_args_t args) {
fs_handle_t *h = proc_read_fd(current_process(), args.a);
if (h == 0) return false;
- dirent_t *o = (dirent_t*)args.b;
+ dirent_t *o = (dirent_t*)args.c;
probe_for_write(o, sizeof(dirent_t));
- return file_readdir(h, o);
+ return file_readdir(h, args.b, o);
}
static uint32_t stat_open_sc(sc_args_t args) {
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index 710326a..a02dc9b 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -420,12 +420,13 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) {
fs_handle_t *h = (fs_handle_t*)malloc(sizeof(fs_handle_t));
if (h == 0) goto error;
+ bool open_ok = n->ops->open(n->data, mode);
+ if (!open_ok) goto error;
+
h->refs = 1;
h->fs = fs;
h->node = n;
-
- bool open_ok = n->ops->open(n->data, mode, h);
- if (!open_ok) goto error;
+ h->mode = mode;
// our reference to node n is transferred to the file handle
mutex_unlock(&n->lock);
@@ -446,7 +447,7 @@ void ref_file(fs_handle_t *file) {
void unref_file(fs_handle_t *file) {
file->refs--;
if (file->refs == 0) {
- file->ops->close(file->data);
+ file->node->ops->close(file->node->data);
unref_fs_node(file->node);
unref_fs(file->fs);
free(file);
@@ -460,17 +461,17 @@ int file_get_mode(fs_handle_t *f) {
size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) {
if (!(f->mode & FM_READ)) return 0;
- if (f->ops->read == 0) return 0;
+ if (f->node->ops->read == 0) return 0;
- return f->ops->read(f->data, offset, len, buf);
+ return f->node->ops->read(f->node->data, offset, len, buf);
}
size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) {
if (!(f->mode & FM_WRITE)) return 0;
- if (f->ops->write == 0) return 0;
+ if (f->node->ops->write == 0) return 0;
- return f->ops->write(f->data, offset, len, buf);
+ return f->node->ops->write(f->node->data, offset, len, buf);
}
bool file_stat(fs_handle_t *f, stat_t *st) {
@@ -480,27 +481,15 @@ bool file_stat(fs_handle_t *f, stat_t *st) {
int file_ioctl(fs_handle_t *f, int command, void* data) {
if (!(f->mode & FM_IOCTL)) return -1;
- if (f->ops->ioctl == 0) return -1;
+ if (f->node->ops->ioctl == 0) return -1;
- return f->ops->ioctl(f->data, command, data);
+ return f->node->ops->ioctl(f->node->data, command, data);
}
-bool file_readdir(fs_handle_t *f, dirent_t *d) {
+bool file_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d) {
if (!(f->mode & FM_READDIR)) return 0;
- return f->ops->readdir && f->ops->readdir(f->data, d);
-}
-
-uint32_t file_get_page(fs_handle_t *f, size_t offset) {
- if (!(f->mode & FM_MMAP)) return 0;
- ASSERT(f->ops->get_page != 0);
- return f->ops->get_page(f->data, offset);
-}
-
-void file_commit_page(fs_handle_t *f, size_t offset, uint64_t time) {
- if (!(f->mode & FM_MMAP)) return;
- ASSERT(f->ops->commit_page != 0);
- f->ops->commit_page(f->data, offset, time);
+ return f->node->ops->readdir && f->node->ops->readdir(f->node->data, ent_no, d);
}
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/lib/include/syscall.h b/src/lib/include/syscall.h
index 246c84c..c26a805 100644
--- a/src/lib/include/syscall.h
+++ b/src/lib/include/syscall.h
@@ -32,7 +32,7 @@ fd_t open(const char* name, int mode);
void close(fd_t file);
size_t read(fd_t file, size_t offset, size_t len, char *buf);
size_t write(fd_t file, size_t offset, size_t len, const char* buf);
-bool readdir(fd_t file, dirent_t *d);
+bool readdir(fd_t file, size_t ent_no, dirent_t *d);
bool stat_open(fd_t file, stat_t *s);
int ioctl(fd_t file, int command, void* data);
int get_mode(fd_t file);
diff --git a/src/lib/libkogata/syscall.c b/src/lib/libkogata/syscall.c
index 88e9aa2..6f37c47 100644
--- a/src/lib/libkogata/syscall.c
+++ b/src/lib/libkogata/syscall.c
@@ -77,8 +77,8 @@ size_t read(fd_t file, size_t offset, size_t len, char *buf) {
size_t write(fd_t file, size_t offset, size_t len, const char* buf) {
return call(SC_WRITE, file, offset, len, (uint32_t)buf, 0);
}
-bool readdir(fd_t file, dirent_t *d) {
- return call(SC_READDIR, file, (uint32_t)d, 0, 0, 0);
+bool readdir(fd_t file, size_t ent_no, dirent_t *d) {
+ return call(SC_READDIR, file, ent_no, (uint32_t)d, 0, 0);
}
bool stat_open(fd_t file, stat_t *s) {
return call(SC_STAT_OPEN, file, (uint32_t)s, 0, 0, 0);