먼저 나는 엑스트라를 안 해서 Buffer cache가 사용되면 어떻게 코드를 작성해야 할 지는 모른다. "We recommend integrating the cache into your design early."라 적혀있는 것을 보면... 그러니 엑스트라까지 할 생각이면 이 글을 참고하는게 독이 될 수도 있다.
프로젝트 4는 시작하기 전에 꼭 FAT에 대해 이해하고 시작하자!!! 무지성 코딩으로 시작하면 싹 다 갈아엎어야 한다!!!!
그래서 FAT에 대해 다시 보자. FAT는 대략적으로 세가지 구간으로 디스크를 나눈다. 우리가 사용할 것은 두번째와 세번째 부분이고, 세번째 데이터를 보관하는 부분의 섹터를 FAT를 이용해 관리한다. 이 Table은 두번째 부분에 저장된다. fat_fs.fat_start 부터 fat_fs.data_start 까지의 부분이 Table을 저장하는 부분이다.
Skeleton을 읽어보면 알겠지만, Table은 알아서 만들어지고 알아서 저장된다. 그러니 fat_fs_init만 구현하면 Table을 활용할 수 있다. 나머지 fat 메소드들은 큰 문제없이쭉쭉 배운대로 구현해나가면 된다. FAT를 다룰때는 sync 문제가 생길 수도 있다하니 나는 lock을 안전빵으로 걸어두었다.
fat_create에서 ROOT_DIR_CLUSTER가 단순히 calloc으로 0으로 채워진 것을 확인할 수 있다. 이것 때문에 루트디렉토리를 찾지 못해 문제가 생기기도 한다. 그래서 나는 dir_create로 채워주었다.
또 이 FAT를 사용하기 위해서 inode.c와 filesys.c를 수정해주어야 한다. 특히 indoe_write_at와 inode_read_at와 같은 시스템콜을 구현하는 함수들을 fat에 맞게고쳐주자. byte_to_sector 함수 또한 고쳐야 한다. 이 과정을 할 때 섹터가 나뉘는 경계 바이트들을 잘 처리해주는게 중요하다. 단순한 구현이니 생각하고 코딩하면 큰 문제 없을 것이다.
다음으로 file_growth까지 구현하면
FAIL tests/filesys/extended/dir-empty-name
FAIL tests/filesys/extended/dir-mk-tree
FAIL tests/filesys/extended/dir-mkdir
FAIL tests/filesys/extended/dir-open
FAIL tests/filesys/extended/dir-over-file
FAIL tests/filesys/extended/dir-rm-cwd
FAIL tests/filesys/extended/dir-rm-parent
pass tests/filesys/extended/dir-rm-root
FAIL tests/filesys/extended/dir-rm-tree
FAIL tests/filesys/extended/dir-rmdir
FAIL tests/filesys/extended/dir-under-file
FAIL tests/filesys/extended/dir-vine
pass tests/filesys/extended/grow-create
FAIL tests/filesys/extended/grow-dir-lg
pass tests/filesys/extended/grow-file-size
pass tests/filesys/extended/grow-root-lg
pass tests/filesys/extended/grow-root-sm
pass tests/filesys/extended/grow-seq-lg
pass tests/filesys/extended/grow-seq-sm
pass tests/filesys/extended/grow-sparse
pass tests/filesys/extended/grow-tell
pass tests/filesys/extended/grow-two-files
pass tests/filesys/extended/syn-rw
FAIL tests/filesys/extended/symlink-file
FAIL tests/filesys/extended/symlink-dir
FAIL tests/filesys/extended/symlink-link
FAIL tests/filesys/buffer-cache/bc-easy
FAIL tests/filesys/extended/dir-empty-name-persistence
FAIL tests/filesys/extended/dir-mk-tree-persistence
FAIL tests/filesys/extended/dir-mkdir-persistence
FAIL tests/filesys/extended/dir-open-persistence
FAIL tests/filesys/extended/dir-over-file-persistence
FAIL tests/filesys/extended/dir-rm-cwd-persistence
FAIL tests/filesys/extended/dir-rm-parent-persistence
FAIL tests/filesys/extended/dir-rm-root-persistence
FAIL tests/filesys/extended/dir-rm-tree-persistence
FAIL tests/filesys/extended/dir-rmdir-persistence
FAIL tests/filesys/extended/dir-under-file-persistence
FAIL tests/filesys/extended/dir-vine-persistence
FAIL tests/filesys/extended/grow-create-persistence
FAIL tests/filesys/extended/grow-dir-lg-persistence
FAIL tests/filesys/extended/grow-file-size-persistence
FAIL tests/filesys/extended/grow-root-lg-persistence
FAIL tests/filesys/extended/grow-root-sm-persistence
FAIL tests/filesys/extended/grow-seq-lg-persistence
FAIL tests/filesys/extended/grow-seq-sm-persistence
FAIL tests/filesys/extended/grow-sparse-persistence
FAIL tests/filesys/extended/grow-tell-persistence
FAIL tests/filesys/extended/grow-two-files-persistence
FAIL tests/filesys/extended/syn-rw-persistence
FAIL tests/filesys/extended/symlink-file-persistence
FAIL tests/filesys/extended/symlink-dir-persistence
FAIL tests/filesys/extended/symlink-link-persistence
와 같이 될 것이다. (생략된 테스트케이스들은 모두 pass이다)
다음으로 subdirectory와 symlink를 구현해보자.
Subdirectory에서 삽질하기 쉬운 포인트들은:
- .과 ..은 파일로 구현하자. 내부에서 이를 처리하는 로직 구현하는 것보다 쉽다
- thread가 접근하고 있는 현재 디렉토리는 malloc해서 저장하자. 경우에 따라 다르지만 thread의 최대 크기를 넘어가서 경우에 따라 터질 수도 있다.
정도인듯 하다. 파일 이름 14바이트 제한은 계속 유지해도 상관없다.
Symbolic link를 구현할 때 생각해야 할 점은:
- symlink는 폴더같이 사용가능하다.
- symlink를 삭제하면 link된 원본이 삭제되는게 아니라 link만 삭제해야 한다
정도이다. 테스트케이스를 읽어보면 금방 확인할 것이다.
이번 프로젝트에서 오류나기 쉬운 것들:
- inode_open하면 inode_close를 꼭 해줘야 한다!!! 안하면 저장이 안 된다.
- ~~~persistence 테스트 케이스들은 make tests/~~~/~~~persistence.result 방식으로 테스트가 안 된다. make check나 make grade로 결과를 확인하자
- persistence 테스트케이스들 같은 경우 build 안 테스트케이스 디렉토리에서 .tar파일을 확인해볼 수 있다. 반디집 등 압축프로그램으로 열리니 눈으로 안에 무엇이 들었고 무엇이 빠졌는지 확인해가며 해도 편하다.(make grade에서 어떤 파일이 다른지 보여주기도 한다)
- sector의 시작점을 어떻게 할 것인지 정해야 한다. 나는 data_start 되는 섹터를 0번째 섹터로 정했다. 그리고 그 offset은 inode.c의 disk_read/disk_write에서 반영해주었다.
그리고 이번 프로젝트에서도 마찬가지로 memory leak이 되더라도 큰 문제없이 테스트케이스들이 돌아가니 앞 프로젝트 구간에서 free등에 오류가 나는 부분이 있으면 진짜 급한 경우 그냥 지워버리면 된다. 물론 시간이 여유있다면 고치는게 좋겠지만.