BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 77a8df88b03707e14f840df6b0daeb9fa081f613 / vfs / inode.c

// Related

Nucleus

Barry FS Object wrapper functions 77a8df8 (3 years, 3 months ago)
diff --git a/vfs/inode.c b/vfs/inode.c
index 6f49c67..c64542d 100644
--- a/vfs/inode.c
+++ b/vfs/inode.c
@@ -7,8 +7,12 @@
  * operation can be called on the particular inode.
  */
 
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
 #include <nucleus/object.h>
 #include <nucleus/memory.h>
+#include <nucleus/task.h>
 #include <nucleus/vfs.h>
 
 static void inode_new(Object *);
@@ -16,6 +20,7 @@ static void inode_delete(Object *);
 
 /* Inode object type */
 ObjectType inodeType = {
+	.name = "INODE",
 	.size = sizeof(Inode),
 	.new = inode_new,
 	.delete = inode_delete,
@@ -26,6 +31,7 @@ static void
 inode_new(Object *obj)
 {
 	Inode *inode = (void *) obj;
+	inode->dirEntries = create_list(&dirEntryType);
 	inode->pages = create_list(&pageType);
 }
 
@@ -36,9 +42,90 @@ inode_delete(Object *obj)
 	Inode *inode = (void *) obj;
 
 	/* Remove inode from the SuperBlock's list */
-//	if (inode->super)
+	if (inode->super) {
 //		super_remove_inode(inode->super, inode);
+		put(inode->super);
+	}
 
 	/* Clean cache */
 	destroy_list(inode->pages);
 }
+
+/* Check if a process has permission to access an inode */
+int
+permission(Inode *inode, int mask)
+{
+	if (!inode)
+		return 0;
+
+	int mode = inode->mode;
+	if (current->euid == inode->uid)
+		mode >>= 6;
+	else if (current->egid == inode->gid)
+		mode >>= 3;
+
+	if (((mode & mask & 0007) == mask) || super_user())
+		return 1;
+	return 0;
+}
+
+/* Create an inode wrapper */
+int
+inode_create(Inode *inode, DirEntry *entry, mode_t mode)
+{
+	if (!inode->ops || !inode->ops->create)
+		return -EINVAL;
+	lock(inode);
+	int err = inode->ops->create(inode, entry, mode);
+	if (!err) {
+		add(inode->dirEntries, entry);
+		entry->inode = super_alloc_inode(inode->super);
+		entry->inode->mode = mode | S_IFREG;
+	}
+	unlock(inode);
+	return err;
+}
+
+/* Find a named entry in a directory inode */
+DirEntry *
+inode_lookup(Inode *inode, const char *name)
+{
+	if (!S_ISDIR(inode->mode))
+		return NULL;
+	lock(inode);
+
+	/* Check cache first */
+	DirEntry *entry = find_direntry(inode->dirEntries, name);
+	if (entry) {
+		get(entry);
+		if (entry->inode)
+			goto end;
+	}
+	/* Try file system lookup */
+	if (!inode->ops || !inode->ops->lookup) {
+		entry = NULL;
+		goto end;
+	}
+	Inode *child = inode->ops->lookup(inode, name);
+
+	/* The file doesn't exist */
+	if (!child) {
+		if (entry)
+			remove(inode->dirEntries, entry);
+		entry = NULL;
+		goto end;
+	}
+
+	/* Fill in DirEntry */
+	if (!entry) {
+		entry = new(&dirEntryType);
+		strncpy(entry->name, name, NAME_MAX);
+		entry->super = inode->super;
+		add(inode->dirEntries, entry);
+	}
+	entry->inode = get(child);
+
+end:
+	unlock(inode);
+	return entry;
+}