UNIX 파일 시스템에서 inode가 파일을 관리하는 방식
inode가 파일명과 메타데이터를 분리하는 이유, 데이터 블록 주소 지정 방식, 하드 링크·심볼릭 링크와 inode 고갈 대응을 정리한다.
2026-08-14 · 최초 발행 2026-01-12
파일명과 파일 정보를 분리하는 inode
inode(index node, 아이노드)는 UNIX 및 Linux 파일 시스템에서 파일의 메타데이터를 보관하는 자료구조다. 파일 크기, 권한, 소유자, 타임스탬프, 데이터 블록 위치는 inode에 들어가지만 파일명은 포함되지 않는다.
파일명과 inode 번호의 연결은 디렉토리가 맡는다. 각 파일은 파일 시스템 안에서 고유한 inode 번호를 가지며, 디렉토리는 파일명과 inode 번호를 대응시키는 엔트리의 집합이다. 이 구조 때문에 이름을 바꾸는 작업은 디렉토리 엔트리를 바꾸는 일이고, inode와 데이터 블록은 그대로 유지된다.
inode는 1970년대 초 UNIX 파일 시스템 설계에서 등장했으며 Dennis Ritchie와 Ken Thompson이 있던 Bell Labs의 UNIX 계열 구조와 연결된다. 파일명과 실제 파일 정보를 분리해 파일 시스템을 조직하고 관리하는 역할을 한다.
일반적으로 inode의 크기는 128 또는 256 바이트로 고정된다. inode의 개수 역시 파일 시스템을 만들 때 결정된다.
inode에 기록되는 파일 상태
inode는 일반 파일, 디렉토리, 심볼릭 링크, 블록 장치, 문자 장치, FIFO(Named Pipe), 소켓처럼 파일의 유형을 기록한다. 권한 정보는 Owner(소유자), Group(그룹), Others(기타)별 Read(r), Write(w), Execute(x) 권한으로 구성되며 rw-r--r-- (644) 같은 형태로 표현된다.
소유자 정보에는 UID(User ID)와 GID(Group ID)가 들어간다. 파일 크기는 바이트 단위로 기록되고, 시간 정보는 다음과 같이 구분된다.
atime(Access Time): 마지막 접근 시간mtime(Modification Time): 마지막 내용 수정 시간ctime(Change Time): 마지막 inode 변경 시간(권한, 소유자 등)
inode에는 이를 가리키는 하드 링크 수(Link Count)와 파일이 차지하는 데이터 블록 수도 저장된다. 하드 링크 수가 0이 되면 inode와 데이터 블록이 삭제된다.
데이터 블록을 가리키는 포인터는 직접 포인터와 간접 포인터 계열로 나뉜다. 일반적으로 직접 포인터는 12개이며, Single Indirect, Double Indirect, Triple Indirect 포인터는 각각 1개씩 사용된다.
inode 크기의 전형적인 예는 다음과 같다.
- 전통적 UNIX: 128 바이트
- ext4: 256 바이트
- XFS: 512 바이트
디렉토리 엔트리가 파일명을 연결하는 방법
디렉토리도 자체 inode를 가진 파일이다. 그 안에는 파일명과 inode 번호를 연결하는 엔트리가 담긴다.
디렉토리 /home/user:
. → inode 50000
.. → inode 10000
file.txt → inode 12345
doc.pdf → inode 12346
따라서 파일명 변경은 디렉토리 엔트리만 수정하며 inode와 데이터 블록은 변경하지 않는다.
mv oldname.txt newname.txt
# 디렉토리에서 파일명만 변경, inode는 동일
같은 inode를 공유하는 하드 링크
하드 링크는 여러 파일명이 하나의 inode를 함께 가리키는 방식이다. 하드 링크를 생성하면 Link Count가 증가한다.
ln original.txt hardlink.txt
# original.txt와 hardlink.txt는 동일한 inode
파일을 삭제하면 링크 수가 줄어들고, 링크 수가 0이 된 시점에 inode와 데이터 블록이 해제된다. 디렉토리는 순환 참조를 방지하기 위해 하드 링크할 수 없다.
ls -li
# 12345 -rw-r--r-- 2 user group 1024 Jan 01 12:00 original.txt
# 12345 -rw-r--r-- 2 user group 1024 Jan 01 12:00 hardlink.txt
# 동일한 inode 번호 (12345), 링크 수 (2)
경로를 담는 심볼릭 링크
심볼릭 링크는 다른 파일의 경로를 저장하는 별도 파일이다. 원본 파일과는 별개의 inode를 가진다.
ln -s /path/to/original.txt symlink.txt
원본 파일이 삭제되면 심볼릭 링크는 Broken Link가 된다. 반면 디렉토리를 가리키는 심볼릭 링크는 만들 수 있다.
ls -li
# 12345 -rw-r--r-- 1 user group 1024 Jan 01 12:00 original.txt
# 67890 lrwxrwxrwx 1 user group 20 Jan 01 12:05 symlink.txt -> /path/to/original.txt
# 서로 다른 inode 번호
inode 번호를 확인할 때
파일 생성 시 파일 시스템은 빈 inode를 찾아 할당하고 inode 번호를 반환한다. 이 번호는 해당 파일 시스템 안에서는 고유하지만, 다른 파일 시스템에 같은 inode 번호가 존재할 수 있다.
ls -i는 파일명 앞에 inode 번호를 표시한다.
ls -i
# 12345 file.txt
# 12346 doc.pdf
stat은 inode 번호와 함께 크기, 블록 수, 권한, 소유자, 시간 정보를 보여 준다.
stat file.txt
# File: file.txt
# Size: 1024 Blocks: 8 IO Block: 4096 regular file
# Device: 802h/2050d Inode: 12345 Links: 1
# Access: (0644/-rw-r--r--) Uid: (1000/ user) Gid: (1000/ group)
# Access: 2024-01-01 12:00:00.000000000 +0900
# Modify: 2024-01-01 12:00:00.000000000 +0900
# Change: 2024-01-01 12:00:00.000000000 +0900
# Birth: -
특정 inode 번호에 연결된 파일은 find로 찾을 수 있다.
find /path -inum 12345
# inode 번호로 파일 검색
작은 파일과 큰 파일을 연결하는 포인터 계층
직접 포인터는 데이터 블록 번호를 inode에 바로 저장한다. 블록 크기가 4KB이고 직접 포인터가 12개라면 최대 12 × 4KB = 48KB를 다룬다. 작은 파일을 효율적으로 저장하는 방식이다.
Single Indirect Pointer는 하나의 블록을 포인터 배열로 사용한다. 블록 크기 4KB, 포인터 크기 4 바이트인 경우 4KB / 4B로 1024개 포인터를 담을 수 있고, 최대 1024 × 4KB = 4MB를 주소 지정한다. 중간 크기 파일에 사용된다.
Double Indirect Pointer는 블록에서 간접 블록들을 거쳐 데이터 블록들에 도달한다. 1024 × 1024 = 1,048,576개 블록, 최대 1,048,576 × 4KB = 4GB를 다룬다.
Triple Indirect Pointer는 블록, 이중 간접 블록들, 간접 블록들, 데이터 블록들로 이어진다. 1024 × 1024 × 1024 = 1,073,741,824개 블록, 최대 1,073,741,824 × 4KB = 4TB를 주소 지정한다.
블록 크기 4KB, 포인터 4B라는 조건에서 주소 지정 범위를 합산하면 직접 포인터는 48KB, 간접 포인터는 4MB, 이중 간접 포인터는 4GB, 삼중 간접 포인터는 4TB이며 총합은 약 4TB다.
실제 ext4는 32-bit 블록 주소와 4KB 블록에서 16TB를 지원하며, large_file을 사용한 ext4는 16EB(Exabyte)를 지원한다.
inode 테이블은 파일 시스템에 어떻게 배치되는가
inode 테이블은 모든 inode를 담은 배열이며, 파일 시스템을 생성할 때 크기가 정해진다. 이 테이블은 슈퍼블록 다음의 고정된 영역에 위치한다.
ext2, ext3, ext4는 파일 시스템을 여러 블록 그룹으로 나누고 각 블록 그룹에 inode 테이블을 둔다. 파일과 inode를 가까운 위치에 배치해 지역성을 높이기 위한 구조다.
파일이 생성되면 빈 inode를 검색해 할당하고 inode 번호를 반환한다. 파일 삭제 시에는 링크 수가 감소하며, 링크 수가 0이 되면 inode와 데이터 블록이 해제된다.
공간이 남아도 파일을 만들 수 없는 경우
inode 테이블의 크기가 고정된 파일 시스템에서는 작은 파일이 많이 생성될 때 inode가 고갈될 수 있다. 이 경우 디스크 공간이 남아 있어도 새 파일을 생성할 수 없다.
# 100GB 디스크, 50GB 사용
# 하지만 inode 100% 사용 → 파일 생성 불가
inode 사용량은 다음 명령으로 확인한다.
df -i
# Filesystem Inodes IUsed IFree IUse% Mounted on
# /dev/sda1 6553600 6553600 0 100% /
불필요한 파일, 특히 작은 파일을 삭제하면 inode를 회수할 수 있다. inode 수를 늘려야 한다면 파일 시스템을 다시 생성하면서 inode 비율을 지정한다.
# 파일 시스템 생성 시 inode 비율 지정 (ext4)
mkfs.ext4 -i 8192 /dev/sda1
# 8192 바이트당 1개 inode
파일 시스템마다 달라지는 inode 관리
ext2, ext3, ext4는 직접 포인터와 간접 포인터를 사용하는 전통적인 inode 구조를 따른다. ext2와 ext3의 inode는 128 바이트이고, 확장 속성을 지원하는 ext4의 inode는 256 바이트다.
XFS는 동적으로 inode를 할당하고 B+ 트리 기반으로 inode를 관리해 inode 고갈 문제를 완화한다.
BSD UNIX의 UFS도 inode와 유사한 구조를 사용한다. Windows의 NTFS는 MFT(Master File Table)를 사용하며, inode와 비슷한 역할을 하는 가변 크기 레코드로 구성된다. NTFS에서는 메타데이터도 파일을 포함한 모든 것이 파일로 취급된다.