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; }