기본 파일 시스템은 파일을 단일한 범위(연속 할당한다는 의미인듯)로 파일을 할당하는데, 이는 외부 단편화에 취약하다. 즉, 이는 n개의 블록이 가용 상태임에도 n개 블록을 점유해야 하는 파일이 할당되지 못한다는 것을 의미한다.(외부 단편화!) on-disk inode 구조를 수정해 이 문제를 제거해라.
실제로, 이것은 아마 직접/간접/이중 간접 인덱스 구조를 사용하라는 의미다. 지난 학기에, 대부분 학생은 멀티 레벨 인덱싱을 사용하는 Berkeley UNIX FFS로 배운 것과 같은 것을 적용했다. 하지만, 우리의 삶을 더 쉽게 하기 위해, 더 쉬운 방식으로 구현하도록 만든다. 그것이 FAT이다. 우리는 주어진 스켈레톤 코드로 반드시 FAT을 구현해야 한다. 우리의 코드는 절대 multi-level indexing에 관한 어떤 코드도 포함해서는 안된다 (ex-FFS).
주의: 우리는 파일 시스템 파티션이 8MB보다 커져서는 안될 것임을 유추할 것이다. 우리는 파티션만큼 큰 파일을 지원해야 한다(단, 메타데이터는 제외). 각 inode는 하나의 디스크 섹터에 저장되어 포함할 수 있는 블록 포인터의 수를 제한한다.
이전 프로젝트까지 우리가 사용했던 기본 파일 시스템에서, 파일은 연속적인 단일 청크 형태로 여러 디스크 섹터에 걸쳐 저장되었다. 연속적인 청크를 cluster라고 하자. 왜냐면 하나의 클러스터는 하나 혹은 그 이상의 연속적인 디스크 섹터를 포함할 수 있기 때문이다. 이 관점에서, 기본 파일 시스템에서 클러스터의 사이즈는 클러스터에 저장된 파일의 크기와 동일하다.
외부 단편화를 완화하기 위해, 우리는 클러스터 사이즈를 축소할 수 있다. (가상 메모리에서 페이지 사이즈를 생각해봐라.) 간단히, 우리의 스켈레톤 코드에서, 우리는 클러스터 내에 섹터 수를 1로 고정했다. 우리가 더 작은 클러스터를 사용할 때, 클러스터는 전체 파일을 저장하기 충분치 않을 지도 모른다. 이 경우, 우리는 하나의 파일을 위해 여러 클러스터가 필요한데, 그래서 우리는 inode에 있는 파일을 위해 클러스터를 인덱싱할 수 있는 자료구조가 필요하다. 한 가지 쉬운 방법은 linked-list를 사용하는 것이다. inode는 파일의 첫번째 블록의 섹터 번호를 담는다. 그리고 첫번째 블록은 두 번째 블록의 섹터 번호를 담을 수 있다. 하지만 이 나이브한 접근방식은 너무 느린데, 왜냐면 비록 우리가 진짜로 필요로 하는 블록이 마지막 블록일지라도 우리는 파일의 모든 블록을 읽어야만 하기 때문이다. 이를 극복하기 위해, FAT(File Allocation Table) 방식에서는 각 블록에 다음 블록 번호를 넣는 방식이 아니라 각 블록의 연결을 고정된 사이즈의 파일 할당 테이블에 넣는다. FAT는 실제 데이터보다 연결 값만 담고 있기 때문에, DRAM 내에 캐싱되기 충분히 작은 사이즈다. 결과적으로, 우리는 단지 이 테이블에서 관련 엔트리를 읽기만 하면 된다.
우리는 filesys/fat.c
에 주어진 스켈레톤 코드로 inode indexing을 구현할 것이다. 이 섹션에서는 fat.c
에서 이미 구현되어 제공되는 함수를 간단히 기술한다. 그리고 우리가 구현해야 하는 함수 역시.
첫째로, fat.c에 있는 6개 함수 (i.e. fat_init()
, fat_open()
, fat_close()
, fat_create()
, and fat_boot_create()
)는 부팅 시에 디스크를 초기화하고 포맷한다. 따라서 우리는 이들을 수정할 필요가 없다. 하지만, 우리는 fat_fs_init()을 작성할 필요가 있을 것이다. 그리고 이들이 왜 무엇을 하는지를 이해하면 도움이 될 것이다.
cluster_t fat_fs_init (void);
FAT 파일 시스템4을 초기화한다. 우리는
fat_length
와fat_fs
의data_start
필드를 초기화할 필요가 있다.fat_length
는 파일 시스템에 얼마나 클러스터가 많은지를 저장하고data_start
는 우리가 파일 저장을 시작할 수 있는 섹터가 어디인지를 저장한다. 우리는fat_fs→bs
에 저장된 몇가지 값을 사용하기를 원할 것이다. 또한, 우리는 이 함수에서 몇가지 다른 유용한 데이터를 초기화하기를 원할 것이다.
cluster_t fat_create_chain (cluster_t clst);