EROFS (Enhanced Read-Only File System)
EROFS는 Huawei가 주도해 Linux 메인라인에 병합된 읽기 전용(Read-Only) 압축 파일시스템(Filesystem)입니다. 본 문서에서는 pcluster 압축 모델과 in-place 압축 해제, 온디스크 포맷과 읽기 경로, `mkfs.erofs` 이미지 생성 전략, Android 시스템 파티션과 컨테이너(Container) 배포, v6.12 file-backed 마운트(Mount)와 fscache 폐기, v6.11~v6.18 최신 변화까지 상세히 설명합니다.
핵심 요약
- 읽기 전용 — 런타임 변경 불가, 무결성(Integrity)·재현성 확보
- pcluster 압축 — logical block과 physical 압축 덩어리를 분리해 랜덤 읽기 비용 최소화
- in-place 압축 해제 — 임시 버퍼를 최소화하여 cold-start 지연 감소
- file-backed 마운트 — v6.12부터 루프백 블록 장치(Block Device) 없이 이미지 파일 직접 마운트
- 주요 활용 — Android 시스템 파티션, 컨테이너 이미지, Live 미디어
단계별 이해
- 온디스크 구조 파악
슈퍼블록(Superblock)과 메타데이터 레이아웃, 압축 단위가 어떻게 배치되는지 이해합니다. - pcluster 매핑 이해
logical read가 extent 배열을 거쳐 압축 덩어리로 연결되는 경로를 파악합니다. - 이미지 생성
mkfs.erofs로 압축 알고리즘(LZ4/LZMA/Zstd)과 클러스터링 정책을 선택합니다. - 배포 구성
dm-verity 무결성 검증과 OverlayFS 읽기-쓰기 레이어를 결합하고, file-backed 마운트 적용 여부를 검토합니다.
개요
EROFS는 2018년 Huawei가 개발을 시작해 2019년 Linux 5.4에 메인라인으로 병합된 읽기 전용 압축 파일시스템입니다. Android 시스템 파티션과 컨테이너 이미지 배포에서 빠른 cold-start와 안정적인 압축 해제를 목표로 설계되었으며, SquashFS와 같은 읽기 전용 압축 파일시스템이지만 pcluster 기반 압축으로 random read 손실을 최소화합니다.
활용 사례
- Android 시스템 파티션 — dynamic partition 기반 /system·/vendor·/product 이미지
- 컨테이너 이미지 — lazy-loading(지연 로딩) 및 레이어 마운트 (file-backed 방식은 후술)
- 실행 파일 패키징 — ComposeFS, Android APEX 모듈
- Live 미디어 — Fedora 42 라이브 미디어, RHEL 10 방향 (배포 파이프라인 섹션 참고)
- 임베디드 시스템 — 저장 공간 제약이 큰 펌웨어(Firmware) 이미지
설계 목표
EROFS는 모바일·임베디드 환경의 저장 장치 특성(느린 랜덤 읽기, 제한된 CPU/메모리)을 전제로 다음 목표에 우선순위를 둡니다.
- 빠른 cold-start — 앱·시스템 시작 시 필요한 메타데이터와 데이터 블록만 짧은 시간 안에 해제합니다.
- random read 손실 최소화 — pcluster 단위 압축으로 불필요한 블록 해제를 피합니다.
- 메모리 효율 — in-place 압축 해제와 folio 기반 Page Cache 운용으로 임시 메모리 사용을 줄입니다.
- 간결한 온디스크 포맷 — 메타데이터 구조를 단순화해 마운트와 조회 비용을 낮춥니다.
pcluster 압축 모델
EROFS의 핵심은 logical block과 physical compressed extent(압축 익스텐트)를 분리하는 pcluster(physical cluster) 모델입니다. 파일의 논리적 읽기 단위(lcluster)와 실제 저장된 압축 덩어리(pcluster)를 extent 배열로 매핑하여, 작은 read에도 필요한 압축 덩어리만 해제하도록 메타데이터를 구성합니다.
압축 알고리즘 선택
- LZ4 — 빠른 해제 속도 중심 배포에 적합 (부팅·앱 cold-start 우선)
- LZMA — 공간 절감 우선 시나리오 (압축률 우선)
- Zstd — 압축률과 해제 속도의 균형형 선택지
EROFS vs SquashFS 비교
EROFS와 SquashFS는 모두 읽기 전용 압축 파일시스템이지만, 설계 철학과 최적화 대상이 다릅니다. SquashFS는 범용 읽기 전용 압축 이미지에 초점을 맞추고, EROFS는 모바일/시스템 이미지에서의 cold-start 지연 최소화에 집중합니다.
상세 기능 비교
| 비교 항목 | SquashFS | EROFS |
|---|---|---|
| 메인라인 병합 | Linux 2.6.29 (2009) | Linux 4.19 (2018) |
| 압축 단위 | 고정 블록 (4KB~1MB) | 가변 pcluster |
| 작은 파일 최적화 | 프래그먼트 패킹 | 인라인 데이터 (tail-packing) |
| 메타데이터 압축 | 예 (8KB 블록) | 아니오 (고정 크기, 비압축) |
| 압축 알고리즘 | gzip, lzo, xz, lz4, zstd | lz4, lzma, zstd, deflate |
| inode 조회 복잡도 | O(log n) — 메타데이터 블록 탐색 | O(1) — NID 기반 직접 접근 |
| NFS 지원 | 예 (Export Table) | 예 (NID 기반) |
| xattr 지원 | 예 | 예 (인라인 + 공유 모두) |
| sparse 파일 | 예 (v4.0+) | 예 |
| FSDAX 지원 | 아니오 | 예 (v5.15+) |
| 멀티 디바이스 | 아니오 | 예 (blob 디바이스) |
| 주요 사용처 | Live OS, 임베디드, Snap, AppImage | Android system, 컨테이너 (containerd) |
| 커널 소스 위치 | fs/squashfs/ | fs/erofs/ |
온디스크 포맷
이미지는 슈퍼블록으로 시작하며, inode·디렉터리·익스텐트 등 메타데이터 영역과 압축 데이터 블록 영역이 뒤를 잇습니다. 슈퍼블록이 각 테이블의 위치와 블록 크기 정보를 제공하므로 마운트 초기에 전체 온디스크 구조를 파악할 수 있습니다.
Superblock 구조체(Struct)
struct erofs_super_block {
__le32 magic; /* EROFS_SUPER_MAGIC_V1 */
__le32 checksum;
__le32 feature_compat;
__le32 feature_incompat;
__le64 blocks;
__le32 blkszbits;
__le16 root_nid;
};
메타데이터와 익스텐트
EROFS는 데이터 영역을 익스텐트(extent) 단위로 관리합니다. 압축 파일은 논리적 클러스터(lcluster)가 물리적 클러스터(pcluster)로 매핑되는 구조이며, 이 매핑 정보가 extent 배열에 저장됩니다. 압축이 필요 없는 데이터는 비압축 익스텐트로 저장되는 경로도 존재하여, CPU 제약이 큰 환경에서는 온디스크 배치를 단순화할 수 있습니다.
읽기 경로와 in-place 압축 해제
일반 파일 읽기는 Page Cache를 거치며, 압축 파일은 folio 단위로 요청된 뒤 pcluster 매핑을 통해 해당 압축 덩어리만 해제됩니다.
generic_file_read_iter()
-> erofs_read_folio()
-> z_erofs_map_blocks_iter() /* logical -> pcluster 매핑 */
-> z_erofs_decompressqueue_work()
-> z_erofs_lz4_decompress() / z_erofs_zstd_decompress()
in-place 압축 해제
in-place 압축 해제는 해제 결과를 별도 임시 페이지에 받은 뒤 Page Cache로 다시 복사하는 이중 복사를 피하고, 대상 folio 안에서 직접 해제하는 방식입니다. 임시 버퍼(Buffer) 사용량이 줄어들어 메모리 압박이 큰 모바일 환경에서 cold-start 지연과 메모리 사용량을 동시에 낮춥니다.
커널 설정
CONFIG_EROFS_FS=y
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_ZIP_LZ4=y
CONFIG_EROFS_FS_ZIP_ZSTD=y
CONFIG_EROFS_FS_PCPU_KTHREAD=y
압축 해제 성능이 중요한 환경에서는 Per-CPU 커널 스레드 옵션(CONFIG_EROFS_FS_PCPU_KTHREAD)을 함께 활성화하여 디코드 워커(Worker)의 컨텍스트 스위치 비용을 줄일 수 있습니다.
mkfs.erofs 이미지 생성
erofs-utils가 제공하는 mkfs.erofs로 디렉터리를 EROFS 이미지로 변환합니다. 압축 알고리즘(-z)과 레벨, 클러스터링 정책 선택으로 용량과 성능을 조율할 수 있습니다.
# 이미지 생성
$ mkfs.erofs system.erofs ./rootfs
# 압축 알고리즘 지정
$ mkfs.erofs -z lz4hc system.erofs ./rootfs
# 마운트
$ sudo mount -t erofs system.erofs /mnt/erofs
성능 튜닝
| 튜닝 항목 | 선택지 | 권장 시나리오 |
|---|---|---|
| 압축 알고리즘 | LZ4 / LZ4HC / Zstd | 부팅 속도 우선은 LZ4, 용량 우선은 Zstd |
| 클러스터링 정책 | random-friendly / compact | 앱 cold-start가 중요하면 random-friendly |
| CPU/IO 균형 | 압축률 vs 해제비용 | 저사양 CPU는 과도한 고압축 피하기 |
file-backed 마운트 (v6.12)
과거 nydus와 같은 컨테이너 lazy-loading 솔루션은 EROFS + fscache 백엔드 조합을 많이 사용했으나, 해당 경로는 deprecated 방향으로 선언되었습니다. 커널 6.12에서 EROFS는 루프백 블록 장치 없이 이미지 파일을 직접 마운트하는 file-backed 마운트를 정식 지원하며, -o fsid= 기반으로 재편되었습니다. 이 기능은 컨테이너 이미지 수천 개를 단일 호스트에서 실행하는 환경에서 루프백 장치의 복잡한 생명주기 관리를 제거합니다.
- ComposeFS, containerd, Android APEX가 직접 수혜 대상입니다.
- 기존 EROFS-over-fscache 백엔드는 폐기(deprecated) 선언되었습니다. file-backed 마운트가 더 단순하고 효율적인 대체 수단입니다.
- HSM "fanotify pre-content hooks" 같은 후속 메커니즘이 성숙하면 fscache 백엔드의 필요성이 더 줄어들 수 있습니다. 다만 실제 제거 시점은 이후 메인라인 변경 이력으로 다시 확인해야 합니다.
# EROFS file-backed 마운트 예시 (커널 6.12 이상)
mount -t erofs -o loop image.erofs /mnt/erofs # 루프 없이도 가능
# 또는 직접 파일 경로 지정 방식 (컨테이너 런타임에서 활용)
커널 6.12부터: EROFS file-backed 마운트 정식 지원. EROFS-over-fscache는 더 이상 권장되지 않습니다.
Android·컨테이너 배포 파이프라인
Android dynamic partition과 컨테이너 배포에서 EROFS는 dm-verity 무결성 검증과 OverlayFS 읽기-쓰기 레이어와 함께 구성됩니다.
# 1) rootfs 준비 및 EROFS 이미지 생성
$ mkfs.erofs -z lz4hc system.erofs ./out/rootfs
# 2) dm-verity 서명 단계 결합
$ veritysetup format system.erofs system.hash
# 3) 부팅 시 read-only 마운트 + OverlayFS 결합
$ sudo mount -t erofs /dev/block/system /mnt/lower
$ sudo mount -t overlay overlay \
-o lowerdir=/mnt/lower,upperdir=/data/upper,workdir=/data/work \
/mnt/rootfs
실사용 채택 — Fedora 42 라이브 미디어 전환
Fedora 42(커널 6.14 기반, 2025년 출시)는 라이브 미디어의 루트 파일시스템을 SquashFS에서 EROFS로 전환했습니다. KDE Desktop, Xfce, LXQt, COSMIC, Budgie 등 주요 데스크톱 배포판과 Fedora CoreOS 라이브 미디어가 모두 포함됩니다.
- 전환 이유 — EROFS는 SquashFS보다 활발히 개발 중이며, 현대적인 파일시스템 기능을 활용할 여지가 큽니다. RHEL 10도 라이브 미디어에 EROFS를 채택하는 방향으로 정렬됩니다.
- 성능 — SquashFS 대비 압축률과 빌드 시간이 소폭 개선되었으며, 라이브 환경 부팅 속도도 약간 빨라졌습니다.
- 사용자 영향 — 라이브 설치 및 동작 방식에 가시적인 변화는 없습니다.
최신 변화 (v6.11~v6.18)
Large Folio & 압축 파일 (v6.11)
v6.11에서 EROFS는 압축 파일 경로에도 large folio를 본격적으로 적용하여, pcluster(physical cluster) 단위 디코드 병렬성과 in-place 압축 해제 효율을 모두 끌어올렸습니다.
- compressed 파일에 대해 large folio 경로 적용으로 할당/해제 오버헤드 감소
- pcluster 단위 디코드 병렬성 개선, inflight 디코드의 컨텍스트 스위치 비용 감소
- decompression in-place 경로 최적화로 임시 버퍼 사용량 축소
압축 알고리즘 확장 (zstd·deflate)
EROFS는 zstd를 v5.16부터 안정적으로 지원하며, v6.13에서 deflate(zlib) 병렬 압축/해제 경로가 정리되었습니다. 이미지 제작 시 mkfs.erofs 옵션으로 알고리즘과 레벨을 선택할 수 있습니다.
/* 이미지 생성 예시 (userspace 명령) */
mkfs.erofs -z zstd,19 image.erofs rootfs/
mkfs.erofs -z deflate,9 image.erofs rootfs/
- zstd는 높은 압축비와 빠른 해제 속도의 균형을 제공하며, 컨테이너 이미지에 가장 널리 쓰입니다
- deflate(zlib)는 호환성/도구 체인 단순성이 강점이며, v6.13에서 병렬 경로 정리로 해제 처리량이 개선되었습니다
- 레벨 숫자로 이미지 크기/시간 trade-off를 조율할 수 있습니다
48비트 블록 주소 및 AI 데이터셋 지원 (v6.15)
커널 6.15에서 EROFS는 대규모 AI 모델 훈련 데이터셋과 같은 대용량 이미지 처리를 위한 48비트 블록 주소(48-bit block addressing)가 도입되었습니다. 기존 32비트 블록 주소(최대 약 4TB)의 한계를 넘어 훨씬 큰 이미지를 지원합니다.
- 48비트 블록 주소 — 32비트의 한계를 넘어 페타바이트 규모의 EROFS 이미지를 지원합니다.
- 바이트 지향 인코딩된 익스텐트(byte-oriented encoded extents) — 주로 Zstandard와 같이 고정 크기 출력 압축을 지원하지 않는 알고리즘을 위해 도입되었습니다. 대형 압축 유닛의 효율적인 인덱싱이 가능합니다.
- AI 모델 훈련용 대규모 데이터셋 저장에 EROFS를 활용하는 시나리오가 증가하는 추세입니다.
커널 6.15부터: mkfs.erofs의 48비트 블록 주소 옵션으로 4TB 이상의 대용량 EROFS 이미지 생성이 가능합니다.
Intel QAT 하드웨어 가속 및 fsoffset 마운트 옵션 (v6.16)
커널 6.16에서는 성능과 유연성을 위한 두 가지 주요 기능이 추가되었습니다.
- Intel QAT 하드웨어 가속 — Intel QAT(QuickAssist Technology) 가속기를 활용한 DEFLATE 압축 해제 지원이 추가되었습니다. Intel Sapphire Rapids 서버에서 순차 읽기 속도가 LZ4 소프트웨어 압축 해제를 능가하는 수준을 달성합니다.
fsoffset마운트 옵션 — EROFS 이미지가 파일이나 블록 장치 내 오프셋 0이 아닌 위치에서 시작할 때, 해당 오프셋을 지정해 직접 마운트할 수 있습니다. 커스텀 컨테이너 이미지 포맷에 유용합니다.- CPU 핫플러그(Hotplug) 처리 지연 초기화 — EROFS를 사용하지 않을 때의 CPU당 워커와 핫플러그 훅 초기화를 지연시켜 불필요한 오버헤드를 줄입니다.
# fsoffset 마운트 옵션 예시 (커널 6.16 이상)
# EROFS 이미지가 파일의 오프셋 4096에서 시작하는 경우
mount -t erofs -o fsoffset=4096 image.bin /mnt/erofs
커널 6.16부터: Intel QAT 가속 DEFLATE 해제 및 fsoffset 마운트 옵션 지원.
메타데이터 압축 (v6.17)
커널 6.17에서 EROFS는 선택적 메타데이터 압축을 지원합니다. 이 기능은 이미 압축된 데이터 블록뿐 아니라 inode/디렉터리/인덱스 테이블 등 메타데이터 영역도 압축하여 이미지 전체 크기를 더욱 줄입니다.
- 임베디드 시스템처럼 저장 용량이 엄격히 제한된 환경에서 EROFS 이미지 크기를 추가로 줄일 수 있습니다.
mkfs.erofs에서 메타데이터 압축 옵션을 통해 활성화합니다.
커널 6.17부터: 선택적 메타데이터 압축 지원. 이미지 크기 추가 절감 가능.
보안 강화 (v6.18)
커널 6.18에서는 악의적으로 조작된 EROFS 이미지를 마운트할 때 발생할 수 있는 시스템 크래시(crash)나 무한 루프(infinite loop)를 방지하는 하드닝(hardening) 개선이 병합되었습니다.
- 특수 제작된 이미지를 통한 커널 패닉 및 무한 루프 취약점(Vulnerability) 수정
- 신뢰할 수 없는 출처의 EROFS 이미지를 다루는 환경(컨테이너 레지스트리, OTA 업데이트 등)에서의 안전성이 향상됩니다.
트러블슈팅
unknown filesystem type 'erofs'가 나오면 커널 설정(CONFIG_EROFS_FS)과 모듈 로드 여부를 먼저 확인하세요.
$ grep EROFS /boot/config-$(uname -r)
$ sudo modprobe erofs
$ dmesg | grep -i erofs
참고자료
공식 문서 및 커널 소스
- Kernel Docs: EROFS — 커널 공식 EROFS 문서입니다
- erofs.docs.kernel.org — EROFS 사용자 문서 사이트입니다
- 커널 소스: fs/erofs/ — EROFS 커널 구현 소스 코드입니다
- 커널 소스: fs/erofs/super.c — EROFS 슈퍼블록 및 마운트 구현입니다
- 커널 소스: fs/erofs/decompressor.c — EROFS 압축 해제 엔진 구현입니다
- 커널 소스: erofs_fs.h — EROFS 온디스크 포맷 헤더 정의입니다
- erofs-utils 공식 저장소 — mkfs.erofs/dump.erofs/fsck.erofs 도구 소스입니다
LWN.net 기술 기사
- LWN: EROFS — 새로운 읽기 전용 파일시스템 — EROFS의 설계 목표와 기술적 배경을 다룹니다
- LWN: EROFS 메인라인 머지 — EROFS가 Linux 5.4에 머지된 과정을 설명합니다
- LWN: 읽기 전용 파일시스템 비교 — SquashFS, EROFS 등 읽기 전용 파일시스템 성능 비교 분석입니다
- LWN: EROFS large folio — EROFS 대형 folio 지원 변경 내용입니다
- LWN: erofs file-backed mount 지원 — file-backed 마운트 추가 내용입니다
관련 커널 문서
- dm-verity 커널 문서 — EROFS와 결합하여 무결성(Integrity) 검증에 사용되는 dm-verity 문서입니다
- OverlayFS 커널 문서 — EROFS 위에 읽기-쓰기 레이어를 제공하는 OverlayFS 문서입니다
- Fedora 42 EROFS 전환 위키 — Fedora 라이브 미디어의 EROFS 전환 제안서입니다
관련 문서
- SquashFS 파일시스템 — 동일 계열의 읽기 전용 압축 파일시스템으로, EROFS vs SquashFS 비교 기준이 되는 문서
- VFS (Virtual Filesystem Switch) — 파일시스템 인터페이스와 마운트 경로의 기반
- OverlayFS — EROFS 하위 레이어 위에 읽기-쓰기 레이어를 제공하는 결합 방식
- Block I/O 서브시스템 — EROFS 이미지가 사용하는 블록 장치 I/O 경로
- 임베디드 빌드 시스템(Build System) — 임베디드 펌웨어 이미지 구조와 읽기 전용 루트 파일시스템 활용