#!if 넘어옴1 != null
''''''{{{#!if 넘어옴2 != null
, ''''''}}}{{{#!if 넘어옴3 != null
, ''''''}}}{{{#!if 넘어옴4 != null
, ''''''}}}{{{#!if 넘어옴5 != null
, ''''''}}}{{{#!if 넘어옴6 != null
, ''''''}}}{{{#!if 넘어옴7 != null
, ''''''}}}{{{#!if 넘어옴8 != null
, ''''''}}}{{{#!if 넘어옴9 != null
, ''''''}}}{{{#!if 넘어옴10 != null
, ''''''}}}은(는) 여기로 연결됩니다.
#!if 설명 == null && 리스트 == null
{{{#!if 설명1 == null
다른 뜻에 대한 내용은 아래 문서를}}}{{{#!if 설명1 != null
{{{#!html 호러 게임}}}에 대한 내용은 [[Fears to Fathom]] 문서{{{#!if (문단1 == null) == (앵커1 == null)
를}}}{{{#!if 문단1 != null & 앵커1 == null
의 [[Fears to Fathom#s-|]]번 문단을}}}{{{#!if 문단1 == null & 앵커1 != null
의 [[Fears to Fathom#|]] 부분을}}}}}}{{{#!if 설명2 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단2 == null) == (앵커2 == null)
를}}}{{{#!if 문단2 != null & 앵커2 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단2 == null & 앵커2 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명3 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단3 == null) == (앵커3 == null)
를}}}{{{#!if 문단3 != null & 앵커3 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단3 == null & 앵커3 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명4 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단4 == null) == (앵커4 == null)
를}}}{{{#!if 문단4 != null & 앵커4 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단4 == null & 앵커4 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명5 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단5 == null) == (앵커5 == null)
를}}}{{{#!if 문단5 != null & 앵커5 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단5 == null & 앵커5 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명6 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단6 == null) == (앵커6 == null)
를}}}{{{#!if 문단6 != null & 앵커6 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단6 == null & 앵커6 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명7 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단7 == null) == (앵커7 == null)
를}}}{{{#!if 문단7 != null & 앵커7 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단7 == null & 앵커7 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명8 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단8 == null) == (앵커8 == null)
를}}}{{{#!if 문단8 != null & 앵커8 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단8 == null & 앵커8 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명9 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단9 == null) == (앵커9 == null)
를}}}{{{#!if 문단9 != null & 앵커9 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단9 == null & 앵커9 != null
의 [[#|]] 부분을}}}}}}{{{#!if 설명10 != null
, {{{#!html }}}에 대한 내용은 [[]] 문서{{{#!if (문단10 == null) == (앵커10 == null)
를}}}{{{#!if 문단10 != null & 앵커10 == null
의 [[#s-|]]번 문단을}}}{{{#!if 문단10 == null & 앵커10 != null
의 [[#|]] 부분을}}}}}}
#!if 설명 == null
{{{#!if 리스트 != null
다른 뜻에 대한 내용은 아래 문서를}}} 참고하십시오.
#!if 리스트 != null
{{{#!if 문서명1 != null
* {{{#!if 설명1 != null
호러 게임: }}}[[Fears to Fathom]] {{{#!if 문단1 != null & 앵커1 == null
문서의 [[Fears to Fathom#s-|]]번 문단}}}{{{#!if 문단1 == null & 앵커1 != null
문서의 [[Fears to Fathom#|]] 부분}}}}}}{{{#!if 문서명2 != null
* {{{#!if 설명2 != null
: }}}[[]] {{{#!if 문단2 != null & 앵커2 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단2 == null & 앵커2 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명3 != null
* {{{#!if 설명3 != null
: }}}[[]] {{{#!if 문단3 != null & 앵커3 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단3 == null & 앵커3 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명4 != null
* {{{#!if 설명4 != null
: }}}[[]] {{{#!if 문단4 != null & 앵커4 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단4 == null & 앵커4 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명5 != null
* {{{#!if 설명5 != null
: }}}[[]] {{{#!if 문단5 != null & 앵커5 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단5 == null & 앵커5 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명6 != null
* {{{#!if 설명6 != null
: }}}[[]] {{{#!if 문단6 != null & 앵커6 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단6 == null & 앵커6 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명7 != null
* {{{#!if 설명7 != null
: }}}[[]] {{{#!if 문단7 != null & 앵커7 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단7 == null & 앵커7 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명8 != null
* {{{#!if 설명8 != null
: }}}[[]] {{{#!if 문단8 != null & 앵커8 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단8 == null & 앵커8 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명9 != null
* {{{#!if 설명9 != null
: }}}[[]] {{{#!if 문단9 != null & 앵커9 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단9 == null & 앵커9 != null
문서의 [[#|]] 부분}}}}}}{{{#!if 문서명10 != null
* {{{#!if 설명10 != null
: }}}[[]] {{{#!if 문단10 != null & 앵커10 == null
문서의 [[#s-|]]번 문단}}}{{{#!if 문단10 == null & 앵커10 != null
문서의 [[#|]] 부분}}}}}}
📁 파일 시스템 | |||||||
{{{#!wiki style="margin: 0 -10px -5px; min-height: calc(1.5em + 5px);" {{{#!folding [ 펼치기 · 접기 ] {{{#!wiki style="margin: -6px -1px -11px" | <colbgcolor=#f1d592><colcolor=#000>마이크로소프트 | FAT | NTFS | ReFS | |||
애플 | HFS | HFS+ | APFS | ||||
리눅스 / 유닉스 | ext2 | ext3 | ext4 | ||||
Btrfs | F2FS | XFS | ZFS |
1. 개요
2012년, 삼성전자의 김재극 연구원이 주도하여 개발해 오픈소스로 발표된 파일 시스템. Flash-Friendly File System의 약자로, 플래시 메모리에 적합하게 만들어 졌다.2. 설명
플래시 메모리의 특성, 즉 HDD와 다르게 덮어쓰기 미지원, 쓰기/지우기가 블록 단위로 실행된다는 특징을 극복하기 위해 F2FS는 로그 구조 파일 시스템을 기반으로 동작한다.2.1. 구조
F2FS는 6개의 주요 영역으로 구성되어 있다.- 슈퍼블록: 파일시스템의 메타데이터를 저장. 부팅 시 기본 정보를 여기서 로드한다.
- 체크포인트(CP): 파일 시스템의 일관된 상태를 주기적으로 저장한다.
- 세그먼트 정보 테이블(SIT): 각 세그먼트의 상태(유효 블록 수, 사용 패턴 등)를 추적한다.
- 노드 주소 테이블(NAT): 파일과 디렉토리의 노드(메타데이터 블록) 위치를 저장한다.
- 세그먼트 요약 영역(SSA): 각 블록의 소유자를 기록한다.
- 메인 영역: 실제 파일 데이터와 디렉토리 데이터가 저장되는 영역이다.
저장소 처음부터 순차적으로 슈퍼블록 → CP → SIT → NAT → SSA → 메인 영역 순으로 배치된다.
데이터 기록 방식에도 차이가 있는데,
- 기존 파일 시스템(EXT4): 파일 수정 시 원래 위치에 덮어쓰기를 시도한다.
- F2FS: 새 데이터를 새 위치에 추가하고, 기존 데이터에 "무효" 표기를 실행한다.
이러한 차이로 인해 플래시 메모리의 낸드 셀 수명을 절약하고, 블록 단위 지우기를 수월하게 실행할 수 있어 성능 향상에 큰 도움을 주고 있다.
데이터는 세그먼트(2MB) 단위로 저장하고, 세그먼트 안에서 블록(4KB) 단위로 관리한다. 세그먼트가 꽉 차면 다음 세그먼트로 넘어간다.
F2FS는 파일과 디렉토리를 **노드** 구조로 관리하고 있다.
- Direct Node: 파일 데이터 블록의 주소를 직접 가리킴(최대 918개 블록)
- Indirect Node: 더 많은 블록을 가리키기 위해 계층 구조로 확장(1, 2, 3단계 간접 포인터)
- 최대 파일 크기는 3.94TB(4KB 블록 기준)
- Inode: 파일의 메타데이터(권한, 크기, 시간)를 저장. 각 파일마다 고유의 Inode를 소유하고 있다.
2.2. 쓰기
- 파일 수정 → 새 데이터 블록을 메인 영역에 기록한다.
- NAT에서 노드 위치를 업데이트한다.
- SSA에 블록 소유 정보를 갱신한다.
- 주기적으로 체크포인트를 저장한다.
2.3. 체크포인트와 복구
- 체크포인트: 파일 시스템의 스냅샷(NAT, SIT, SSA)을 주기적으로 찍고, 크래시 발생 시 복구에 사용한다.
복구 방식은 Roll-Forward Recovery를 사용하는데, 체크포인트 생성 시 로그를 재적용해 주기적으로 최신 상태를 유지시킨다.
두 개의 체크포인트 영역이 번갈아 갱신되면서 항상 한쪽이 유효한 상태를 유지하는 구조이다.
2.4. Garbage Collection
플래시 특성상 데이터 덮어쓰기가 불가능하므로, 무효 처리한 데이터의 공간을 정리하는 작업을 Garbage Collection이라고 부른다. F2FS는 2가지 방식으로 청소를 수행한다.- On-Demand: 공간이 부족할 시 실행한다.
- Greedy 알고리즘으로 유효 블록이 적은 세그먼트를 골라 빠르게 비운다.
- Background: 시스템이 유휴 상태일 때 실행한다.
- Cost-Benefit 알고리즘을 통해 청소 비용 대비 효율을 계산해서 최적화를 실행한다.
청소 과정은 다음과 같다.
- SIT에서 유효 블록의 비율을 확인한다.
- SSA에서 유효 데이터의 소유자를 파악한다.
- 유효 데이터를 새 세그먼트로 이동한다.
- 원본 세그먼트를 삭제한다(플래시의 Erase 작업 실행).
2.5. 파일 압축
- 지원 알고리즘: LZO, LZ4, ZSTD
- 압축 단위: 4KB 블록 단위로 압축 후 저장
- 목적: 저장 공간의 절약과 쓰기 횟수를 줄여 플래시 수명 향상에 기여한다.
읽기 작업 시 압축 해제 후 캐시에 저장하여 성능 저하를 최소화한다.
압축은 파일 단위로 설정이 가능하며, 기본적으로 비활성화되어 있어 f2fs-tools를 통해 활성화해야 한다.
2.6. 검색
디렉토리 구조: 해시 기반으로 파일 이름을 관리한다.- 파일 이름을 해시 값으로 변환 → Direct Node에 저장된 해시 테이블에서 위치를 검색한다.
- 충돌 시 선형 탐색으로 해결한다.
그 결과, 파일 수가 얼마든지 매우 빠른 검색을 할 수 있다.
2.7. 장단점
장점- 플래시 메모리에 최적화: 순차 쓰기와 청소로 플래시 성능을 극대화한다.
- 복구의 용이성: 로그 구조와 체크포인트 적용으로 크래시 발생 후 복구가 용이하다.
- 확장성: 대용량 파일(최대 3.94TB)과 디렉토리를 지원한다.
단점
- 복잡성: 메타데이터의 관리가 복잡하여 오버헤드가 발생할 가능성이 있다.
- HDD에는 비적합: 순차 쓰기가 중심인 파일시스템이기에 HDD에서는 성능 저하가 존재한다.
- SSD의 자체 FTL(Firmware Translation Layer)과 충돌 가능성이 존재한다.
3. 사용 예시
SSD등에서 사용하여도 좋지만, 모바일 환경에 잘 어울릴 것으로 기대되었으며 실제로 효과적이며, 스마트폰 루팅이나 롬질에 관심이 있는 사람이라면 최소한 한 번쯤 들어봤을 정도로 꽤 알려진 형식이다. 다만 제조사에서 처음부터 이 방식으로 출고하는 스마트폰 제품은 드물고, 개인적으로 커스텀 리커버리나 ADB 등을 통해 내부 저장소를 포맷하여 사용하는 것이 일반적이다. 보통 Data, Cache 파티션을 F2FS로 많이 적용하고 System 파티션에 하는 경우는 문제가 있을 경우 복구가 어려울 수 있으므로 드물게 사용한다.제조사에서 기본 지원한 경우는 다음과 같다.
- 원플러스 3/3T가 기본적으로 지원했으나, 안정성 문제를 들어서 원플러스 5/5T에서는 ext4로 되돌아갔다.
- 픽셀3/픽셀3 XL, 엑스페리아 1도 지원한다.
- 개발사인 삼성전자에서는 2019년 하반기에야 갤럭시 탭 S6을 시작으로 노트10, A90 등에서 채택되었다. 특히 UFS 3.0과 동시에 탑재되어 S10 등 ext4 + UFS 2.1 기기 대비 체감 성능이 매우 높은 편이다.
스마트폰에서 F2FS를 사용하여 보려면, 당연하겠지만 지원하는 롬과 커널이 설치되어 있어야 한다. 또한 비정상적인 종료 등 갑작스런 상황에 대해선 로그 기반 파일 시스템인 특성 상 로그 전체 차원의 오류 가능성 때문에 ext4보다 불안정할 수도 있음을 유의하여야 한다.
만약 제대로 설치되면 체감 속도의 향상을 기대할 수 있으므로, 낡은 기기에 ROM을 바꾸어 사용하려면 검토할 가치는 충분하다.
4. 그 외
F2FS를 적용한 기기와 ext4를 적용한 기기의 속도비교 또 퀄컴 스냅드래곤 800 이전 기기에서 보다 체감 효과가 크다고 알려져 있다. 예를 들어 갤럭시 S2라든가…CyanogenMod의 마시멜로 기반 최신 버전 롬인 CM13에서는 이를 지원하고, 일부 커스텀 커널에서도 지원한다.
플래시 메모리에서 쓰라고 만들었지만, 플래시 메모리가 아닌 일반 하드디스크에서 사용해도 큰 문제는 없다. 다만 일부 프로그램의 준비 시간이 좀 길어지기는 한다. (Phoronix 벤치마크)