diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-02 23:02:59 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-02 23:02:59 +0100 |
commit | e356371f09df87ebab2d7e3d816de1147768dfa9 (patch) | |
tree | 4932209fc8799bb63006c3ebb11b9a438ae34342 | |
parent | 969c8cacc50e8c39ddbc19e05f3f5b98c34bde01 (diff) | |
download | kogata-e356371f09df87ebab2d7e3d816de1147768dfa9.tar.gz kogata-e356371f09df87ebab2d7e3d816de1147768dfa9.zip |
Change VFS interface : handles no longer visible to underlying FS.
-rw-r--r-- | src/apps/init/main.c | 58 | ||||
-rw-r--r-- | src/common/include/syscallproto.h | 2 | ||||
-rw-r--r-- | src/kernel/dev/pciide.c | 31 | ||||
-rw-r--r-- | src/kernel/fs/iso9660.c | 113 | ||||
-rw-r--r-- | src/kernel/include/vfs.h | 33 | ||||
-rw-r--r-- | src/kernel/user/nullfs.c | 149 | ||||
-rw-r--r-- | src/kernel/user/process.c | 5 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 4 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 37 | ||||
-rw-r--r-- | src/lib/include/syscall.h | 2 | ||||
-rw-r--r-- | src/lib/libkogata/syscall.c | 4 |
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); |