'운영체제 FAT 파일시스템'에 해당되는 글 1건

고생 끝에 FAT방식의 파일시스템을 c언어 기반으로 제작하였다.


제작과정에서 문제점과 해결방안을 남긴다.

1. 처음에 파일시스템을 설계할 때 파일이 지워지면 디렉토리의 압축뿐만 아니라 FAT의 압축도 함께 일어나도록 하였다. 하지만 이렇게 되면 처음에 파일을 생성하고 지울 때 는 쉬울지 몰라도 디렉터리를 여러개 생성하고 그 디렉터리 안에 파일이 있는 경우 FAT에 여기저기 흩어져 있을 것이므로 매우 FAT을 재정렬하는 문제는 매우 어렵게 된다. 따라서 fragmentation을 허용하고 다시 파일이나 디렉토리가 생성될 때 fragmentation을 재활용하는 방식으로 수정하였다.

2. create_file 함수를 작성할 때 /* last_sector = 이 디렉토리의 맨 마지막 섹터*/

라는 주석을 보고 이해가 전혀 되지 않았다.

또한 while (FAT[last_sector] != (unsigned short)~0) 이해할 수 없었다.

많은 고민 끝에 last_sector는 현재 디렉토리에서 확장된 디렉터리의 섹터를 나타내는 것으로 보았다. 또한 (unsigned short)~0부분은 처음에 실행하여도 무한 루프를 돌았 다. 이것은 논리적으로 전혀 이해가 안되었고 (unsigned short)0으로 수정하였다.

이렇게 수정하면

while (FAT[last_sector] != (unsigned short)0) {

//(unsigned short)~0에서->(unsigned short)0으로 변경해야 확장된 디렉토리로 넘 어갈 수 있습니다.

last_sector = FAT[last_sector];

}

이러한 코드의 의미는 확장된 다음섹터로 넘어가는 의미가 된다.

3. write_file을 구현 할 때 mini_sh에서 루프를 돌면서 사이즈를 512씩 잘라서 넘겨준다.

이러한 방법도 좋지만 create_file함수에서 매개변수 f_size를 하나를 추가하여 아예 처음 파일을 생성할 때 파일의 속성에 사이즈를 설정하고 오픈파일 테이블에 복사해서 그것을 write_file이 이용하도록 변경하였다. 이렇게 되면 mini_sh의 루프도 사라지고 size를 한번에 넘겨주게 된다.

 

//fs_createfile함수에 파라미터를 추가하였다.

//예를 들어mkfile a 2000 이라고 쉘에 입력하면

//사이즈2000fs_createfile의 파라미터로 전달된다.

int fs_createfile(char *name,int f_size)

 

//파라미터로 전달된 파일의 사이즈를 할당해준다.

ep->size = f_size

//오픈파일 테이블에 복사한다.

open_file_table[fid].size= ep->size;

 

그리고 wrtie_file함수를 쓴다.(위의 3.알고리즘 참조).

 

 

4. remove_file함수를 만들 때 FAT을 변경하는 부분을 만드는 알고리즘을 구현하기가 어 려웠다. 또한 파일의 수가 8개의 n배수였다가 n-1배수로 변경되는 순간 디렉토리를 압 축하는 것도 상당히 애를 먹었다. FAT을 변경하는 것은 파일의 첫 번째 섹터로부터 while문을 따라가며 구현하는 알고리즘을 만들었고 디렉토리를 압축하는 것은

//확장된 디렉토리를 축소하는 함수이다.

void curtail_directory(int files_in_dir,int pre_sector) 이러한 함수를 구현함으로써

해결하였다. 인자에 pre_sector을 받음으로 FAT에서 현재 확장된 디렉토리 이전의 디 렉토리의 섹터를 구해내고 이를 수정하고 현재디렉토리도 함께 수정하는 방식.

 

//파일의첫번째섹터를index로받는다.

index=ep->first_sector;

 

/*FAT 테이블에서 삭제할 부분을 수정한다.

FAT연결고리를 따라가면서 수정한다.*/

while(FAT[index]){

int copy_index=index;

index=FAT[index];

FAT[copy_index]=(unsigned short)~0;

}

FAT[index]=(unsigned short)~0;

 

if((files_in_dir-1)%8==0){//파일의 개수가 8개의 배수가 되는 순간 다시 디렉토리를 축소시켜야한다.

curtail_directory(files_in_dir,cur_dir);//curtail_directory함수이용!

}

5. fs_rmdir을 구현할 때 디렉토리를 삭제하면 디렉토리 안의 파일을 추적하면서 파일을 삭제해주어야 한다. 이 부분은 구현할 수 있었다. 하지만 디렉토리안의 디렉토리는 어 떻게 해결할지 막막했다. 디렉토리안의 디렉토리가 있고 그안에 디렉토리가 있고 계속 있을텐데 이 디렉토리들 안의 파일들까지 다 제거하려면 어떻게 함수를 구현해야 하 는가? -> 재귀함수를 통하여 해결하였다. remove_directory 라는 함수를 통하여 현 재 디렉토리안의 파일과 디렉토리를 추적해나가면서 디렉토리이면 그 디렉토리의 첫 번째 섹터를 다시 remove_directory의 인자로 전달하여 recursive하게 계속 call하 도록 하였다.

6. fsck 파일일관성 검사를 inode가 없는 FAT파일 시스템에서 어떻게 구현해야 할지 고 민했다. 두가지 방식으로 파일 일관성 검사를 진행 하도록 하였다.

1. 블록검사

FAT할당테이블을 보고 사용중인 테이블은 BLOCK_IN_USE 배열에 1로 표시하고 사용중이지 않은 테이블은 FREE_BLOCK 배열에 1로 표시한다. 이 때 두 배열중 에 어느 하나는 1이고 어느 하나는 0이여야 한다. 이는 두 배열의 같은 위치의 원 소를 더해서 값이 1이 되는지 확인 함으로써 해결가능하다.

2. 파일검사

디스크를 읽어서 파일의 개수를 알아내고 이는 파일,디렉토리 생성삭제시 카운트되는 변수 fd_number와 비교된다. 이 두 값이 같으면 일관성이 있는 것이고 같지 않으면 파일시스템 오류이다.

 

7. log_area 구현

로그에 실행할 연산 정보를 기록하는 것까지는 문제가 없었다. 하지만 파일시스템이 크러쉬되고 다시 실행 됬을 때 로그정보 뿐만 아니라 전에 만들었던 파일 및 디렉토 리가 모두 복구가 되어야지 만이 로그에 저장된 삭제연산이 가능하다. 그런데 파일 및 디렉토리를 모두 복구하는 것은 종료하기 전에 이 시스템의 FAT정보와 디스크정보를 모두 파일로 남겨야 함을 뜻한다. 처음에는 atexit 함수를 통하여 종료할 때 파일로 정보를 남기도록 하고 다시 실행하면 복구가 되도록 하였다. 하지만 이렇게 하면 크러 쉬가 될 때 atexit는 실행되지 않으므로 이전의 파일 디렉토리 정보가 저장이 안된다. 크러쉬 될 때 실행되는 함수를 정의할 수 있는 함수는 없었다. 따라서 log정보만 파일 로 기록하고 파일시스템이 크러쉬되고 재부팅 될 때 파일로부터 로그정보를 읽고 실 행되지 않은 연산이 있으면 무효화 하는 것으로 하였다.  


파일시스템.hwp


'이론 > 운영체제' 카테고리의 다른 글

데이터 통신 개요  (0) 2015.09.28
파일과 파일 시스템  (0) 2015.09.27
기억장치 관리  (0) 2015.09.27
프로세스 개요  (0) 2015.09.26
운영체제 개요  (0) 2015.09.26
운영체제 3학년 최종 텀프로젝트.  (0) 2015.03.19
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.