리눅스 커널 파일시스템 기본 [1]
파일시스템이란 하드디스크, SSD, 플래시 메모리와 같은 저장장치 위에 파일과 디렉터리를 체계적으로 정리(organize)하는 방법을 말합니다. 파일시스템의 종류는 매우 다양합니다 (FAT, ext4, btrfs, NTFS 등). 그리고 한 대의 컴퓨터에서 같은 파일시스템 종류가 여러 개 동시에 사용될 수도 있습니다.
파일시스템마다 파일과 디렉터리, 사용자 데이터, 그리고 내부적으로 사용하는 메타데이터를 관리하는 방식이 서로 다르긴 하지만, 거의 모든 파일시스템에 공통적으로 사용되는 몇 가지 기본 개념들이 있습니다 (이 중 일부 개념은 저장장치(storage)와 메모리 양쪽에 존재하고, 일부는 메모리에만 존재합니다.):
- 슈퍼블록(superblock): 해당 파일시스템의 기본 정보를 담고 있습니다. 예를 들어 블록 크기, 루트 아이노드, 파일시스템 전체 크기 같은 정보죠. 슈퍼블록은 저장장치와 메모리 모두에 존재하는데, 메모리에는 속도 향상을 위한 캐싱 용도로 복사되어 있습니다.
- 파일(file):현재 열려있는 파일에 관한 정보(예: 현재 읽기 위치 등)를 담고 있는데, 이 정보는 메모리에만 존재합니다.
- 아이노드(inode): 아이노드는 디스크에 저장된 파일을 고유하게 식별하는 역할을 합니다. 아이노드는 파일 크기, 접근 권한, 파일 종류 등 다양한 속성도 함께 가지고 있죠. 이 아이노드는 저장장치와 메모리 양쪽에 존재하며, 메모리에는 캐시 목적 등으로 복사되어 있습니다.
- 덴트리(dentry): 덴트리(dentry)는 파일 이름과 아이노드(inode)를 연결하는 역할을 합니다. 덴트리 역시 저장장치와 메모리 양쪽에 존재하며, 메모리에는 캐싱 목적으로 복사되어 있습니다.
struct ext4_inode 내부의 i_block에서 스토리지의 각 block들을 가리킨다. EXT4_N_BLOCKS 크기는 15로 ext4가 지원하는 데이터 블록 주소 지정 방식의 표준 크기이며, 이를 통해 작은 파일부터 아주 큰 파일까지 효율적으로 저장 위치를 관리할 수 있습니다.
| i_block 배열 인덱스 | 용도 |
|---|---|
| 0~11 | 직접 데이터 블록 포인터. 실제 파일 데이터가 저장된 블록을 직접 가리키는 포인터 |
| 12 | 단일 간접 블록 포인터. 직접 블록으로 커버할 수 없는 더 큰 파일 데이터를 관리 |
| 13 | 이중 간접 블록 포인터. 다계층 블록 주소를 가리켜서 훨씬 더 큰 파일 크기를 지원 |
| 14 | 삼중 간접 블록 포인터. 더 깊은 계층의 포인터를 통해 아주 큰 파일도 지원 |
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_block[EXT4_N_BLOCKS];/* Pointers to blocks */
struct dentry {
/* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
seqcount_spinlock_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct inode *d_inode; /* Where the name belongs to
여기서 잠깐 inode의 i는 뭘까? index를 의미한다고 한다. 파일을 빠르게 찾기 위한 인덱스 역할을 하는 노드라는 뜻이다.
struct file 내부에 f_path가 있고 f_path 내부에 dentry 포인터가 있다.
정리하자면 파일 디스크립터 숫자를 인덱스로 디스크립터 테이블에 접근하면 struct file 포인터가 있다 --> struct file --> struct path --> struct dentry --> struct inode - EXT4_I() --> struct ext4_inode --> i_block
위 흐름으로 block 위치까지 찾아낼 수 있다.
참고자료
- https://linux-kernel-labs.github.io/refs/heads/master/lectures/fs.html
댓글
댓글 쓰기