i-node 구조와 파일 데이터 주소 지정 이해하기
Unix 계열 파일시스템의 i-node 구조, 디렉토리 엔트리, inumber와 직접·간접 블록 주소 지정 방식을 정리합니다.
2026-08-14 · 최초 발행 2025-12-28
파일명과 파일 정보를 분리하는 i-node
Unix 계열 파일시스템에서 파일의 이름과 속성은 같은 곳에 저장되지 않는다. 디렉토리는 이름과 i-node 번호를 연결하고, i-node(index node)는 파일명을 제외한 메타데이터와 실제 데이터 블록의 위치를 관리한다.
i-node는 일반적으로 120 bytes의 고정 크기 자료구조이며, 시스템에 따라 128, 256 bytes 크기를 사용하기도 한다. 파일시스템을 만들 때 정해진 개수만큼 미리 할당되고, 파일이나 디렉토리마다 하나의 i-node가 배정된다. 배열 인덱스를 이용해 O(1)로 접근할 수 있다는 점도 이 설계의 기반이다.
파일 권한과 소유권, 링크 수, 타임스탬프, 파일 크기, 데이터 블록 주소가 i-node에 들어간다. 파일명과 속성을 분리했기 때문에 하나의 파일에 여러 이름을 붙이는 하드 링크도 가능하다.
i-node 안에 기록되는 정보
i-node는 파일의 종류와 접근 권한부터 데이터가 놓인 위치까지 보관한다.
파일 타입은 다음과 같이 표현된다.
-: 일반 파일 (Regular File)d: 디렉토리 (Directory)l: 심볼릭 링크 (Symbolic Link)c: 문자 장치 (Character Device)b: 블록 장치 (Block Device)p: 파이프 (Named Pipe/FIFO)s: 소켓 (Socket)
파일 모드는 소유자, 그룹, 기타 사용자 각각의 rwx 권한과 setuid, setgid, sticky bit 같은 특수 비트로 구성된다. 소유권은 UID(User ID)와 GID(Group ID)로 저장한다.
파일 크기는 바이트 단위로 기록하며, 64비트 시스템에서는 최대 9 exabytes를 지원한다. 별도로 실제 디스크에 할당된 512바이트 블록 수도 관리한다. 희소 파일(Sparse File)은 파일 크기에 비해 이 값이 작을 수 있다.
시간 정보도 i-node의 일부다.
atime은 마지막으로 파일 내용을 읽은 시간이며read(),cat등으로 갱신된다.mtime은 마지막으로 파일 내용을 수정한 시간이며write()나 편집으로 갱신된다.ctime은 i-node 정보가 바뀐 시간이다. 권한, 소유자, 링크 수 변경 등이 여기에 해당한다.
링크 수는 이 i-node를 가리키는 디렉토리 엔트리의 개수다. 하드 링크를 만들면 증가하고, 링크 수가 0이 되면 i-node와 데이터 블록이 해제된다.
디렉토리는 이름을 inumber에 연결한다
디렉토리도 파일이며, 그 데이터 블록에는 하위 파일과 디렉토리를 가리키는 엔트리가 저장된다. 각 엔트리는 i-node 번호, 레코드 길이, 파일명 길이, 선택적인 파일 타입, 가변 길이의 파일명으로 이루어진다. 파일명은 최대 255 bytes다.
inumber는 파일시스템 안에서 i-node를 고유하게 식별하는 번호이자 i-node 배열의 인덱스다. 0부터 시작하며, 0과 1번은 예약되고 2번은 루트 디렉토리에 사용된다. 파일명을 바꾸더라도 inumber는 바뀌지 않는다.
ls -i로 inumber를 확인할 수 있고, 같은 번호를 가진 항목은 같은 파일의 하드 링크임을 알 수 있다. find -inum은 특정 inumber로 파일을 찾을 때 사용한다.
$ ls -li
total 24
5678 -rw-r--r-- 2 user group 1024 Jan 15 10:30 file1.txt
5678 -rw-r--r-- 2 user group 1024 Jan 15 10:30 file2.txt # 하드 링크
9012 drwxr-xr-x 3 user group 4096 Jan 15 11:00 subdir
여기서 file1.txt와 file2.txt의 inumber는 모두 5678이므로, 둘은 같은 파일을 가리키는 하드 링크다.
데이터 블록까지 이어지는 포인터
i-node는 파일 데이터가 저장된 블록의 주소를 총 15개의 포인터로 관리한다. 직접 블록 10개와 단일·이중·삼중 간접 블록 포인터가 각각 1개씩 포함된다.
직접 블록은 데이터 블록을 곧바로 가리킨다. 10개를 사용하며 일부 시스템에서는 12개를 사용한다. 포인터는 32비트에서 4 bytes, 64비트에서 8 bytes이고, 블록 크기가 4KB라면 10 × 4KB = 40KB를 다룬다. 데이터는 한 번의 디스크 접근으로 읽을 수 있어 작은 파일에 적합하며, 대부분의 파일은 직접 블록만으로 충분하다.
단일 간접 블록은 데이터 블록 주소들의 배열을 가리킨다. 블록 크기 4KB와 포인터 크기 4 bytes를 기준으로 한 블록에는 4096 / 4 = 1024개 주소를 저장하며, 1024 × 4KB = 4MB를 다룬다. 데이터를 읽으려면 간접 블록과 실제 데이터 블록을 차례로 읽어 2번 디스크에 접근한다.
이중 간접 블록은 단일 간접 블록들의 주소를 담는다. 같은 기준에서 1차 간접 블록이 1024개 주소를 가지며, 각 주소가 가리키는 2차 간접 블록도 1024개 주소를 가진다. 따라서 1024 × 1024 × 4KB = 4GB를 지원하고, 데이터 읽기에는 1차 간접 블록, 2차 간접 블록, 실제 데이터 블록을 읽는 3번의 디스크 접근이 필요하다.
삼중 간접 블록은 이중 간접 블록들의 주소를 담는 방식이다. 1차 간접 블록은 1024개 주소, 2차 간접 블록은 1024 × 1024개 주소, 3차 간접 블록은 1024 × 1024 × 1024개 주소를 관리한다. 블록 크기가 4KB일 때 용량은 1024 × 1024 × 1024 × 4KB = 4TB이며, 데이터를 읽으려면 간접 블록을 세 단계 거친 뒤 실제 데이터 블록을 읽으므로 4번 디스크에 접근한다.
블록 크기 4KB, 포인터 크기 4 bytes를 기준으로 하면 주소 지정 범위는 다음과 같다.
- 직접 블록: 10 × 4KB = 40 KB
- 단일 간접: 1,024 × 4KB = 4 MB
- 이중 간접: 1,024² × 4KB = 4 GB
- 삼중 간접: 1,024³ × 4KB = 4 TB
----------------------------------------
총 최대 크기: 약 4 TB
파일 크기에 따라 달라지는 읽기 경로
40KB 이하의 작은 파일은 직접 블록을 통해 데이터를 읽는다.
4MB 크기의 파일에서는 단일 간접 블록에서 대상 데이터 블록의 주소를 먼저 찾는다.
1GB 크기의 파일은 이중 간접 블록을 경유한다.
캐시와 할당 상태를 함께 관리한다
inode cache는 자주 쓰이는 i-node를 메모리에 보관한다. LRU 정책으로 최근 사용하지 않은 i-node부터 제거하고, 수정된 i-node는 dirty bit로 표시해 디스크 동기화가 필요할 때 기록한다. 이 과정은 디스크 I/O를 대폭 줄인다.
i-node는 가능한 한 연속된 inumber를 할당하고, 디렉토리와 그 하위 파일에 가까운 i-node를 배치해 지역성을 고려한다. 디렉토리별 i-node 블록 그룹을 분리하는 방식도 사용한다.
디스크 공간이 남았는데도 No space left on device 오류가 발생한다면 i-node 고갈을 확인해야 한다. 작은 파일을 대량으로 만들 때 발생할 수 있으며, df -i로 i-node 사용률을 조회한다. 불필요한 파일을 삭제하거나 i-node 수를 늘려 파일시스템을 다시 생성할 수 있고, XFS나 Btrfs처럼 동적 i-node 할당을 지원하는 파일시스템을 사용할 수도 있다.
희소 파일은 중간에 빈 공간이 있는 파일이다. 0으로 채워진 블록을 실제로 할당하지 않아 디스크 공간을 절약하며, i-node에는 할당된 블록 수만 기록된다.
같은 i-node를 공유하는 링크와 별도 파일인 링크
하드 링크는 여러 디렉토리 엔트리가 같은 i-node를 가리키는 구조다. 원본과 링크의 구분이 없고 모든 링크가 동등하다. 링크를 만들면 Link Count가 증가하며, 파일시스템 경계를 넘을 수 없다. rm은 링크 수만 줄이고, 그 수가 0이 된 뒤에 i-node와 데이터 블록이 해제된다.
심볼릭 링크는 대상 파일의 경로를 담는 특수 파일이다. 대상과는 별도의 i-node를 가지고 파일시스템 경계를 넘을 수 있다. 대상 파일이 삭제되면 깨진 링크(Broken Link)가 되며, 데이터 블록에는 대상 경로 문자열이 저장된다.
디스크의 i-node와 메모리의 i-node
디스크 상의 i-node는 i-node 블록 영역에 배열로 저장된다. 크기는 120, 128, 256 bytes처럼 고정되어 있고, 압축된 메타데이터 형태로 시스템 종료 뒤에도 유지된다.
메모리의 in-core inode는 디스크 표현보다 큰 구조체다. 디스크 i-node의 모든 정보에 더해 LRU 링크와 dirty bit 같은 캐시 관리 정보, 동시 접근 제어를 위한 락 정보, 메모리에서 사용 중인 프로세스 수를 나타내는 참조 카운트를 포함한다. 커널의 inode cache가 이를 관리하고, 주기적 또는 명시적 sync로 디스크에 기록한다.