Pintos 완주 후 다시 읽기
Project 4의 path, directory, symlink, inode, FAT를 하나의 번역 흐름으로 다시 읽는다.
이 글에서 다루는 것
Project 4는 파일 시스템 기능을 많이 추가한다. 하지만 완성 후 다시 보면 핵심 질문은 하나다. user가 준 문자열 경로를 어떻게 실제 디스크 조각까지 연결할 것인가.
- 상대/절대 경로와 현재 디렉터리
- directory entry와 inode
- symlink 재해석
- 파일 grow와 FAT chain
1. 경로는 문자열이 아니라 탐색 계획이다
/a/link/file 같은 문자열은 파일 자체가 아니다. 루트에서 시작할지 현재 디렉터리에서 시작할지 정하고, 토큰을 하나씩 lookup하면서 inode를 찾아가야 한다.
경로 해석 흐름
while (token != NULL) {
char *next = strtok_r (NULL, "/", &save);
struct inode *inode = NULL;
if (!dir_lookup (dir, token, &inode)) {
free (copy);
dir_close (dir);
return NULL;
}
if (inode_is_symlink (inode) && (follow_final || next != NULL)) {
char *joined = join_symlink_path (inode_symlink_target (inode),
next, save);
struct inode *resolved = NULL;
resolved = resolve_path_from (dir, joined, follow_final, depth + 1);
inode_close (inode);
free (copy);
dir_close (dir);
return resolved;
}
}
2. directory는 특별한 파일처럼 읽을 수 있다
Project 4에서 directory fd가 중요해진다. open이 파일만 여는 것이 아니라 directory도 열 수 있고, readdir, isdir, inumber는 열린 fd가 가리키는 inode 성격을 물어본다.
3. symlink는 파일 복사가 아니라 경로 재해석이다
symlink를 처음 보면 target 파일을 복사하는 기능처럼 오해하기 쉽다. 실제로는 link inode 안에 target 문자열을 저장해두고, 그 link를 따라가야 하는 상황에서 target 경로로 다시 해석한다.
link를 만들 때 파일 내용까지 복제해야 한다고 착각한다. 그러면 target이 directory일 때나 link chain일 때 설명이 깨진다.
link inode는 target 문자열을 품고 있고, open/create/write 흐름에서 필요한 순간 resolve가 다시 돈다.
4. grow는 inode 길이와 FAT chain이 같이 움직여야 한다
파일에 더 큰 offset으로 write가 들어오면 inode 길이만 늘린다고 끝나지 않는다. 새 데이터를 담을 cluster를 FAT에서 확보하고 기존 chain 뒤에 연결해야 한다.
for (candidate = start; candidate < fat_fs->fat_length; candidate++) {
if (candidate > 0 && fat_fs->fat[candidate] == 0)
goto found;
}
found:
fat_fs->fat[candidate] = EOChain;
if (clst != 0)
fat_fs->fat[clst] = candidate;
fat_fs->last_clst = candidate + 1;
이 흐름은 inode_write_at()에서 실제 write 범위에 맞춰 필요한 cluster를 늘리는 동작과 연결된다. inode는 파일의 논리적 길이를 알고, FAT는 그 파일이 디스크의 어떤 cluster들을 따라가야 하는지 기억한다.
검증 감각
이 기준의 Project 4 파일 시스템 구현은 basic/extended 파일 시스템 테스트 146개 PASS 결과를 가진 코드에서 읽었다. buffer cache bonus는 별도 최적화 영역으로 두고, 여기서는 기본/extended 요구 흐름을 기준으로 설명한다.
이번 글에서 기억할 것
- 파일 시스템은 이름을 곧바로 데이터로 바꾸지 않는다. 이름은 directory entry와 inode를 거쳐야 한다.
- symlink는 파일 복사가 아니라 경로 문자열의 재해석이다.
- 파일 grow는 inode length와 FAT chain 확장이 함께 맞아야 통과된다.
스스로 점검
- 상대 경로는 어떤 directory에서 출발하는가?
- symlink의 final component를 따라갈지 말지는 왜 상황마다 달라질 수 있는가?
- 파일 길이가 늘 때 inode와 FAT 중 하나만 수정하면 어떤 문제가 생기는가?
다음 글 예고
마지막 글에서는 user program의 write 요청 하나가 syscall, user pointer 검증, VM, fd table, file, inode, FAT, disk까지 내려가는 전체 경로를 한 번에 따라간다.
한 줄 정리
Project 4의 파일 시스템은 경로 문자열을 inode와 FAT chain으로 번역하는 긴 파이프라인이었다.