BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / master / vfs / ext2fs / inode.c

// Related

Nucleus

Barry System headers (remove libc dependency) 18495cf (3 years, 2 months ago)
#include <stdint.h>
#include <nucleus/lib.h>
#include <nucleus/vfs.h>
#include "ext2fs.h"

Inode *ext2fs_lookup(Inode *vnode, const char *name);

InodeOps ext2fsInodeOps = {
	.lookup = ext2fs_lookup,
};

/* Read an ext2fs inode */
void
ext2fs_read_inode(SuperBlock *sb, uint32_t index, struct Ext2Inode *res)
{
	struct Ext2Super *rsuper = sb->data;

	/* Find the Block Group Descriptor */
	struct 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++;
	sb->back->pos = (rsuper->blockSize ? 1 : 2)
	              * (1024 << rsuper->blockSize);
	sb->back->pos += sizeof(struct Ext2BlockGroupDesc) * group;
	file_read(sb->back, (char *) &bgd, sizeof(struct Ext2BlockGroupDesc));

	/* Read Inode */
	sb->back->pos = bgd.inodeTable * (1024 << rsuper->blockSize);
	sb->back->pos += rsuper->inodeSize * index;
	file_read(sb->back, (char *) res, sizeof(struct Ext2Inode));
}

/* Read an ext2fs inode as a VFS Inode */
void
ext2fs_read_vnode(SuperBlock *sb, uint32_t index, Inode *res)
{
	struct Ext2Inode inode;
	ext2fs_read_inode(sb, index, &inode);

	res->ino = index;
	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 = sb;
}

/* Lookup an ext2fs file */
Inode *
ext2fs_lookup(Inode *vnode, const char *name)
{
	char buf[PAGE_SIZE];
	uint32_t block, blk = 0;
	struct Ext2DirEntry *de;
	struct Ext2Inode inode;
	ext2fs_read_inode(vnode->super, vnode->ino, &inode);
	for (blk = 0; blk < 0xFFFF; blk++) {
		block = ext2fs_get_data_addr(vnode->super, &inode, blk);
		if (!block)
			return NULL;
		ext2fs_read_block(vnode->super, block, buf);
		for (de = (struct Ext2DirEntry *) buf;
		     strncmp(de->name, name, de->namelen)
		     && de < (struct Ext2DirEntry *) (buf + PAGE_SIZE);
		     de = (void *) de + de->size);
		if (de >= (struct Ext2DirEntry *) (buf + PAGE_SIZE))
			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) {
		res = new(&inodeType);
		ext2fs_read_vnode(vnode->super, de->ino, res);
	}
	return res;
}