Nucleus
Barry Directory entry object e190987 (3 years, 3 months ago)
diff --git a/include/nucleus/vfs.h b/include/nucleus/vfs.h
index df3be93..fd78c10 100644
--- a/include/nucleus/vfs.h
+++ b/include/nucleus/vfs.h
@@ -6,12 +6,15 @@
#include <nucleus/object.h>
#include <nucleus/memory.h>
+#define NAME_MAX 255
+
typedef struct FSType FSType;
typedef struct FileSystem FileSystem;
typedef struct SuperBlock SuperBlock;
typedef struct SuperOps SuperOps;
typedef struct Inode Inode;
typedef struct InodeOps InodeOps;
+typedef struct DirEntry DirEntry;
typedef Inode *(*mount_callback_t)(FSType *, int, const char *, void *);
@@ -43,19 +46,31 @@ struct Inode {
InodeOps *ops;
SuperBlock *super;
union {
+ ObjectList *dirEntries;
ObjectList *pages;
};
};
struct InodeOps {
};
+/* Structure for a Directory Entry */
+struct DirEntry {
+ Object obj;
+ Inode *inode, *mnt;
+ uint32_t hash;
+ char name[NAME_MAX];
+ SuperBlock *super;
+};
+
extern ObjectType fstypeType;
extern ObjectType fsType;
extern ObjectType inodeType;
+extern ObjectType dirEntryType;
void init_vfs(void);
void register_fstype(const char *name, mount_callback_t mount);
int mount(const char *src, const char *target, const char *type,
unsigned long flags, void *data);
+DirEntry *find_direntry(ObjectList *list, const char *name);
#endif
diff --git a/vfs/direntry.c b/vfs/direntry.c
new file mode 100644
index 0000000..f0953d1
--- /dev/null
+++ b/vfs/direntry.c
@@ -0,0 +1,70 @@
+/*
+ * This file implements the Directory Entry object and associated operations.
+ */
+
+#include <string.h>
+#include <nucleus/object.h>
+#include <nucleus/vfs.h>
+
+/* Information for find callback */
+struct FindData {
+ const char *name;
+ DirEntry *result;
+};
+
+static void direntry_delete(Object *);
+
+ObjectType dirEntryType = {
+ .size = sizeof(DirEntry),
+ .delete = direntry_delete,
+};
+
+/* Hash a file name */
+static uint32_t
+name_hash(const char *name)
+{
+ uint32_t digest = 5381;
+ int c;
+ while (c = *name++)
+ digest = ((digest << 5) + digest) ^ c;
+ return digest;
+}
+
+/* Destroy a Directory Entry */
+static void
+direntry_delete(Object *obj)
+{
+ DirEntry *entry = (void *) obj;
+ if (entry->inode)
+ put(entry->inode);
+}
+
+/* Callback for finding a directory entry by name */
+static int
+compare_direntry_name(void *addr, void *data)
+{
+ DirEntry *entry = (void *) addr;
+ struct FindData *find = data;
+ uint32_t hash = name_hash(find->name);
+ if (entry->hash != hash)
+ return 0;
+ if (strcmp(entry->name, find->name))
+ return 0;
+ find->result = get(entry);
+ return 1;
+}
+
+/* Find a Directory Entry by name in a list */
+DirEntry *
+find_direntry(ObjectList *list, const char *name)
+{
+ lock(list);
+ struct FindData data = {
+ .name = name,
+ .result = NULL,
+ };
+ iterate(list, compare_direntry_name, &data);
+ unlock(list);
+ return data.result;
+}
+