subdirectories 들어가기 전 50 fail을 만들어야한다고 하는데 어디서부터 문제일까?
test case 하나하나 잡기에는 너무 많고, 모르겠을 땐 일단 흐름을 잡아보며 진행하다가 do_format에 dir_create(ROOT_DIR_SECTOR, 16)를 추가해주지 않은 것이 문제였다.
/* Formats the file system. */
static void
do_format(void)
{
printf("Formatting file system...");
#ifdef EFILESYS
/* FAT 생성 후 disk에 저장 */
fat_create();
/* Root Directory 생성 */
disk_sector_t root = cluster_to_sector(ROOT_DIR_CLUSTER);
if (!dir_create(root, 16)) // root_dir sector에 dir_entry를 16개 생성
PANIC("root directory creation failed");
fat_close();
#else
free_map_create();
if (!dir_create(ROOT_DIR_SECTOR, 16))
PANIC("root directory creation failed");
free_map_close();
#endif
printf("done.\n");
}
< tests/filesys/extended/grow-create >
Formatting file system...
[do_format] root_dir sector : 33
[dir_create] sector : 33
done.
Boot complete.
Putting 'grow-create' into the file system...
Putting 'tar' into the file system...
Executing 'grow-create':
(grow-create) begin
(grow-create) create "blargle"
(grow-create) open "blargle" for verification
(grow-create) verified contents of "blargle"
(grow-create) close "blargle"
(grow-create) end
grow-create: exit(0)
/* 지정된 섹터의 ENTERY_CNT 항목에 대한 공간이 있는 디렉터리를 만듭니다.
성공하면 true를 반환하고 실패하면 false를 반환합니다.*/
bool
dir_create (disk_sector_t sector, size_t entry_cnt) {
return inode_create (sector, entry_cnt * sizeof (struct dir_entry));
}
데이터의 길이 바이트로 파일 시스템 디스크의 섹터에 새 inode를 쓰는 함수다.
<원래 코드>
bool
inode_create (disk_sector_t sector, off_t length){
struct inode_disk *disk_inode = NULL;
bool success = false;
ASSERT (length >= 0);
ASSERT (sizeof *disk_inode == DISK_SECTOR_SIZE);
disk_inode = calloc (1, sizeof *disk_inode);
if (disk_inode != NULL) {
size_t sectors = bytes_to_sectors (length);
disk_inode->length = length;
disk_inode->magic = INODE_MAGIC;
if (free_map_allocate (sectors, &disk_inode->start)) {
disk_write (filesys_disk, sector, disk_inode);
if (sectors > 0) {
static char zeros[DISK_SECTOR_SIZE];
size_t i;
for (i = 0; i < sectors; i++)
disk_write (filesys_disk, disk_inode->start + i, zeros);
}
success = true;
}
free (disk_inode);
}
return success;
}
<fat 로 수정된 코드 >
bool
inode_create(disk_sector_t sector, off_t length){
struct inode_disk *disk_inode = NULL;
bool success = false;
ASSERT(length >= 0);
ASSERT(sizeof *disk_inode == DISK_SECTOR_SIZE);
disk_inode = calloc(1, sizeof *disk_inode);
if (disk_inode != NULL)
{
size_t sectors = bytes_to_sectors(length); // 주어진 파일 길이를 위한 섹터 수를 계산
disk_inode->length = length;
disk_inode->magic = INODE_MAGIC;
cluster_t cur = 0;
static char zeros[DISK_SECTOR_SIZE];
for (size_t i = 0; i < sectors; i++)
{
if (cur == 0){
cur = fat_create_chain(0); // 새로운 체인 만들기
disk_inode->start = cluster_to_sector(cur); // 체인의 시작점 저장하기
}
else
cur = fat_create_chain(cur);
disk_write(filesys_disk, cluster_to_sector(cur), zeros);
}
disk_write(filesys_disk, sector, disk_inode); // 디스크에 아이노드 내용 기록하기
success = true;
free(disk_inode);
}
return success;
}
<file growth 수정 후>
/* 데이터의 길이 바이트로 inode를 초기화합니다.
* 파일 시스템 디스크의 섹터에 새 inode를 씁니다.
* 성공하면 true를 반환, 메모리 또는 디스크 할당에 실패하면 false를 반환합니다. */
bool
inode_create(disk_sector_t sector, off_t length){
struct inode_disk *disk_inode = NULL;
bool success = false;
ASSERT(length >= 0);
ASSERT(sizeof *disk_inode == DISK_SECTOR_SIZE);
disk_inode = calloc(1, sizeof *disk_inode);
if (disk_inode != NULL){
if (sector == cluster_to_sector(ROOT_DIR_CLUSTER)){
disk_inode->length == DISK_SECTOR_SIZE;
}
disk_inode->length = 0;
disk_inode->magic = INODE_MAGIC;
disk_write(filesys_disk, sector, disk_inode);
success = true;
free(disk_inode);
}
return success;
}
pass tests/filesys/base/syn-write 까지 촤라락 통과 후 50 failed 남았다!
하 해야할 양과 난이도에 비해 시간이 너무 금방간다.. 핀토스로 인해 생긴 화병 ❤️🔥
전체적인 흐름을 이해하지 못했을 때는 test fail이 나면 해당 test를 잡기에 급급했다. 하지만 흐름을 알고 난 후는 test case만을 보고 분석하는 디버깅이 아닌 코드를 읽으면서 디버깅을 하게 되는 것 같다.