diff --git a/CMakeLists.txt b/CMakeLists.txt index 239ef9a..1a7c191 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set(kernel_arch x86_64) set(kernel_name "Mango") set(kernel_exe_name "mango_kernel") -set(generic_src_dirs ds init kernel libc obj sched util vm) +set(generic_src_dirs ds init kernel libc sched util vm) set(kernel_sources "") set(kernel_headers "") diff --git a/obj/object.c b/kernel/object.c similarity index 63% rename from obj/object.c rename to kernel/object.c index 9921a15..3f40f57 100644 --- a/obj/object.c +++ b/kernel/object.c @@ -1,6 +1,6 @@ +#include #include #include -#include #define HAS_OP(obj, opname) ((obj)->ob_type->ob_ops.opname) @@ -9,9 +9,6 @@ static spin_lock_t object_types_lock = SPIN_LOCK_INIT; kern_status_t object_bootstrap(void) { - init_set_objects(); - init_link_objects(); - init_global_namespace(); return KERN_OK; } @@ -56,7 +53,8 @@ struct object *object_create(struct object_type *type) memset(obj_buf, 0x00, type->ob_size); - struct object *obj = (struct object *)((unsigned char *)obj_buf + type->ob_header_offset); + struct object *obj = (struct object *)((unsigned char *)obj_buf + + type->ob_header_offset); obj->ob_type = type; obj->ob_lock = SPIN_LOCK_INIT; @@ -131,64 +129,3 @@ struct object *object_header(void *p) return obj; } - -kern_status_t object_read(struct object *obj, void *p, size_t offset, - size_t max, size_t *nr_read, mango_flags_t flags) -{ - kern_status_t status = KERN_UNSUPPORTED; - - if (obj->ob_type->ob_ops.read) { - status = obj->ob_type->ob_ops.read(obj, p, offset, &max, flags); - } else { - max = 0; - } - - if (nr_read) { - *nr_read = max; - } - - return status; -} - -kern_status_t object_write(struct object *obj, const void *p, size_t offset, - size_t max, size_t *nr_written, mango_flags_t flags) -{ - kern_status_t status = KERN_UNSUPPORTED; - - if (obj->ob_type->ob_ops.write) { - status = obj->ob_type->ob_ops.write(obj, p, offset, &max, flags); - } - - return status; -} - -kern_status_t object_get_child_named(struct object *obj, const char *name, struct object **out) -{ - kern_status_t status = KERN_UNSUPPORTED; - - if (HAS_OP(obj, get_named)) { - status = obj->ob_type->ob_ops.get_named(obj, name, out); - } - - return status; -} - -kern_status_t object_get_child_at(struct object *obj, size_t at, struct object **out) -{ - kern_status_t status = KERN_UNSUPPORTED; - - if (HAS_OP(obj, get_at)) { - status = obj->ob_type->ob_ops.get_at(obj, at, out); - } - - return status; -} - -kern_status_t object_query_name(struct object *obj, char name[OBJECT_NAME_MAX]) -{ - if (HAS_OP(obj, query_name)) { - return obj->ob_type->ob_ops.query_name(obj, name); - } - - return KERN_UNSUPPORTED; -} diff --git a/obj/link.c b/obj/link.c deleted file mode 100644 index db4087c..0000000 --- a/obj/link.c +++ /dev/null @@ -1,62 +0,0 @@ -#include - -#define LINK_CAST(p) OBJECT_C_CAST(struct link, l_base, &link_type, p) - -struct link { - struct object l_base; - char l_name[OBJECT_NAME_MAX]; - struct object *l_dest; -}; - -static struct object_type link_type; - -static kern_status_t link_query_name(struct object *obj, char out[OBJECT_NAME_MAX]) -{ - struct link *link = LINK_CAST(obj); - strncpy(out, link->l_name, OBJECT_NAME_MAX - 1); - out[OBJECT_NAME_MAX - 1] = 0; - - return KERN_OK; -} - -static struct object_type link_type = { - .ob_name = "link", - .ob_size = sizeof(struct link), - .ob_header_offset = offsetof(struct link, l_base), - .ob_ops = { - .query_name = link_query_name, - }, -}; - -void init_link_objects(void) -{ - object_type_register(&link_type); -} - -struct object *link_create(const char *name, struct object *dest) -{ - struct object *link_obj = object_create(&link_type); - if (!link_obj) { - return NULL; - } - - struct link *link = LINK_CAST(link_obj); - - strncpy(link->l_name, name, sizeof link->l_name - 1); - link->l_name[sizeof link->l_name - 1] = 0; - - link->l_dest = object_ref(dest); - - return link_obj; -} - -struct object *link_read_ptr(struct object *link_obj) -{ - struct link *link = LINK_CAST(link_obj); - return link->l_dest; -} - -bool object_is_link(struct object *obj) -{ - return obj->ob_type == &link_type; -} diff --git a/obj/namespace.c b/obj/namespace.c deleted file mode 100644 index 204e73e..0000000 --- a/obj/namespace.c +++ /dev/null @@ -1,334 +0,0 @@ -#include - -#define NAMESPACE_CAST(p) OBJECT_C_CAST(struct object_namespace, ns_base, &ns_type, p) - -static struct object_type ns_type; -static struct object_namespace *global_ns; - -struct object_namespace { - /* root directory set object */ - struct object ns_base; - struct object *ns_root; -}; - -static kern_status_t ns_query_name(struct object *obj, char out[OBJECT_NAME_MAX]) -{ - out[0] = '/'; - out[1] = 0; - return KERN_OK; -} - -static kern_status_t ns_get_child_at(struct object *obj, size_t at, struct object **out) -{ - struct object_namespace *ns = NAMESPACE_CAST(obj); - return object_get_child_at(ns->ns_root, at, out); -} - -static kern_status_t ns_get_child_named(struct object *obj, const char *name, struct object **out) -{ - struct object_namespace *ns = NAMESPACE_CAST(obj); - return object_get_child_named(ns->ns_root, name, out); -} - -static struct object_type ns_type = { - .ob_name = "namespace", - .ob_size = sizeof(struct object_namespace), - .ob_header_offset = offsetof(struct object_namespace, ns_base), - .ob_ops = { - .query_name = ns_query_name, - .get_named = ns_get_child_named, - .get_at = ns_get_child_at, - }, -}; - -void init_global_namespace(void) -{ - object_type_register(&ns_type); - global_ns = object_namespace_create(); -} - -struct object_namespace *global_namespace(void) -{ - return global_ns; -} - -struct object_namespace *object_namespace_create(void) -{ - struct object *ns_object = object_create(&ns_type); - struct object_namespace *ns = NAMESPACE_CAST(ns_object); - ns->ns_root = set_create("/"); - return ns; -} - -static void cleanup_object_path(char *path, size_t len, size_t *parts) -{ - while (path[len - 1] == '/') { - path[--len] = 0; - } - - size_t final_len = len; - *parts = 0; - - int slashes = 0; - for (int i = 0; path[i]; i++) { - if (path[i] == '/') { - slashes++; - continue; - } - - if (slashes < 1) { - continue; - } - - char *from = path + i; - char *to = path + i - slashes + 1; - int count = len - i; - memmove(to, from, count); - final_len -= (slashes - 1); - slashes = 0; - (*parts)++; - } - - path[final_len] = 0; -} - -struct object *ns_header(struct object_namespace *ns) -{ - return &ns->ns_base; -} - -kern_status_t object_namespace_get_object(struct object_namespace *ns, const char *path, struct object **out) -{ - if (*path != '/') { - return KERN_INVALID_ARGUMENT; - } - - while (*path == '/') { - path++; - } - - size_t path_len = strlen(path); - if (path_len == 0) { - *out = object_ref(ns->ns_root); - return KERN_OK; - } - - size_t parts = 0; - char *rpath = kmalloc(path_len + 1, 0); - if (!rpath) { - return KERN_NO_MEMORY; - } - - memcpy(rpath, path, path_len); - rpath[path_len] = 0; - cleanup_object_path(rpath, path_len, &parts); - - char *sp; - char *tok = strtok_r(rpath, "/", &sp); - struct object *cur = ns->ns_root; - - unsigned long flags; - while (tok) { - object_lock_irqsave(cur, &flags); - - struct object *next; - kern_status_t status = object_get_child_named(cur, tok, &next); - if (status != KERN_OK) { - object_unlock_irqrestore(cur, flags); - kfree(rpath); - return status; - } - - object_unlock_irqrestore(cur, flags); - cur = next; - tok = strtok_r(NULL, "/", &sp); - - object_lock_irqsave(cur, &flags); - if (!object_is_link(cur)) { - object_unlock_irqrestore(cur, flags); - continue; - } - - struct object *dest_obj; - dest_obj = link_read_ptr(cur); - object_unlock_irqrestore(cur, flags); - - if (!dest_obj) { - kfree(rpath); - /* TODO better error code for broken links */ - return KERN_INVALID_ARGUMENT; - } - - object_deref(cur); - cur = dest_obj; - } - - kfree(rpath); - - if (object_is_link(cur)) { - struct object *link_dest = link_read_ptr(cur); - object_deref(cur); - cur = object_ref(link_dest); - } - - *out = cur; - return KERN_OK; -} - -kern_status_t object_namespace_create_link(struct object_namespace *ns, const char *linkpath, struct object *dest) -{ - if (*linkpath != '/') { - return KERN_INVALID_ARGUMENT; - } - - while (*linkpath == '/') { - linkpath++; - } - - size_t path_len = strlen(linkpath); - if (path_len == 0) { - return KERN_INVALID_ARGUMENT; - } - - size_t parts = 0; - char *rpath = kmalloc(path_len + 1, 0); - if (!rpath) { - return KERN_NO_MEMORY; - } - - memcpy(rpath, linkpath, path_len); - rpath[path_len] = 0; - cleanup_object_path(rpath, path_len, &parts); - - char *p = rpath + strlen(rpath) - 1; - while (*p != '/' && p >= rpath) { - p--; - } - - if (p == rpath) { - kfree(rpath); - return KERN_INVALID_ARGUMENT; - } - - *p = '\0'; - const char *linkname = p + 1; - - char *sp; - char *tok = strtok_r(rpath, "/", &sp); - struct object *cur = object_ref(ns->ns_root); - - unsigned long flags; - while (tok) { - object_lock_irqsave(cur, &flags); - - struct object *next; - kern_status_t status = object_get_child_named(cur, tok, &next); - if (status == KERN_NO_ENTRY) { - next = set_create(tok); - if (!next) { - object_unlock_irqrestore(cur, flags); - object_deref(cur); - kfree(rpath); - return KERN_NO_MEMORY; - } - - status = set_add_object(cur, next); - - object_unlock_irqrestore(cur, flags); - object_deref(cur); - } else { - object_unlock_irqrestore(cur, flags); - } - - if (status != KERN_OK) { - kfree(rpath); - return status; - } - - cur = next; - tok = strtok_r(NULL, "/", &sp); - } - - struct object *link = link_create(linkname, dest); - kfree(rpath); - - if (!link) { - object_deref(cur); - return KERN_NO_MEMORY; - } - - object_lock_irqsave(cur, &flags); - kern_status_t status = set_add_object(cur, link); - object_unlock_irqrestore(cur, flags); - - object_deref(cur); - object_deref(link); - - return status; -} - -kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj) -{ - if (*path != '/') { - return KERN_INVALID_ARGUMENT; - } - - while (*path == '/') { - path++; - } - - size_t path_len = strlen(path); - if (path_len == 0) { - return set_add_object(ns->ns_root, obj); - } - - size_t parts = 0; - char *rpath = kmalloc(path_len, 0); - if (!rpath) { - return KERN_NO_MEMORY; - } - - memcpy(rpath, path, path_len); - cleanup_object_path(rpath, path_len, &parts); - - char *sp; - char *tok = strtok_r(rpath, "/", &sp); - struct object *cur = ns->ns_root; - - unsigned long flags; - while (tok) { - object_lock_irqsave(cur, &flags); - - struct object *next; - kern_status_t status = object_get_child_named(cur, tok, &next); - if (status == KERN_NO_ENTRY) { - next = set_create(tok); - if (!next) { - object_unlock_irqrestore(cur, flags); - kfree(rpath); - return KERN_NO_MEMORY; - } - - status = set_add_object(cur, next); - } - - if (status != KERN_OK) { - object_unlock_irqrestore(cur, flags); - kfree(rpath); - return status; - } - - object_unlock_irqrestore(cur, flags); - cur = next; - tok = strtok_r(NULL, "/", &sp); - } - - kfree(rpath); - - return set_add_object(cur, obj); -} - -kern_status_t object_unpublish(struct object_namespace *ns, struct object *obj) -{ - return KERN_OK; -} diff --git a/obj/set.c b/obj/set.c deleted file mode 100644 index da75640..0000000 --- a/obj/set.c +++ /dev/null @@ -1,134 +0,0 @@ -#include - -#define SET_CAST(p) OBJECT_C_CAST(struct set, s_base, &set_type, p) - -struct set { - struct object s_base; - struct queue s_list; - char s_name[OBJECT_NAME_MAX]; -}; - -static struct object_type set_type; - -static kern_status_t set_query_name(struct object *obj, char out[OBJECT_NAME_MAX]) -{ - struct set *set = SET_CAST(obj); - strncpy(out, set->s_name, OBJECT_NAME_MAX - 1); - out[OBJECT_NAME_MAX - 1] = 0; - - return KERN_OK; -} - -static kern_status_t set_get_child_at(struct object *obj, size_t at, struct object **out) -{ - struct set *set = SET_CAST(obj); - size_t i = 0; - queue_foreach(struct object, child, &set->s_list, ob_list) { - if (i == at) { - *out = object_ref(child); - return KERN_OK; - } - - i++; - } - - return KERN_NO_ENTRY; -} - -static kern_status_t set_get_child_named(struct object *obj, const char *name, struct object **out) -{ - struct set *set = SET_CAST(obj); - char child_name[OBJECT_NAME_MAX]; - - queue_foreach(struct object, child, &set->s_list, ob_list) { - kern_status_t status = object_query_name(child, child_name); - if (status != KERN_OK) { - continue; - } - - if (!strcmp(child_name, name)) { - *out = object_ref(child); - return KERN_OK; - } - } - - return KERN_NO_ENTRY; -} - -static struct object_type set_type = { - .ob_name = "set", - .ob_size = sizeof(struct set), - .ob_header_offset = offsetof(struct set, s_base), - .ob_ops = { - .query_name = set_query_name, - .get_named = set_get_child_named, - .get_at = set_get_child_at, - }, -}; - -void init_set_objects(void) -{ - object_type_register(&set_type); -} - -struct object *set_create(const char *name) -{ - struct object *set_obj = object_create(&set_type); - if (!set_obj) { - return NULL; - } - - struct set *set = SET_CAST(set_obj); - set->s_list = QUEUE_INIT; - strncpy(set->s_name, name, sizeof set->s_name - 1); - set->s_name[sizeof set->s_name - 1] = 0; - - return set_obj; -} - -kern_status_t set_add_object(struct object *set_obj, struct object *obj) -{ - if (!object_is_set(set_obj)) { - return KERN_INVALID_ARGUMENT; - } - - struct set *set = SET_CAST(set_obj); - - char child_name[OBJECT_NAME_MAX]; - char obj_name[OBJECT_NAME_MAX]; - - kern_status_t status = object_query_name(obj, obj_name); - if (status != KERN_OK) { - return status; - } - - queue_foreach (struct object, child, &set->s_list, ob_list) { - object_query_name(child, child_name); - - if (!strcmp(child_name, obj_name)) { - return KERN_NAME_EXISTS; - } - } - - object_ref(obj); - queue_push_back(&set->s_list, &obj->ob_list); - return KERN_OK; -} - -kern_status_t set_remove_object(struct object *set_obj, struct object *obj) -{ - if (!object_is_set(set_obj)) { - return KERN_INVALID_ARGUMENT; - } - - struct set *set = SET_CAST(set_obj); - queue_delete(&set->s_list, &obj->ob_list); - object_deref(obj); - - return KERN_OK; -} - -bool object_is_set(struct object *obj) -{ - return obj->ob_type == &set_type; -}