diff options
| author | Miguel <m.i@gmx.at> | 2018-09-14 20:23:24 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-14 20:23:24 +0200 |
| commit | fdf6100721870780319bc7cc766a0bb5b4789965 (patch) | |
| tree | f30ff5b21ee557ec5dcd5ccddb7b2a1abc46db1c /fs/ext2.c | |
| parent | 1195ca0bd84693fd56f6d34a9f2de3107b9820bf (diff) | |
ext2 improved , struggling with scheduler
Diffstat (limited to 'fs/ext2.c')
| -rw-r--r-- | fs/ext2.c | 302 |
1 files changed, 120 insertions, 182 deletions
@@ -10,6 +10,7 @@ #include "fs.h" +// THE SUPERBLOCK typedef struct ext2_superblock_struct { uint32_t inodes_count; @@ -35,7 +36,7 @@ typedef struct ext2_superblock_struct uint16_t gid_reserved; }ext2_superblock; -/* we dont use this yet +/* we dont use this typedef struct ext2_superblock_ext_struct { uint32_t first_inode; @@ -61,6 +62,7 @@ typedef struct ext2_superblock_ext_struct }ext2_superblock_ext; */ +// BLOCKGROUP DESCRIPTOR TABLE typedef struct ext2_blockgroup_desc_struct { uint32_t addr_block_bitmap; @@ -97,271 +99,207 @@ typedef struct ext2_inode_struct uint32_t indirect2; uint32_t indirect3; uint32_t gen_num; - uint32_t later1; // will be implemented later by the fooldriver + uint32_t acl; uint32_t size_high; uint32_t frag; uint32_t os_spec2[3]; }ext2_inode; - -void ram_read(char *in,char *out,int size, int count) +static ext2_superblock *ext2_check(uint32_t ext2_start_addr) { - for(int i=0;i<size*count;i++) - { - out[i]=in[i]; + ext2_superblock *super=ext2_start_addr+1024; + if(super->ext2_sig!=0xef53){ + kpanic("no ext2 signature found, where ram-image expected at addr: 8X%08X",ext2_start_addr+1024); } + return super; } -int ext2_check(uint8_t *ram) +void ext2_dump_info(uint32_t ext2_start_addr) { - ext2_superblock super; -// ext2_superblock_ext super_ext; - uint8_t *ptr=ram+1024; - ram_read((char*)ptr,&super,sizeof(super),1); - - if(super.ext2_sig!=0xef53){ - klog("addr: 0x%08X",ram); - kpanic("no ext2 signature found, where ram-image expected"); - } - return 1; + ext2_superblock *super=ext2_check(ext2_start_addr); + klog("ext2 fs version %d.%d found",super->version_major, super->version_minor); + klog("block_size %d",1024<<super->block_size); + klog("blocks per group %d",super->blocks_per_group); + klog("inodes per group %d",super->inodes_per_group); + klog("free inodes: %d / %d",super->inodes_unalloc_count,super->inodes_count+super->inodes_unalloc_count); + klog("free blocks: %d / %d (%d reserved)",super->blocks_unalloc_count,super->blocks_count+super->blocks_unalloc_count,super->blocks_reserved_count); } -ext2_inode ext2_get_inode(uint8_t *ram,int inode_num) +// inode numbers start a 1! +ext2_inode *ext2_get_inode(uint32_t ext2_start_addr,uint32_t inode_num) { + uint32_t ptr; //will temporarily hold adress of some structs - // get basic shit from superblock! - ext2_superblock super; - ext2_blockgroup_desc desc; - ext2_inode inode; - - uint8_t *ptr=ram+1024; - ram_read((char*)ptr,&super,sizeof(super),1); - if(super.ext2_sig!=0xef53) - { - klog("addr: 0x%08X",ram); - kpanic("no ext2 signature found, where ram-image expected!"); - } - - int block_group=(inode_num-1)/super.inodes_per_group; + // check signature and get pointer to superblock. + ext2_superblock *super=ext2_check(ext2_start_addr); - // get descrtptor for our blockgroup! - //TODO: only correct for 1024bytes/block. read more than one!!! - int block_size=1024; - int descriptor_start_block=2; + // get blockgroup descriptor for the block group containing + // our inode. + int block_group=(inode_num-1)/super->inodes_per_group; + int descriptor_start_block=1024<<super->block_size==1024?2:1; - ptr=ram+block_size*descriptor_start_block; - ptr+=sizeof(desc)*block_group; // skip to our descriptor; + ptr=ext2_start_addr+(1024<<super->block_size)*descriptor_start_block; + ptr+=sizeof(ext2_blockgroup_desc)*block_group; // skip to descriptor for our inode's block + ext2_blockgroup_desc *desc=ptr; - ram_read((char*)ptr,&desc,sizeof(desc),1); // read descriptor - - // read our inode; - ptr=ram+block_size*desc.addr_inode_table; - ptr+=128*((inode_num-1)%super.inodes_per_group); - - ram_read((char*)ptr,&inode,sizeof(inode),1); //get inode 2 (rood-directory) + // read the inode + ptr=ext2_start_addr+(1024<<super->block_size)*desc->addr_inode_table; + ptr+=128*((inode_num-1)%super->inodes_per_group); + ext2_inode *inode=ptr; return inode; - } -void* ext2_get_blockstart(void* start, uint32_t block_size, uint32_t block_idx) +static void* ext2_get_blockstart(void* start, uint32_t block_size, uint32_t block_idx) { return (start+block_size*block_idx); } -void* ext2_get_indirectstart(void *start, uint32_t block_size, uint32_t indirect1_idx, uint32_t block_idx) +static void* ext2_get_indirectstart(void *start, uint32_t block_size, uint32_t indirect1_idx, uint32_t block_idx) { uint32_t *indirect_ptr=ext2_get_blockstart(start,block_size,indirect1_idx); void *ptr=ext2_get_blockstart(start,block_size,indirect_ptr[block_idx]); return ptr; } -void* ext2_get_indirectstart_double(void *start, uint32_t block_size, uint32_t indirect2_idx, uint32_t block_idx) +static void* ext2_get_indirectstart_double(void *start, uint32_t block_size, uint32_t indirect2_idx, uint32_t block_idx) { - //doubly indirect list uint32_t *dil=ext2_get_blockstart(start,block_size,indirect2_idx); int indirect1_idx=block_idx/(block_size/4); int idx=block_idx%(block_size/4); - //klog("bl: %d : %d / %d",block_idx,indirect1_idx, idx); return ext2_get_indirectstart(start,block_size,dil[indirect1_idx],idx); } -int ext2_inode_content(char *ram,int inode_nr,uint8_t *ramdest,int max) +// +uint32_t ext2_inode_blockstart(uint32_t ext2_start_addr,uint32_t inode_nr,uint32_t block) { - ext2_check((uint8_t *)ram); - ext2_inode inode=ext2_get_inode((uint8_t*)ram,inode_nr); - - int pos=0; - int block=0; - int block_size=1024; - int block_counter=0; - uint8_t *ptr=ext2_get_blockstart(ram,block_size,inode.direct_pointer[0]); - int sum=0; - int count=0; + ext2_superblock *super=ext2_check(ext2_start_addr); + int block_size=1024<<super->block_size; - klog("Loading %d.%d bytes",inode.size_high, inode.size_low); + ext2_inode *inode=ext2_get_inode(ext2_start_addr,inode_nr); - if(inode.size_high>0)kpanic("inode with high.size unsupported, i am sorry."); + uint8_t *ptr=0; - while(pos<inode.size_low) // TODO: use size high! + if(block<12) { - ramdest[pos]=*ptr; - - sum = (sum >> 1) + ((sum & 1) << 15); - sum+=(int)*ptr; - sum&=0xffff; - count++; - - ptr++; - block_counter++; - pos++; - - if(block_counter>=block_size) - { - block++; - - if(block<12) - { - ptr=ext2_get_blockstart(ram,block_size,inode.direct_pointer[block]); - - } - else if(block-12<block_size/4) - { - ptr=ext2_get_indirectstart(ram,block_size,inode.indirect1,block-12); - } - - else if(block-12-block_size/4<1024/4*1024/4) - { - ptr=ext2_get_indirectstart_double(ram,block_size,inode.indirect2,block-12-block_size/4); - } - else - { - kpanic("Triple Indirect Block Pointers not supported yet, file is too big to load, sorry!"); - } - - - block_counter=0; - } - - + ptr=ext2_get_blockstart(ext2_start_addr,block_size,inode->direct_pointer[block]); } - klog("Fool Check Sum: 0x%08X for %d bytes",sum,count); - return 1; + else if(block-12<block_size/4) + { + ptr=ext2_get_indirectstart(ext2_start_addr,block_size,inode->indirect1,block-12); + } + + else if(block-12-block_size/4<1024/4*1024/4) + { + ptr=ext2_get_indirectstart_double(ext2_start_addr,block_size,inode->indirect2,block-12-block_size/4); + } + + return ptr; } -int ext2_filename_to_inode_traverse(uint8_t *ram, char *path,int inode_start) +static uint32_t ext2_filename_to_inode_traverse(uint32_t ext2_start_addr, char *path,uint32_t inode_start) { + uint32_t len=0; + // true if final filename bool final=false; // skip leading slashes while(*path=='/')path++; char *first=path; - while(*path!='/'&&*path!=0)path++; - char *last=path; + // find end of dir or file name + while(path[len]!='/'&&path[len]!=0)len++; - if(*path==0)final=true; - else(*path=0); + // no more slashes + if(path[len]==0)final=true; - klog("looking for %s '%s' in inode: %d",final?"file":"dir",first,inode_start); + //klog("looking for %s '%s' in inode: %d",final?"file":"dir",first,inode_start); - fs_dirent dirs[25]; - int count= ext2_read_dir(ram, inode_start,dirs,25); // get dir - - for(int i=0;i<count;i++) + uint32_t pos=0; + while(1) { - if(!strcmp_l(first,dirs[i].name,0)) + fs_dirent dirs; + uint32_t ret=ext2_read_dir(VMEM_EXT2_RAMIMAGE,inode_start, &dirs,&pos); + if(!ret)break; + + if(!strcmp_l(first,dirs.name,len)) { - klog("found: %s (%s)",first,dirs[i].type==FS_FILE_TYPE_DIR?"dir":"file"); - if(final)return dirs[i].inode; - return ext2_filename_to_inode_traverse(ram,last+1,dirs[i].inode); + klog("found inode %d %s%s (in inode %d)",dirs.inode,dirs.name,dirs.type==FS_FILE_TYPE_DIR?"/ ":" ",inode_start); + if(final)return dirs.inode; + return ext2_filename_to_inode_traverse(ext2_start_addr,&path[len]+1,dirs.inode); } - //klog("no match: %s",dirs[i].name); } - klog("file not found!"); - return -1; - - - + return 0; } -int ext2_filename_to_inode(uint8_t *ram, char *path) -{ +uint32_t ext2_filename_to_inode(uint32_t ext2_start_addr, char *path) +{ if(!strcmp_l(path,"/",0))return 2; // root is inode 2 by definition - - char buf[256]; - for(int i=0;i<256;i++) - { - buf[i]=path[i]; - if(buf[i]==0)break; - } - - return ext2_filename_to_inode_traverse(ram,buf,2); + return ext2_filename_to_inode_traverse(ext2_start_addr,path,2); } -int ext2_read_dir(uint8_t *ram, int inode_nr,fs_dirent *dirs,int max) +uint32_t ext2_read_inode(uint32_t ext2_start_addr, int inode_nr, char *buf, uint32_t *pos, uint32_t max_size) { + uint32_t count=0; - klog("read_dir : max: %d",max); - ext2_inode inode=ext2_get_inode(ram,inode_nr); - - char buf[256]; - int block_size=1024; - uint8_t *ptr=ram+block_size*inode.direct_pointer[0]; //TODO: use other pointers in future! - - int pos=0; - int c=0; + ext2_superblock *super=ext2_check(ext2_start_addr); + ext2_inode *inode=ext2_get_inode(ext2_start_addr,inode_nr); + uint32_t block_size=1024<<super->block_size; - while(pos<inode.size_low) // use size high? + while((*pos)<inode->size_low) { - if(c==max)break; + if(count==max_size)return count; - // read dir data - ext2_dir dir; - ram_read((char*)ptr,&dir,sizeof(dir),1); + // get ptr to pos + uint32_t block=(*pos)/block_size; + uint32_t ptr = ext2_inode_blockstart(ext2_start_addr,inode_nr,block)+((*pos)%block_size); - // read name - ptr+=sizeof(dir); - ram_read((char*)ptr,&buf,sizeof(char),dir.name_length_low); - ptr+=dir.name_length_low; - buf[dir.name_length_low]=0; + buf[count]=*((char *)ptr); - // increment memory pointer and position - ptr+=dir.size-8-dir.name_length_low; - pos+=dir.size; + *pos+=1; + count++; + } - // copy data over to dirs - dirs[c].inode=dir.inode; + return count; - ext2_inode inode_current=ext2_get_inode(ram,dir.inode); +} - if(inode_current.permissions&0x4000) - { - dirs[c].type=FS_FILE_TYPE_DIR; - } - else - { - dirs[c].type=FS_FILE_TYPE_FILE; - } +int ext2_read_dir(uint32_t ext2_start_addr, int inode_nr, fs_dirent *dirs, uint32_t *pos) +{ + ext2_superblock *super=ext2_check(ext2_start_addr); + ext2_inode *inode=ext2_get_inode(ext2_start_addr,inode_nr); + uint32_t block_size=1024<<super->block_size; - int i=0; - do{ - dirs[c].name[i]=buf[i]; - i++; - }while(buf[i-1]!=0); + while(*pos<inode->size_low) + { + // get ptr to pos + uint32_t block=(*pos)/block_size; + uint32_t ptr = ext2_inode_blockstart(ext2_start_addr,inode_nr,block)+((*pos)%block_size); -// klog("name: %s\n",dirs[c].name); + //dir data + ext2_dir *dir=ptr; - c++; + if(dir->inode) //otherwise skip + { + dirs->type=FS_FILE_TYPE_FILE; + ext2_inode *inode_current=ext2_get_inode(ext2_start_addr,dir->inode); + if(inode_current->permissions&0x4000)dirs->type=FS_FILE_TYPE_DIR; + memcpy(dirs->name,ptr+8,dir->name_length_low); + if(dir->name_length_low>255)dirs->name[255]=0; + dirs->name[dir->name_length_low]=0; // null temrinate + dirs->inode=dir->inode; + + *pos+=dir->size; + return 1; + } + *pos+=dir->size; } - - return c; - + return 0; } |
