BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / blob / 1628fcfdfdf2978ed9ccac96ee7d13bb3dc43a01 / vfs / ext2fs / inode.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
/*
 * 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;
}