고생 끝에 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 이라고 쉘에 입력하면 //사이즈2000이 fs_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정보만 파일 로 기록하고 파일시스템이 크러쉬되고 재부팅 될 때 파일로부터 로그정보를 읽고 실 행되지 않은 연산이 있으면 무효화 하는 것으로 하였다. |
'이론 > 운영체제' 카테고리의 다른 글
데이터 통신 개요 (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 |
댓글을 달아 주세요