BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / vfs / ext2fs / inode.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
diff --git a/vfs/ext2fs/inode.c b/vfs/ext2fs/inode.c
new file mode 100644
index 0000000..3437220
--- /dev/null
+++ b/vfs/ext2fs/inode.c
@@ -0,0 +1,94 @@
+/*
+ * This file contains the Ext2 inode implementation.  It contains the functions
+ * for the inode operations, as well as several internal operations relating to
+ * inodes required for the full Ext2 implementation.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <fcntl.h>
+#include "fs.h"
+#include "../vfs.h"
+#include "../super.h"
+#include "../../mem/heap.h"
+
+Inode *ext2fs_lookup(Inode *inode, const char *name);
+
+InodeOps ext2fsInodeOps = {
+	.lookup = ext2fs_lookup,
+};
+
+/* Read an Ext2 inode as a VFS inode */
+void
+ext2_read_vnode(SuperBlock *super, uint32_t index, Inode *res)
+{
+	Ext2Inode inode;
+	ext2_read_inode(super, index, &inode);
+
+	res->ino = index;
+	res->usage = 0;
+	res->uid = inode.uid;
+	res->gid = inode.gid;
+	res->mode = inode.type;
+	res->nlink = inode.numHardLinks;
+	res->size = inode.lsize;
+	res->ops = &ext2fsInodeOps;
+	res->fileOps = &ext2fsFileOps;
+	res->super = super;
+}
+
+/* Read an Ext2 inode */
+void
+ext2_read_inode(SuperBlock *super, uint32_t index, Ext2Inode *res)
+{
+	Ext2Super *rsuper = super->data;
+
+	/* Find the Block Group Descriptor */
+	Ext2BlockGroupDesc bgd;
+	uint32_t groups = rsuper->numBlocks / rsuper->blocksPerGroup;
+	uint32_t group = (index - 1) / rsuper->inodesPerGroup;
+	index = (index - 1) % rsuper->inodesPerGroup;
+	if (rsuper->numBlocks % rsuper->blocksPerGroup)
+		groups++;
+	super->back->pos = (rsuper->blockSize ? 1 : 2)
+	                 * (1024 << rsuper->blockSize);
+	super->back->pos += sizeof(Ext2BlockGroupDesc) * group;
+	file_read(super->back, (char *) &bgd, sizeof(Ext2BlockGroupDesc));
+	/* Read Inode */
+	super->back->pos = bgd.inodeTable * (1024 << rsuper->blockSize);
+	super->back->pos += rsuper->inodeSize * index;
+	file_read(super->back, (char *) res, sizeof(Ext2Inode));
+}
+
+/* Look up a file */
+Inode *
+ext2fs_lookup(Inode *vnode, const char *name)
+{
+	char buf[4096];
+	uint32_t block, blk = 0;
+	Ext2DirEntry *de;
+	Ext2Inode inode;
+	ext2_read_inode(vnode->super, vnode->ino, &inode);
+	for (blk = 0; blk < 0xFFFF; blk++) {
+		block = ext2_get_data_addr(vnode->super, &inode, blk);
+		if (!block)
+			return NULL;
+		ext2_read_block(vnode->super, block, buf);
+		for (de = (Ext2DirEntry *) buf;
+		     strncmp(de->name, name, de->nameLen)
+		     && de < (Ext2DirEntry *) (buf + 4096);
+		     de = (void *) ((char *) de + de->size));
+		if (de >= (Ext2DirEntry *) (buf + 4096))
+			return NULL;
+		if (!strncmp(de->name, name, de->nameLen))
+			break;
+	}
+	if (!de->ino)
+		return NULL;
+	Inode *res = super_find_inode(vnode->super, de->ino);
+	if (res)
+		return res;
+	res = kmalloc(sizeof(Inode));
+	ext2_read_vnode(vnode->super, de->ino, res);
+	return res;
+}