모든 이야기

아이노드: 파일 이름을 바꿔도 파일의 정체가 유지되는 이유

유닉스 계열 파일 시스템에서 파일 이름과 파일 자체의 메타데이터는 분리해 관리될 수 있다. 아이노드는 파일 종류, 권한, 소유자, 크기, 시간 정보와 데이터 위치 등을 나타내는 구조다. 디렉터리는 이름을 아이노드 번호에 연결한다. 이 구분 덕분에 이름을 바꾸거나 여러 이름을 같은 파일에 붙이는 동작을 일관되게 설명할 수 있다.

memo.txt와 draft.txt라는 두 디렉터리 항목이 아이노드 42 하나를 가리키고 아이노드가 데이터 블록을 연결하는 그림

파일 이름은 디렉터리가 연결하고 아이노드는 객체의 정보와 데이터 위치를 나타낸다.

디렉터리가 이름을 붙인다

설명용 디렉터리에서 memo.txt가 아이노드 42를 가리킨다고 하자. 프로그램은 경로를 따라 디렉터리 항목을 찾고, 번호에 해당하는 아이노드의 정보로 데이터에 접근한다. 아이노드 자체가 일반적으로 파일 이름을 저장하는 것은 아니다. OSTEP의 파일 시스템 구현 장은 디렉터리와 아이노드, 데이터 블록을 구분해 설명한다.

경로의 각 디렉터리 역시 파일 시스템의 객체다. /notes/memo.txt를 찾으려면 루트에서 notes 항목을 찾고 해당 디렉터리에서 memo.txt를 찾는 식으로 진행한다. 경로 이름은 탐색 방법이며, 마지막에 도달한 아이노드는 파일의 상태와 데이터 연결을 표현한다. 경로를 바꿔도 같은 객체를 가리키면 파일 내용은 그대로일 수 있다.

이름 두 개, 객체 하나

memo.txt와 draft.txt가 모두 아이노드 42를 가리키도록 만들면 하드 링크가 된다. 두 이름 중 하나로 내용을 수정하면 다른 이름으로도 같은 변경을 읽는다. 두 복사본이 우연히 같은 내용을 가진 것과는 다르다. 아이노드의 링크 수는 이런 이름 연결을 관리하며, 일반적으로 하드 링크는 같은 파일 시스템 안에서 만든다.

한 이름을 삭제해도 다른 연결이 남으면 파일 객체와 데이터는 계속 사용된다. 모든 이름이 없어졌더라도 프로세스가 파일을 열어 사용 중이면 데이터가 바로 사라지지 않을 수 있다. 디렉터리 연결 수와 열린 참조의 수명은 함께 고려해야 한다. 그래서 삭제한 로그 파일이 열린 채 남아 디스크 공간을 계속 사용하는 상황을 설명할 수 있다.

데이터의 위치를 나타내는 방법

아이노드는 데이터 자체 전체를 담기보다 데이터 블록을 찾아가는 정보를 담는 경우가 많다. 단순 모델은 직접 포인터와 간접 포인터를 사용한다. 현대 파일 시스템은 연속된 여러 블록을 한 구간으로 표현하는 익스텐트 등 다른 구조를 쓸 수 있다. 모든 아이노드가 같은 개수의 직접·간접 포인터를 가진다고 외우면 구현 차이를 놓친다.

희소 파일은 논리적인 크기 전체에 실제 블록을 배정하지 않을 수 있다. 비어 있는 영역은 읽을 때 0처럼 보이지만 해당 데이터 블록이 존재하지 않을 수 있다. 파일 크기와 디스크에 실제 배정된 용량은 그래서 다르다. 아이노드는 파일의 논리적인 속성과 물리 데이터 배치를 연결하는 역할을 한다.

심볼릭 링크는 대상 경로를 가리키는 별도의 객체다. 대상과 같은 아이노드를 직접 공유하는 하드 링크와 다르며, 대상 경로가 바뀌거나 삭제되면 끊어진 링크가 될 수 있다. 같은 이름 연결이라고 생각하면 삭제와 수정의 동작을 잘못 예상하게 된다. 두 링크가 무엇을 공유하는지부터 구분해야 한다.

아이노드 번호만으로 모든 저장 장치에서 전역적으로 유일한 파일을 식별할 수는 없다. 파일 시스템이나 장치의 구분도 필요하다. 또한 구현에 따라 데이터 공간이 남아 있어도 사용할 아이노드가 부족할 수 있다. 파일 이름, 열린 파일 기술자, 아이노드, 데이터 블록을 구분하면 링크와 삭제, 공간 사용량에 관한 문제를 정확하게 읽을 수 있다.

참고 자료

아이노드: 파일 이름을 바꿔도 파일의 정체가 유지되는 이유 · ariser