아날로그 파일 시스템

8184 단어 Linux 커널
먼저 전체적인 설계를 한 다음에 구체적인 함수를 결합시켜 상세한 분석을 한다.
먼저 시뮬레이션된 하드 드라이브로 약 100M의 파일을 만듭니다.하드디스크의 공간은 모두 세 부분으로 나뉘는데 그것이 바로 슈퍼 블록 구역,inode 구역과 디스크 블록 구역이다.그 중에서 슈퍼 블록 구역은 struct 구조로,inode 구역과 디스크 블록 구역의 사용 상황을 저장한다.노드 구역은 1024개의 노드 블록으로 구성되어 있다.하나의inode 블록은 디렉터리 파일이나 일반 파일에 대응합니다. 그 중에서 대응하는 파일의 파일 형식, 파일 크기, 차지하는 디스크 블록의 수, 그리고 차지하는 디스크 블록 번호를 저장합니다.그리고 매번 파일에 대한 읽기와 쓰기는 해당하는inode의 내용과 대응하는 디스크 블록의 내용을 바꾸면 된다.마지막은 디스크 블록 영역이며 각 디스크 블록의 크기는 1KB입니다.총 1024*80개의 디스크 블록으로 구성되어 있는데 사실 디스크 블록은 특수한 데이터 구조로 표시할 필요가 없다. 대응하는 위치를 찾은 다음에 읽기와 쓰기를 할 때 메모리에 읽고 조작한 후에 하드디스크에 넣으면 된다.
다음에 디렉터리에 대해 말하자면 사실 디렉터리는 하나의 디렉터리 파일로 많은 디렉터리 항목을 포함하고 각 디렉터리 항목은 두 부분으로 구성된다. 1.하위 디렉토리 또는 파일의 파일 이름, 2.이 파일에 대응하는 i 노드입니다.주의해야 할 것은 하위 디렉터리를 만들 때 이 하위 디렉터리의 디렉터리 파일의 내용은 비어 있는 것이 아니라 적어도 두 개의 디렉터리 항목을 포함하고 있다는 것이다."..."과...여기서 파일 이름은 입니다.의 디렉토리 항목은 현재 디렉토리를 나타냅니다. 파일 이름은 "..."는 상위 디렉토리를 나타냅니다."상위 디렉토리에 들어가야 할 때""...""만 찾으면 됩니다."디렉터리 항목에 대응하는inode만 있으면 됩니다.특히 주의해야 할 것은 루트 디렉터리에 있다."..."대응하는inode 번호는 같습니다. 이것은 현재 디렉터리가 루트 디렉터리인지 아닌지를 판단하는 데 조건을 제공합니다.
그 다음은 일반 파일의 작업입니다.일반 파일의 생성은 디렉터리 파일의 생성보다 간단합니다. 왜냐하면 일반 파일은 시작할 때 비어 있을 수 있기 때문입니다.따라서 상응하는 inode 구조를 읽고 초기화하면 된다.파일에 대한 편집은 편집기를 하나 더 쓰기 귀찮아서vim의 인터페이스를 슬기롭게 호출했다.우선 버프를 따로 만듭니다.txt 파일, 파일을 편집할 때, 이 파일의 디스크 블록의 내용을 읽고 버프에 넣습니다.txt에서 하위 프로세스를 호출해서vim로 편집합니다.편집이 끝난 후에 버프를 다시 만듭니다.txt 파일의 내용을 상응하는 파일에 다시 쓰면 파일의 편집 작업도 끝난다.
마지막으로 파일 삭제 작업입니다.일반 파일의 삭제 작업은 비교적 간단하다. 해당하는inode를 읽고 모든 디스크 블록을 풀고, 마지막에 그 자체를 풀면 된다.사실 방출이란 슈퍼 블록 안의 디스크 블록 비트맵이나inode 비트맵의 상응하는 위치를 0으로 설정하면 되고 복잡한 조작이 없다.그러나 디렉터리의 삭제 작업은 비교적 복잡하다. 왜냐하면 한 디렉터리에 보통 다른 파일이 포함되어 있기 때문이다.그래서 Linux 시스템에서 디렉터리를 삭제할 때, 디렉터리가 비어 있지 않고 삭제하지 말라고 알려 줍니다.그러나 이 아날로그 파일 시스템에서는 디렉터리가 비어 있든 없든 간에 포함된 내용을 모두 삭제합니다.이것은 사실 이 시스템에서 가장 조작하기 어려운 부분이다.사용하는 방법은 폴더 삭제입니다. 디렉터리를 만났을 때 하위 디렉터리에 들어가고, 파일을 만났을 때 파일을 삭제하며, 현재 디렉터리에 내용이 없으면 상위 디렉터리로 돌아갑니다.깊이 있게 훑어본 후에 디렉터리 트리 전체가 삭제되었습니다.주의해야 할 것은 삭제해야 하는 루트 디렉터리와 하위 디렉터리의 동작은 다르다는 것이다. 루트 디렉터리는 자신을 삭제해야 할 뿐만 아니라, 부모 디렉터리도 수정해야 한다. 이름과 inode를 포함하는 디렉터리 항목은 부모 디렉터리에 저장된 디렉터리 파일이고, 그 자체에 포함된 하위 디렉터리는 수정할 필요가 없다. 왜냐하면 부모 디렉터리도 삭제되어야 하기 때문이다.이렇게 해서 파일 삭제 작업도 끝났고 시스템 전체도 거의 완성되지 않았다.
구체적인 코드는 다음과 같다.
#include 
#include 
#include 
#include 
#define InodeNum	1024//i    
#define BlkNum		(80*1024)//      
#define BlkSize		1024//      1K
#define BlkPerNode	1024//               
#define DISK 		"disk.txt"
#define BUFF		"buff.txt"//          
#define SuperBeg	0//        
#define InodeBeg	sizeof(SuperBlk)//i       
#define BlockBeg	(InodeBeg+InodeNum*sizeof(Inode))//       
#define MaxDirNum	(BlkPerNode*(BlkSize/sizeof(Dir)))//          
#define DirPerBlk	(BlkSize/sizeof(Dir))//             
#define Directory	0
#define File		1
#define CommanNum	(sizeof(command)/sizeof(char*))//    

typedef struct{
	int inode_map[InodeNum];//i    
	int blk_map[BlkNum];//     
	int inode_used;//     i    
	int blk_used;//          
}SuperBlk;

typedef struct{
	int blk_identifier[BlkPerNode];//        
	int blk_num;//        
	int file_size;//     
	int type;//     
}Inode;

typedef struct{
	char name[30];//   
	short  inode_num;//     inode
}Dir;

Dir 	dir_table[MaxDirNum];//               
int 	dir_num;//         
int	 	inode_num;//     inode  
Inode 	curr_inode;//     inode  
SuperBlk	super_blk;//        
FILE*	Disk;

/*    */
char*	command[]={"fmt","quit","mkdir","rmdir","cd","ls","mk","rm","vim"};
char	path[40]="monster: root";

int init_fs(void);//       
int close_fs(void);//      
int format_fs(void);//       

int open_dir(int);//    inode     
int close_dir(int);//    inode   
int show_dir(int);//    
int make_file(int,char*,int);//         
int del_file(int,char*,int);//     
int enter_dir(int,char*);//     

int file_write(char*);//   
int file_read(char*);//   

int adjust_dir(char*);//      ,     ,      

int check_name(int,char*);//     ,  -1       ,      inode
int type_check(char*);//       

int free_inode(int);//     inode
int apply_inode();//  inode,     inode ,  -1 INODE  
int init_dir_inode(int,int);//        inode
int init_file_inode(int);//        inode

int free_blk(int);//        
int get_blk(void);//     

void change_path(char*);

int main()
{
	char comm[30],name[30];
	char *arg[]={"vim",BUFF,NULL};
	int i,quit=0,choice,status;

	Disk=fopen(DISK,"r+");
	init_fs();

	while(1){
		printf("%s# ",path);
		scanf("%s",comm);
		choice=-1;

		for(i=0;iMaxDirNum){//                
		printf("mkdir: cannot create directory '%s' :Directory full
",name); return 0; } if(check_name(inode,name)!=-1){// printf("mkdir: cannnot create file '%s' :File exist
",name); return 0; } if(dir_num/DirPerBlk!=(dir_num+1)/DirPerBlk){// blk_need=2; } // printf("blk_used:%d
",super_blk.blk_used); if(super_blk.blk_used+blk_need>BlkNum){ printf("mkdir: cannot create file '%s' :Block used up
",name); return 0; } if(blk_need==2){// t=curr_inode.blk_num++; curr_inode.blk_identifier[t]=get_blk(); } /* inode*/ new_node=apply_inode(); if(new_node==-1){ printf("mkdir: cannot create file '%s' :Inode used up
",name); return 0; } if(type==Directory){ /* inode*/ init_dir_inode(new_node,inode); } else if(type==File){ /* inode*/ init_file_inode(new_node); } strcpy(dir_table[dir_num].name,name); dir_table[dir_num++].inode_num=new_node; } /* */ int show_dir(int inode) { int i,color=32; for(i=0;i=InodeNum){ return -1;//inode } super_blk.inode_used++; for(i=0;i=0;--pos) { if(path[pos]=='/') { path[pos]='\0'; break; } } } else {// strcat(path,"/"); strcat(path,name); } return ; } int type_check(char* name) { int i,inode; Inode temp; for(i=0;i

좋은 웹페이지 즐겨찾기