kernel version은 v6.10.12 버전으로 분석을 진행합니다.
inode(index node)란
운영체제에서 사용하는 파일 시스템 구조 중 하나입니다.
파일이나 디렉토리와 같은 파일 시스템에 관한 정보를 가지고 있고 파일도 각자 한 개의 inode를 가지고 있습니다.
inode는 소유자 그룹, 접근 모드(rwx), 파일 형태, inode 번호 등 해당 파일에 관한 정보를 가지고 있습니다.
파일 시스템 안의 파일들은 고유한 inode 번호를 통해 식별할 수 있습니다.
파일 시스템은 파일에 대한 데이터 구조에 의존해서 작동합니다. 이러한 데이터 구조를 metadata라고 하며 metadata는 데이터를 설명하는 데이터, 즉 다른 데이터의 특성을 설명하는 데이터입니다.
inode의 기본 구조는 metadata를 효율적으로 저장하고 관리하는 데 초점을 두고, inode(index node)는 각 파일에 대한 metadata 정보를 포함하는 데이터 구조입니다.
inode 확인 명령어
stat
stat syscall을 이용해여 inode에 있는 내용들을 출력할 수 있습니다.
stat a.c
File: a.c
Size: 124 Blocks: 8 IO Block: 4096 regular file
Device: 8,5 Inode: 1311302 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2025-12-17 14:52:42.259722813 +0900
Modify: 2025-09-17 15:10:30.110396972 +0900
Change: 2025-09-17 15:10:30.111396988 +0900
Birth: 2025-09-17 15:10:30.110396972 +0900
Shell
복사
disk inode 확인
실제 파일 시스템이 생성될 때 고정된 수의 inode가 할당됩니다. 일반적으로 전체 디스크 공간의 1%가 inode 테이블에 예약됩니다. 이러한 이유로 디스크 공간이 여유롭더라도 저장할 수 있는 파일의 수가 제한됩니다.
df -i /dev/sda5
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda5 8486912 2086637 6400275 25% /
Shell
복사
위 출력 부분에서 볼 수 있듯, /dev/sda5에는 8,486,912개의 inode가 있으며, 그 중 25% 정도인 2,086,637개를 사용하고 있습니다.
file inode 확인
아래의 명령어를 통해 file의 inode도 확인할 수 있습니다.
ls -i exp.py
5 exp.py
Shell
복사
exp.py의 inode는 5입니다.
directory inode 확인
파일과 동일하게 디렉토리의 inode도 확인할 수 있습니다.
ls -idl ./CTF
1315734 drwxrwxr-x 5 ubuntu ubuntu 4096 5월 25 2024 ./CTF
Shell
복사
inode에 저장되는 주요 정보
1.
파일 유형
2.
파일 크기
3.
소유자(UID)
4.
그룹(GID)
5.
파일 권한
6.
생성 및 수정 시간
7.
하드 링크 개수
8.
데이터 블록 포인터
ext4_inode
Linux에서 주로 사용되는 ext4 파일 시스템을 살펴보겠습니다.
ext4에서 사용하는 inode의 구조체는 아래와 같습니다.
아래의 구조체를 살펴보면 파일 이름을 저장하고 있는 부분이 보이지 않습니다. 파일 이름은 디렉토리 엔트리에서 관리됩니다.
struct ext4_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size_lo; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Inode Change time */
__le32 i_mtime; /* Modification time */
__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
__le32 i_blocks_lo; /* Blocks count */
__le32 i_flags; /* File flags */
union {
struct {
__le32 l_i_version;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl_lo; /* File ACL */
__le32 i_size_high;
__le32 i_obso_faddr; /* Obsoleted fragment address */
union {
struct {
__le16 l_i_blocks_high; /* were l_i_reserved1 */
__le16 l_i_file_acl_high;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
__le16 l_i_reserved;
} linux2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__le16 m_i_file_acl_high;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
__le16 i_extra_isize;
__le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */
__le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
__le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
__le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
__le32 i_crtime; /* File Creation time */
__le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
__le32 i_version_hi; /* high 32 bits for 64-bit version */
__le32 i_projid; /* Project ID */
};
C
복사
디렉토리 엔트리(Directory entry)
Linux의 경우 파일 이름, 파일 정보, inode 번호등 이 저장됩니다.
디렉토리 자체도 inode를 가지며, 자신과 부모 디렉토리에 대한 정보도 포함하고 있습니다.
디렉토리 엔트리란 디렉토리 파일 내부에 저장되며, 파일 또는 하위 디렉토리의 이름을 표현하는데 쓰이는 자료구조입니다.
struct ext4_dir_entry_2 {
__le32 inode; /* Inode number */
__le16 rec_len; /* Directory entry length */
__u8 name_len; /* Name length */
__u8 file_type; /* See file type macros EXT4_FT_* below */
char name[EXT4_NAME_LEN]; /* File name */
};
C
복사
1.
__le32 inode
가리키는 inode 번호
2.
__le16 rec_len
디렉토리 엔트리 길이
3.
__u8 name_len
파일 이름 길이
4.
__u8 file_type
파일 타입 힌트
5.
char name[EXT4_NAME_LEN]
파일 이름
파일에 접근할 때, 디렉토리 엔트리의 inode 번호를 통해 해당 파일의 metadata에 접근합니다.
디렉토리 엔트리에서 파일 이름을 저장하며, 파일 시스템은 이를 기반으로 동일한 디렉토리 내에서 파일 이름의 중복을 허용하지 않습니다.
즉, 파일 이름과 inode는 별도로 존재하며, 디렉토리 엔트리로 각 파일이나 하위 디렉토리를 inode와 매핑하여, 운영체제가 파일 시스템 내에서 파일을 찾을 수 있도록 합니다.
파일 쓰기 과정
1.
새로운 파일이 생성되면 파일 시스템에서 빈 inode를 찾습니다.
2.
해당 inode에 파일 속성을 저장합니다
3.
파일 내용이 디스크 블록에 저장됩니다.
4.
디렉토리 엔트리에 inode 번호와 파일 이름이 등록됩니다.
파일 읽기 과정
1.
사용자가 파일을 열면, 운영체제는 디렉토리에서 해당 파일의 inode 번호를 찾습니다.
2.
해당 inode table에서 해당 번호에 해당하는 inode를 검색합니다
3.
inode가 가르키는 데이터 블록을 찾아 내용을 읽어옵니다.



