struct fat_boot
{
unsigned int magic; // overflow 감지
unsigned int sectors_per_cluster; // cluster 1개가 차지하는 sector 수 -> 1로 고정
unsigned int total_sectors; // disk의 모든 sector 수
unsigned int fat_start; // fat이 시작하는 sector number
unsigned int fat_sectors; // fat이 차지하는 sector 수
unsigned int root_dir_cluster; // root directory의 cluster number
};
struct fat_fs
{
struct fat_boot bs; // filesystem 정보
unsigned int *fat; // fat
unsigned int fat_length; // fat의 길이 -> entry 개수
disk_sector_t data_start; // data block이 시작되는 sector number
cluster_t last_clst; // 마지막 clust
struct lock write_lock; // 쓰기 lock
};
FAT 구조체는 위와 같다.
여기서 cluster란 파일이 저장된 여러개의 디스크 sector 덩어리를 뜻한다. pintos에서는 단순함을 위해 cluster의 크기를 1로 두었다.
void fat_boot_create(void)
{
unsigned int fat_sectors =
(disk_size(filesys_disk) - 1) / (DISK_SECTOR_SIZE / sizeof(cluster_t) * SECTORS_PER_CLUSTER + 1) + 1;
fat_fs->bs = (struct fat_boot){
.magic = FAT_MAGIC,
.sectors_per_cluster = SECTORS_PER_CLUSTER,
.total_sectors = disk_size(filesys_disk),
.fat_start = 1,
.fat_sectors = fat_sectors,
.root_dir_cluster = ROOT_DIR_CLUSTER,
};
}
void fat_init(void)
{
fat_fs = calloc(1, sizeof(struct fat_fs));
if (fat_fs == NULL)
PANIC("FAT init failed");
// Read boot sector from the disk
unsigned int *bounce = malloc(DISK_SECTOR_SIZE);
if (bounce == NULL)
PANIC("FAT init failed");
disk_read(filesys_disk, FAT_BOOT_SECTOR, bounce);
memcpy(&fat_fs->bs, bounce, sizeof(fat_fs->bs));
free(bounce);
// Extract FAT info
if (fat_fs->bs.magic != FAT_MAGIC)
fat_boot_create();
fat_fs_init();
}
void fat_create(void)
{
// Create FAT boot
fat_boot_create();
fat_fs_init();
// Create FAT table
fat_fs->fat = calloc(fat_fs->fat_length, sizeof(cluster_t));
if (fat_fs->fat == NULL)
PANIC("FAT creation failed");
// Set up ROOT_DIR_CLST
fat_put(ROOT_DIR_CLUSTER, EOChain);
// Fill up ROOT_DIR_CLUSTER region with 0
uint8_t *buf = calloc(1, DISK_SECTOR_SIZE);
if (buf == NULL)
PANIC("FAT create failed due to OOM");
disk_write(filesys_disk, cluster_to_sector(ROOT_DIR_CLUSTER), buf);
free(buf);
}