파일 시스템 내부 구조
파일 시스템 구현의 기본 원리를 살펴본 후, 이제 실제 파일 시스템의 내부 구조와
성능 최적화 기법을 더 깊이 알아봅니다.
ext4, APFS 등 현대 파일 시스템의 구조와 NFS를 포함한 네트워크 파일 시스템도 다룹니다.
1. 파일 시스템 마운팅
운영체제는 파일 시스템을 사용하기 전에 마운트해야 합니다.
마운트는 파일 시스템을 디렉토리 트리의 특정 지점(마운트 포인트)에 연결하는 것입니다.
마운트 전: 마운트 후:
/ (루트) / (루트)
╱ ╲ ╱ ╲
home mnt home mnt
│ │ (비어 있음) │ │
user1 user1 ┌──────────────┐
│ USB 드라이브 │
│ (ext4) │
│ photos/ │
│ docs/ │
└──────────────┘
/mnt/photos 로 접근 가능
마운트 명령어 예시
장치를 마운트 포인트에 연결
mount /dev/sdb1 /mnt
특정 파일 시스템 타입 지정
mount -t ext4 /dev/sdb1 /mnt
읽기 전용 마운트
mount -o ro /dev/sdb1 /mnt
현재 마운트 목록 확인
mount | column -t
언마운트
umount /mnt
/etc/fstab 파일
부팅 시 자동으로 마운트할 파일 시스템을 정의합니다.
/etc/fstab 예시
장치 마운트포인트 타입 옵션 덤프 패스
/dev/sda1 / ext4 defaults 0 1
/dev/sda2 /home ext4 defaults 0 2
/dev/sdb1 /data xfs noatime 0 2
tmpfs /tmp tmpfs size=2G 0 0
2. 파티션과 블록 그룹
디스크 파티션 구조
┌──────────────────────────────────────────────────┐
│ 물리 디스크 │
│ │
│ ┌─────┬────────────┬────────────┬────────────┐ │
│ │ MBR │ Partition 1│ Partition 2│ Partition 3│ │
│ │ │ (ext4) │ (swap) │ (ext4) │ │
│ │ │ / │ │ /home │ │
│ └─────┴────────────┴────────────┴────────────┘ │
│ │
│ GPT (GUID Partition Table): │
│ ┌─────┬──────┬──────┬──────┬───────┬─────┐ │
│ │ MBR │ GPT │Part 1│Part 2│ ... │ GPT │ │
│ │보호용│헤더 │ │ │ │백업 │ │
│ └─────┴──────┴──────┴──────┴───────┴─────┘ │
└──────────────────────────────────────────────────┘
블록 그룹 (ext4)
ext4는 디스크를 여러 블록 그룹으로 나누어 관리합니다.
┌────────────────────────────────────────────────────┐
│ ext4 파일 시스템 레이아웃 │
│ │
│ ┌──────┬──────────┬──────────┬──────────┬────────┐ │
│ │Group │ Group 0 │ Group 1 │ Group 2 │ ... │ │
│ │ 0 │ │ │ │ │ │
│ └──────┴──────────┴──────────┴──────────┴────────┘ │
│ │
│ 각 블록 그룹 내부: │
│ ┌────────┬────────┬────────┬────────┬────────────┐ │
│ │ Super │ Group │ Block │ inode │ Data │ │
│ │ Block │ Desc. │ Bitmap │ Table │ Blocks │ │
│ │ (백업) │ Table │+ inode │ │ │ │
│ │ │ │ Bitmap │ │ │ │
│ └────────┴────────┴────────┴────────┴────────────┘ │
└────────────────────────────────────────────────────┘
블록 그룹의 장점:
- **지역성(Locality)**: 관련 데이터를 가까이 배치하여 디스크 탐색 최소화
- **병렬 처리**: 서로 다른 블록 그룹에 대한 작업을 병렬로 수행 가능
- **안정성**: 슈퍼블록과 그룹 디스크립터 백업으로 복구 가능
3. ext4 파일 시스템 내부 구조
ext4는 Linux에서 가장 널리 사용되는 파일 시스템입니다.
ext4 주요 특징
| 특성 | 값 |
| ------------------- | ------------------- |
| 최대 파일 크기 | 16 TiB |
| 최대 볼륨 크기 | 1 EiB |
| 최대 파일 이름 길이 | 255 바이트 |
| 최대 디렉토리 깊이 | 무제한 |
| 저널링 | 지원 (ordered 기본) |
| 익스텐트 | 지원 |
익스텐트 (Extent) 기반 할당
ext4는 기존의 간접 블록 포인터 대신 익스텐트를 사용합니다.
기존 방식 (ext2/ext3): ext4 익스텐트:
inode → 직접 포인터 12개 inode → 익스텐트 트리
→ 단일 간접 포인터
→ 이중 간접 포인터 익스텐트: (시작 블록, 길이)
→ 삼중 간접 포인터 하나의 익스텐트로 연속 블록 표현
예: 100개 연속 블록 예: 100개 연속 블록
→ 100개의 포인터 필요 → 1개의 익스텐트 (start=50, len=100)
// ext4 익스텐트 구조체 (간단화)
struct ext4_extent {
uint32_t ee_block; // 논리 블록 번호
uint16_t ee_len; // 블록 수 (최대 32768)
uint16_t ee_start_hi; // 물리 블록 상위 16비트
uint32_t ee_start_lo; // 물리 블록 하위 32비트
};
// 익스텐트 트리 헤더
struct ext4_extent_header {
uint16_t eh_magic; // 매직 넘버 (0xF30A)
uint16_t eh_entries; // 유효한 엔트리 수
uint16_t eh_max; // 최대 엔트리 수
uint16_t eh_depth; // 트리 깊이 (0 = 리프)
uint32_t eh_generation;
};
ext4의 지연 할당 (Delayed Allocation)
전통적 방식: 지연 할당:
write() 호출 write() 호출
│ │
├→ 블록 할당 (즉시) ├→ 페이지 캐시에 데이터 저장
├→ 디스크에 쓰기 │ (블록 아직 미할당)
└→ 완료 │
├→ flush 시점
│ ├→ 연속 블록 한번에 할당
│ └→ 디스크에 쓰기
└→ 완료
장점: 연속 블록 할당 가능성 증가, 성능 향상
4. Apple File System (APFS)
APFS는 Apple이 HFS+를 대체하기 위해 개발한 파일 시스템입니다.
APFS 주요 특징
┌──────────────────────────────────────────┐
│ APFS 컨테이너 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Volume 1 │ │ Volume 2 │ │ Volume 3 │ │
│ │ (macOS) │ │ (Data) │ │ (Preboot)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 공간 공유: 볼륨들이 컨테이너 내 │
│ 빈 공간을 동적으로 공유 │
└──────────────────────────────────────────┘
- **Copy-on-Write (CoW)**: 데이터를 수정할 때 원본을 보존하고 새 위치에 기록
- **스냅샷**: CoW를 활용한 시점 복구 지원
- **공간 공유**: 하나의 컨테이너 내 여러 볼륨이 공간을 동적으로 공유
- **암호화**: 파일/볼륨 단위 네이티브 암호화 지원
- **클론**: 파일/디렉토리의 즉각적인 복사 (메타데이터만 복사, 수정 시 실제 복사)
Copy-on-Write 동작
초기 상태:
Block A → [Original Data]
수정 시 (CoW):
Block A → [Original Data] (보존)
Block B → [Modified Data] (새 위치에 기록)
메타데이터 포인터가 Block B를 가리키도록 업데이트
스냅샷이 있으면:
스냅샷 → Block A (원본 참조 유지)
현재 → Block B (수정본 참조)
5. 성능 최적화
버퍼 캐시 (Buffer Cache)
애플리케이션 read() 요청
│
▼
┌──────────────────┐
│ 버퍼 캐시 │
│ (커널 메모리) │
│ │
│ [블록 42: data] │ ← 캐시 히트: 즉시 반환
│ [블록 88: data] │
│ [블록 15: data] │
│ [블록 7: data] │
└────────┬─────────┘
│ 캐시 미스
▼
┌─────────┐
│ 디스크 │ → 읽은 후 캐시에 저장
└─────────┘
미리 읽기 (Read-Ahead)
순차 접근 패턴을 감지하면 다음 블록을 미리 읽어 캐시에 저장합니다.
요청 패턴: 블록 1 → 블록 2 → 블록 3 → ...
블록 3 요청 시:
커널이 순차 패턴 감지 → 블록 4, 5, 6, 7도 미리 읽기
┌────┬────┬────┬────┬────┬────┬────┐
│ B1 │ B2 │ B3 │ B4 │ B5 │ B6 │ B7 │
│요청│요청│요청│미리│미리│미리│미리│
│완료│완료│반환│읽기│읽기│읽기│읽기│
└────┴────┴────┴────┴────┴────┴────┘
Free-Behind
순차 읽기 시 이미 사용된 페이지를 캐시에서 제거하여 캐시 공간을 확보합니다.
순차 읽기 진행 방향 →
캐시 상태:
[B1] [B2] [B3] [B4] [B5] ← 일반 LRU
↑ 오래된 페이지도 캐시에 남음
[--] [--] [B3] [B4] [B5] ← Free-Behind 적용
↑ 읽은 후 바로 해제 → 새 데이터를 위한 공간 확보
페이지 캐시와 버퍼 캐시의 통합 (Unified Buffer Cache)
과거 (분리): 현재 (통합):
┌──────────┐ ┌──────────┐ ┌──────────────────────┐
│ 페이지 │ │ 버퍼 │ │ 통합 페이지 캐시 │
│ 캐시 │ │ 캐시 │ │ │
│(mmap용) │ │(read용) │ │ mmap과 read/write │
│ │ │ │ │ 모두 같은 캐시 사용 │
└──────────┘ └──────────┘ └──────────────────────┘
같은 데이터 중복 캐시 가능 중복 제거, 일관성 보장
6. NFS (Network File System)
NFS는 네트워크를 통해 원격 파일 시스템에 접근하는 분산 파일 시스템 프로토콜입니다.
NFS 아키텍처
클라이언트 서버
┌──────────────────┐ ┌──────────────────┐
│ 사용자 프로세스 │ │ │
│ open("/mnt/f") │ │ │
├──────────────────┤ │ │
│ VFS │ │ │
├──────────────────┤ ├──────────────────┤
│ NFS 클라이언트 │ │ NFS 서버 데몬 │
│ (nfsd) │ ← RPC/XDR →│ (nfsd) │
├──────────────────┤ ├──────────────────┤
│ 네트워크 │ │ 로컬 │
│ (TCP/UDP) │ │ 파일 시스템 │
└──────────────────┘ └──────────────────┘
NFS 마운트
NFS 서버에서 공유 디렉토리 설정
/etc/exports
/data 192.168.1.0/24(rw,sync,no_subtree_check)
NFS 서비스 시작
sudo systemctl start nfs-server
클라이언트에서 마운트
sudo mount -t nfs server:/data /mnt/nfs
/etc/fstab에 추가하여 부팅 시 자동 마운트
server:/data /mnt/nfs nfs defaults 0 0
NFS의 무상태(Stateless) 설계
NFS v3는 무상태 프로토콜로 설계되었습니다.
무상태 장점:
- 서버 충돌 후 재시작 시 클라이언트 재연결 불필요
- 서버가 클라이언트별 상태를 관리하지 않아 확장성 우수
무상태 구현:
- 파일 핸들(file handle)로 파일 식별
- 각 요청이 독립적 (오프셋 등 필요한 정보를 모두 포함)
- 캐싱은 클라이언트 측에서 처리
NFS v4 변화:
- 상태 유지(stateful) 프로토콜로 전환
- 파일 잠금, 위임(delegation) 등 고급 기능 지원
- 보안 강화 (Kerberos 인증)
7. 정리
- **마운팅**: 파일 시스템을 디렉토리 트리에 연결하는 과정
- **블록 그룹**: 데이터 지역성을 높이고 탐색 시간을 줄이는 구조
- **ext4**: 익스텐트, 지연 할당, 저널링으로 성능과 안정성 확보
- **APFS**: Copy-on-Write, 스냅샷, 공간 공유 등 현대적 기능
- **성능 최적화**: 버퍼 캐시, 미리 읽기, Free-Behind, 통합 페이지 캐시
- **NFS**: RPC 기반 네트워크 파일 시스템, v3 무상태 / v4 상태 유지
**Q1.** ext4의 익스텐트(extent)가 기존 간접 블록 포인터보다 좋은 이유는 무엇인가요?
**A1.** 익스텐트는 연속된 물리 블록을 (시작 블록, 길이)로 표현하므로,
대용량 파일에서 수천 개의 개별 블록 포인터 대신 소수의 익스텐트로 관리할 수 있습니다.
이를 통해 메타데이터 오버헤드가 줄고, 연속 블록을 한 번의 I/O로 읽을 수 있어 성능이 향상됩니다.
**Q2.** Copy-on-Write(CoW)의 장점과 단점은 무엇인가요?
**A2.** 장점: 원본 데이터를 보존하므로 스냅샷 구현이 용이하고, 충돌 시 일관성을 유지합니다.
또한 파일 복제(clone)가 O(1)으로 빠릅니다.
단점: 수정 시 항상 새 위치에 기록하므로 순차 쓰기가 랜덤 쓰기로 변할 수 있고,
조각화가 발생할 수 있습니다.
**Q3.** NFS v3가 무상태 프로토콜인 이유와 v4에서 상태 유지로 전환한 이유는?
**A3.** v3의 무상태 설계는 서버 충돌 후 재시작이 간단하고 확장성이 좋습니다.
그러나 파일 잠금이나 캐시 일관성 등 고급 기능 구현이 어렵습니다.
v4는 상태를 유지하여 파일 잠금, 위임(delegation), 보안 등
더 풍부한 기능을 지원하도록 발전했습니다.
현재 단락 (1/222)
파일 시스템 구현의 기본 원리를 살펴본 후, 이제 실제 파일 시스템의 내부 구조와