#include <stdio.h> #include <stdlib.h> #include <math.h> #include "ext2sim.h" FILE *fs_file; char fs_state; extern S_SUPERBLOCK superblock; extern FS_INFO info; extern char *block_bitmap; extern char *inode_bitmap; extern S_GROUP_DESCRIPTOR group_desc[MAX_GROUPS]; int mount_fs(char *fname,char state) { int block_size; if(fs_state!=FS_STATE_NOT_MOUNTED) return -1; if(state==FS_STATE_MOUNTED_RW){ fs_file=fopen(fname,"rb+"); if(fs_file==0){ fs_file=fopen(fname,"wb"); if(fs_file==0) return -3; } } if(state==FS_STATE_MOUNTED_RO){ fs_file=fopen(fname,"rb"); if(fs_file==0) return -2; } fs_state=state; if(fs_state!=FS_STATE_MOUNTED_RW&&fs_state!=FS_STATE_MOUNTED_RO) return -5; if(fs_file==0) return -6; if(read_superblock()!=0){ printf("UNKNOWN/EMPTY FS!\n"); deinitialise_bitmaps(); } else{ printf("EXT2FS:\n"); block_size=1024<<superblock.s_log_block_size; info.block_size=block_size; info.sektors_per_block=block_size/512; info.group_desc_start=superblock.s_first_data_block+1; info.first_group_start=info.group_desc_start+info.sektors_per_block; info.group_size=2+superblock.s_blocks_per_group+ceil((double)superblock.s_inodes_per_group*128/1024); info.group_count=ceil((double)superblock.s_inodes_count/(double)superblock.s_inodes_per_group); initialise_bitmaps(); if(read_group_descriptor()!=0){ printf("Can't read group descriptor!\n"); } else{ if(check()==0){ printf("Block size = %d bytes, %d groups\n",block_size,info.group_count); printf("%d free inodes (%d inodes total)\n",superblock.s_free_inodes_count,superblock.s_inodes_count); printf("%d free blocks (%d blocks total)\n",superblock.s_free_blocks_count,superblock.s_block_count); printf("%d free kbytes (%d kbytes total)\n",superblock.s_free_blocks_count*block_size/1024,superblock.s_block_count*block_size/1024); } } } return 0; } int umount_fs(void) { if(fs_state==FS_STATE_NOT_MOUNTED) return -1; fclose(fs_file); fs_state=FS_STATE_NOT_MOUNTED; return 0; } int read_sector(int num,unsigned char buf[512]) { if(fs_state==FS_STATE_NOT_MOUNTED) return -1; fseek(fs_file,num*512,SEEK_SET); if(ftell(fs_file)!=num*512) return -2; if(fread(buf,1,512,fs_file)!=512) return -3; return 0; } int write_sector(int num,unsigned char buf[512]) { if(fs_state!=FS_STATE_MOUNTED_RW) return -1; fseek(fs_file,num*512,SEEK_SET); if(ftell(fs_file)!=num*512) return -2; if(fwrite(buf,1,512,fs_file)!=512) return -3; return 0; } int write_block(int num,int l,unsigned char *buf) { if(fs_state!=FS_STATE_MOUNTED_RW) return -1; fseek(fs_file,num*info.block_size,SEEK_SET); if(ftell(fs_file)!=num*info.block_size) return -2; // if(l>info.block_size) l=info.block_size; if(fwrite(buf,1,l,fs_file)!=l) return -3; return 0; } int read_block(int num,int l,unsigned char *buf) { if(fs_state==FS_STATE_NOT_MOUNTED) return -1; fseek(fs_file,num*info.block_size,SEEK_SET); if(ftell(fs_file)!=num*info.block_size) return -2; // if(l>info.block_size) l=info.block_size; if(fread(buf,1,l,fs_file)!=l) return -3; return 0; } int create_disk(int num) { unsigned char buf[512]; int i; if(fs_state!=FS_STATE_MOUNTED_RW) return -1; fseek(fs_file,0,SEEK_SET); for(i=0;i<512;i++) buf[i]=0; for(i=0;i<num;i++){ if(fwrite(buf,1,512,fs_file)!=512) return -2; } return 0; } int read_inode(int num,S_INODE *inode) { int bl,s,i; unsigned char *buf; num--; if(num<0||num>=superblock.s_inodes_count) return -1; bl=num/superblock.s_inodes_per_group; s=128*superblock.s_inodes_per_group; buf=(unsigned char *) malloc(s); if(buf==0) return -2; if(read_block(group_desc[bl].bg_inode_table,s,buf)!=0){ free(buf); return -3; } bl=(num%superblock.s_inodes_per_group)*128; memcpy((unsigned char *)inode,buf+bl,128); free(buf); return 0; } int read_blocks(unsigned int i_block[15],int l,unsigned char *buf) { int i=0,pos=0,r; while(l>0){ if(i<12){ if(l>info.block_size) r=info.block_size; else r=l; if(read_block(i_block[i],r,buf+pos)!=0) return -1; pos+=info.block_size; l-=info.block_size; } else return -1; i++; } return 0; }