00 F2FS tasarım felsefesi
F2FS (Flash-Friendly File System), Samsung tarafından 2012 yılında geliştirilen ve 2012 sonunda mainline Linux kernel'a kabul edilen log-structured dosya sistemidir. Geleneksel blok cihaz odaklı dosya sistemlerinin flash ortamında yarattığı sorunları adresler.
Neden yeni bir dosya sistemi?
ext4 ve diğer geleneksel dosya sistemleri HDD'nin rastgele erişim ve yerinde güncelleme (in-place update) modeline göre tasarlanmıştır. NAND flash bu modele uymaz:
- NAND yazmadan önce silme gerektirir — silme birimi (erase block) yazma biriminden (sayfa) çok daha büyüktür
- Yerinde güncelleme mümkün değildir — mevcut sayfayı güncellemek için erase block silinip yeniden yazılmalıdır
- Yazma güçlendirmesi (write amplification) artışı wear leveling'i bozar
- Küçük rastgele yazmalar özellikle zararlıdır — her küçük yazma büyük erase block'u tetikler
F2FS'in temel öncülleri
Genel mimari
Flash Aygıt (eMMC / UFS / NVMe)
┌──────────────────────────────────────────────┐
│ Superblock (SB) │ CP Area │ SIT │ NAT │ SSA │
│ (metadata) (2 kopy) │ (segment bilgisi) │
├──────────────────────────────────────────────┤
│ Main Area │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Seg 0 │ │Seg 1 │ │Seg 2 │ │Seg N │ ... │
│ │ 2MB │ │ 2MB │ │ 2MB │ │ 2MB │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
└──────────────────────────────────────────────┘
SB: SuperBlock CP: CheckPoint SIT: Segment Info Table
NAT: Node Address Table SSA: Segment Summary Area
F2FS, eMMC ve UFS tabanlı Android cihazlarda ve gömülü Linux'ta yaygındır. Ext4'ün yerini almaz; düzenli güncellemeli, sıkça yazılan bölümler (data partition, /var, /tmp) için idealdir. Read-only rootfs için squashfs hâlâ üstündür.
Bu bölümde
- F2FS log-structured yapısı NAND flash'ın yazma modeliyle örtüşür
- Multi-stream logging benzer ömürlü verileri bir arada tutarak GC'yi iyileştirir
- NAT tablosu yerinde güncelleme simülasyonu yaparak üst katmanlara saydam çalışır
01 Node / segment / section / zone hiyerarşisi
F2FS verisi dört seviyeli hiyerarşik yapıda düzenlenir. Bu yapıyı anlamak GC stratejisi ve performans optimizasyonu için kritiktir.
Hiyerarşi açıklaması
| Seviye | Boyut (varsayılan) | Açıklama |
|---|---|---|
| Block | 4 KB | En küçük I/O birimi. Bir sayfa (page) eşdeğeri |
| Segment | 2 MB (512 block) | Temel yönetim birimi. SIT her segment için valid block sayısını izler |
| Section | Varsayılan 1 segment | GC birimi — tüm section bir arada temizlenir |
| Zone | Varsayılan 1 section | Flash cihazın fiziksel erase block grubuyla hizalama birimi |
Node ve Data ayrımı
6 yazma akışı (active log)
Yazma Akışları:
┌───────────────────────────────────────────────┐
│ Hot Node Log │ Warm Node Log │ Cold Node │
│ (inode'lar) │ (direct node) │ (indirect)│
├─────────────────┼─────────────────┼────────────┤
│ Hot Data Log │ Warm Data Log │ Cold Data │
│ (directory) │ (normal write) │ (GC moved)│
└───────────────────────────────────────────────┘
Her akış = bağımsız aktif segment
Checkpoint yapısı
# F2FS superblock ve checkpoint bilgisi
dump.f2fs -d 1 /dev/mmcblk1p2
# Örnek çıktı (önemli alanlar):
# Info: checkpoint state = 5 : crc consistent unmount
# Info: current valid block count = 52428
# Info: BIO count = 0
# sysfs üzerinden anlık istatistik
cat /sys/fs/f2fs/mmcblk1p2/stat
Bu bölümde
- Segment (2 MB) temel yönetim birimidir; section GC birimidir
- 6 akışlı logging hot/warm/cold ayrımı ile GC etkinliğini artırır
- Node ve Data blokları ayrı segmentlerde tutulur — korelasyon azalır
02 mkfs.f2fs ve mount options
mkfs.f2fs ile F2FS formatlanır ve mount seçenekleriyle çalışma zamanı davranışı ayarlanır.
mkfs.f2fs — format seçenekleri
# Temel format
mkfs.f2fs /dev/mmcblk1p2
# Tüm seçeneklerle (üretim)
mkfs.f2fs \
-l "data-part" \
-O encrypt \
-O extra_attr \
-O compression \
-t 1 \
/dev/mmcblk1p2
# -l : etiket
# -O encrypt : dosya bazlı şifreleme desteği (fscrypt)
# -O extra_attr : genişletilmiş inode attribute
# -O compression : dosya bazlı sıkıştırma (LZ4/zstd)
# -t 1 : trim (discard) desteği etkin
# eMMC provision üretim scripti
mkfs.f2fs \
-a 1 \
-s 1 \
-z 1 \
-l "userdata" \
-O encrypt,extra_attr,compression \
/dev/mmcblk0p5
# -a : segs_per_sec (1 = segment=section)
# -s : secs_per_zone
# -z : zone sayısı
Önemli mount seçenekleri
| Seçenek | Açıklama | Tavsiye |
|---|---|---|
| discard / nodiscard | Mount sırasında sürekli TRIM — erase block anlık serbest bırakılır | Destekleyen eMMC'de etkin |
| nobarrier | Write barrier devre dışı — güç kesilirse veri kaybı riski | UPS olan sistemlerde |
| lazytime | Zaman damgası güncellemelerini belleğe topla, bellekten yaz | Her zaman önerilir |
| background_gc=off/on/sync | Arkaplan GC modu | on varsayılan, sync acil durum |
| gc_merge | Foreground/background GC birleştir | Yüksek yazma baskısında |
| compress_algorithm=lz4 | Dosya bazlı LZ4 sıkıştırma | Log/metin dosyaları için |
| active_logs=6 | 6 yazma akışı (varsayılan) | Her zaman 6 |
| alloc_mode=default/reuse | Segment tahsis modu | default genelde iyi |
| extent_cache | Extent önbellekle sıralı okuma hızlandır | Büyük dosyalarda |
# /etc/fstab — üretim gömülü sistem için
UUID=1234abcd /data f2fs defaults,discard,lazytime,nodiratime,background_gc=on 0 2
# /tmp için tmpfs ile birlikte (F2FS'i korur)
tmpfs /tmp tmpfs defaults,noatime,mode=1777,size=64M 0 0
# Anlık mount test
mount -t f2fs -o discard,lazytime,background_gc=on \
/dev/mmcblk1p2 /data
# Mevcut mount seçeneklerini göster
cat /proc/mounts | grep f2fs
Bu bölümde
- mkfs.f2fs -O encrypt,compression ile fscrypt ve inline sıkıştırma aktifleşir
- discard + lazytime kombinasyonu günlük kullanım için önerilen temel settir
- /tmp için tmpfs F2FS wear'ı azaltır — flash ömrünü korur
03 Garbage collection — GC tuning
F2FS'in log-structured yapısı zamanla geçersiz (stale) bloklar biriktirir. GC bu blokları temizleyerek boş segment sağlar. GC stratejisi performans ve ömür dengesini doğrudan etkiler.
GC türleri
GC sysfs parametreleri
# F2FS sysfs dizini (mmcblk1p2 mount edilmiş)
ls /sys/fs/f2fs/mmcblk1p2/
# GC ayarları
cat /sys/fs/f2fs/mmcblk1p2/gc_min_sleep_time # ms cinsinden
cat /sys/fs/f2fs/mmcblk1p2/gc_max_sleep_time
cat /sys/fs/f2fs/mmcblk1p2/gc_idle_interval
# Agresif GC etkinleştir (boş alan kritik)
echo 1 > /sys/fs/f2fs/mmcblk1p2/gc_urgent
echo 50 > /sys/fs/f2fs/mmcblk1p2/gc_min_sleep_time
echo 500 > /sys/fs/f2fs/mmcblk1p2/gc_max_sleep_time
# Normal mod (düşük yazma baskısı)
echo 0 > /sys/fs/f2fs/mmcblk1p2/gc_urgent
echo 10000 > /sys/fs/f2fs/mmcblk1p2/gc_min_sleep_time
echo 30000 > /sys/fs/f2fs/mmcblk1p2/gc_max_sleep_time
# Manuel GC tetikle (maintenance penceresi)
echo 1 > /sys/fs/f2fs/mmcblk1p2/gc_urgent
sleep 30
echo 0 > /sys/fs/f2fs/mmcblk1p2/gc_urgent
GC algoritmaları
| Algoritma | Seçim kriteri | Avantaj | Dezavantaj |
|---|---|---|---|
| Greedy | En az valid block içeren segment | En az taşıma, düşük gecikme | Kötü locality, parçalanma |
| Cost-Benefit | Age + utilization skoru | Wear leveling daha iyi | Daha yüksek CPU |
# GC istatistiklerini izle
cat /sys/fs/f2fs/mmcblk1p2/stat | grep -i gc
# dump.f2fs ile detaylı istatistik
dump.f2fs -s /dev/mmcblk1p2
# Seçili segment bilgisi
dump.f2fs -S /dev/mmcblk1p2 | head -50
# iostat ile GC sırasında I/O izle
iostat -x mmcblk1 1 30
Bu bölümde
- Background GC tercih edilmeli — foreground GC gecikme spike'larına yol açar
- gc_urgent=1 kritik düşük boş alan için acil modudur
- GC parametreleri sysfs üzerinden çalışma zamanında ayarlanabilir
04 Discard / TRIM entegrasyonu
TRIM (ATA TRIM / eMMC Discard), dosya silindiğinde blokların artık kullanılmadığını depolama denetleyicisine bildirir. Bu bildirim wear leveling ve GC etkinliğini artırır.
TRIM çalışma mekanizması
Uygulama dosyayı siler
↓
F2FS: blokları "geçersiz" işaretler
↓
┌──────────┬────────────────┐
│ discard │ fstrim │
│ (mount │ (periyodik │
│ seçeneği)│ komut) │
└──────────┴────────────────┘
↓ her iki yol da eMMC DISCARD CMD38 gönderir
eMMC Denetleyici: blok havuzuna geri al
↓
Sonraki yazma daha temiz erase block üzerinden
Discard modları
# 1. Mount-time discard (anlık — her silmede TRIM gönderir)
mount -t f2fs -o discard /dev/mmcblk1p2 /data
# 2. Periyodik fstrim (batch — daha az overhead)
# /etc/cron.d/fstrim veya systemd timer ile
fstrim -av # tüm mount edilmiş FS'lere TRIM gönder
fstrim -v /data # sadece /data
# Systemd weekly timer (fstrim.timer)
systemctl enable --now fstrim.timer
systemctl status fstrim.timer
# 3. F2FS background discard (önerilen — batch)
# /sys/fs/f2fs parametreleri
cat /sys/fs/f2fs/mmcblk1p2/discard_granularity
echo 4 > /sys/fs/f2fs/mmcblk1p2/discard_granularity # 4*segment = 8MB
# eMMC discard desteğini kontrol et
cat /sys/block/mmcblk1/queue/discard_max_bytes
cat /sys/block/mmcblk1/queue/discard_granularity
fstrim periyodik timer
# /etc/systemd/system/fstrim-data.service
[Unit]
Description=F2FS veri partisyon TRIM
After=data.mount
[Service]
Type=oneshot
ExecStart=/sbin/fstrim -v /data
ExecStart=/sbin/fstrim -v /var
# /etc/systemd/system/fstrim-data.timer
[Unit]
Description=Haftalık F2FS TRIM
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
Anlık discard mount seçeneği her silme işleminde eMMC komut göndererek gecikme yaratır. Batch discard (fstrim.timer) genel olarak daha iyi throughput sağlar. Ancak düşük boş alan durumunda anlık discard eMMC'nin daha hızlı yer açmasına yardımcı olur.
Bu bölümde
- discard mount seçeneği anlık TRIM, fstrim.timer batch TRIM sağlar
- eMMC discard desteği /sys/block/mmcblk*/queue/ üzerinden doğrulanmalı
- Background discard + haftalık fstrim kombinasyonu genelde en dengelisidir
05 Wear leveling yaklaşımı
F2FS, yazmaları tüm flash alanına yayarak her erase block'un eşit oranda yıpranmasını sağlar. Bu dinamik wear leveling, flash ömrünü doğrudan etkiler.
F2FS'te wear leveling mekanizması
Write amplification faktörü (WAF)
# eMMC write counter (JEDEC Health registers)
mmc extcsd read /dev/mmcblk0 | grep -i life
# F2FS istatistiklerinden WAF tahmini
cat /sys/fs/f2fs/mmcblk1p2/stat
# GC: data segs written vs user data written
# fio ile gerçekçi WAF testi
fio --filename=/data/waf_test \
--rw=randwrite \
--bs=4k \
--ioengine=libaio \
--iodepth=32 \
--size=256M \
--numjobs=4 \
--time_based \
--runtime=300 \
--name=waf_randwrite \
--group_reporting
WAF minimizasyon stratejileri
| Strateji | Yöntem | Beklenen Etki |
|---|---|---|
| Küçük yazmaları topla | Uygulama buffering veya tmpfs kullan | WAF %30–50 azalır |
| Sıralı yazma zorla | O_DIRECT + büyük blok boyutu | WAF ~1.0 hedefe yaklaşır |
| Log dosyası rotasyonu | Sabit boyutlu log, döngüsel yaz | Sıcak alan sınırlanır |
| /tmp için tmpfs | mount -t tmpfs tmpfs /tmp | Flash yazma tamamen ortadan kalkar |
| fsync azalt | Uygulama fsync politikasını gözden geçir | GC baskısı azalır |
Bu bölümde
- F2FS log-structured yazma ile doğal dinamik wear leveling sağlar
- Statik wear leveling eMMC kontrolcüsünün görevidir — F2FS WAF'ı minimize eder
- Küçük rastgele yazmaları toplamak WAF'ı en çok azaltan stratejidir
06 F2FS vs ext4 vs UBIFS karşılaştırması
Gömülü storage için doğru dosya sistemi seçimi kullanım senaryosuna bağlıdır. Üç ana alternatifi karşılaştırıyoruz.
| Özellik | F2FS | ext4 | UBIFS |
|---|---|---|---|
| Hedef depolama | Yönetilen flash (eMMC, UFS, NVMe, SD) | Yönetilen flash, HDD, SSD | Ham NAND flash (MTD) |
| Yazma modeli | Log-structured (append-only) | Journal (in-place update) | Log-structured |
| Rastgele yazma | Mükemmel (append → sıralı) | Orta (journal overhead) | İyi |
| Sıralı okuma | Çok iyi | Çok iyi | İyi |
| Wear leveling | Dinamik (log + GC) | Yok (kontrolcüye bırakır) | LEB tahsis + WL |
| Güç kesintisi | Checkpoint + rollback | Journal replay | Journal + WB |
| GC | Background/foreground | Yok (trimle) | Background GC |
| Compression | Dosya bazlı (LZ4/zstd) | Yok (btrfs'e bak) | LZO/zlib dahili |
| TRIM desteği | Var (discard/fstrim) | Var (discard/fstrim) | Yok (ham NAND) |
| Kernel maturity | Mainline 3.8+, kararlı | Çok kararlı | Mainline, kararlı |
| MTD desteği | Yok | Yok | Sadece MTD |
| Snapshot | Yok (Btrfs'e bak) | Yok | Yok |
Seçim rehberi
Bu bölümde
- F2FS yönetilen flash (eMMC/UFS) için ext4'ten belirgin şekilde üstündür
- Ham NAND için UBIFS tek geçerli seçenektir — eMMC ile çalışmaz
- Read-only root için squashfs en verimli çözümdür
07 f2fs-tools — fsck, dump, defrag
f2fs-tools paketi, F2FS dosya sistemi bakım araçlarını içerir: fsck.f2fs, dump.f2fs, defrag.f2fs, resize.f2fs ve sload.f2fs.
fsck.f2fs — tutarlılık denetimi
# Temel kontrol (read-only)
fsck.f2fs /dev/mmcblk1p2
# Onarım modunda çalıştır
fsck.f2fs -f -y /dev/mmcblk1p2
# -f : zorla kontrol
# -y : tüm soruları evet cevapla (otomatik onarım)
# Verbose çıktı
fsck.f2fs -v /dev/mmcblk1p2
# Hızlı mod (sadece metadata)
fsck.f2fs -q /dev/mmcblk1p2
# Boot öncesi initramfs'te (systemd-fsck yerine)
# /etc/fstab'da son alan 2 (nonzero = fsck etkin)
dump.f2fs — istatistik ve analiz
# Superblock bilgisi
dump.f2fs -d 1 /dev/mmcblk1p2
# Segment bilgisi
dump.f2fs -s /dev/mmcblk1p2 | head -30
# Node bilgisi (ino numarası ver)
dump.f2fs -n 3 /dev/mmcblk1p2
# Tüm inode listesi
dump.f2fs -i /dev/mmcblk1p2 | head -20
# Checkpoint bilgisi
dump.f2fs -c /dev/mmcblk1p2
defrag.f2fs ve resize.f2fs
# Disk birleştirme (online — mount edilmişken)
defrag.f2fs /dev/mmcblk1p2
# Spesifik bir dosyayı birleştir
defrag.f2fs -f /data/büyük_dosya.img /dev/mmcblk1p2
# Boyut küçültme (offline — mount edilmemişken)
resize.f2fs -t /dev/mmcblk1p2 # hedef boyutu yazdır
resize.f2fs /dev/mmcblk1p2 # maksimum boyuta büyüt
# sload.f2fs — host'ta imaj içine dosya kopyala
# (üretim imaj oluşturma için)
sload.f2fs -f /path/to/rootfs -t / /dev/loop0
# mkfs + sload ile imaj oluşturma
dd if=/dev/zero bs=1M count=512 of=data.img
mkfs.f2fs data.img
sload.f2fs -f /path/to/data -t / data.img
Bu bölümde
- fsck.f2fs -f -y ile otomatik onarım, boot öncesi script'e eklenebilir
- dump.f2fs segment analizi GC verimliliğini izlemek için kullanılır
- sload.f2fs üretim imaj oluşturmada host-side dosya yerleşimi sağlar
08 Pratik: BeagleBone eMMC'de F2FS + GC tuning
BeagleBone Black'in 4 GB eMMC'sinde veri partisyonunu F2FS olarak formatla, GC parametrelerini optimize et ve wear izleme scripti yaz.
Hedef bölüm düzeni
| Partition | Boyut | FS | Amaç |
|---|---|---|---|
| mmcblk1p1 | 64 MB | FAT32 | Boot (MLO, u-boot, uImage, dtb) |
| mmcblk1p2 | 1.5 GB | ext4 (ro) | Root filesystem (squashfs yerine ext4 ro) |
| mmcblk1p3 | 2 GB | F2FS | Data (log, config, user data) |
| mmcblk1p4 | kalan | F2FS | /var + /tmp overlay |
Adım 1 — F2FS formatla
# eMMC bölümle (sgdisk)
sgdisk --zap-all /dev/mmcblk1
sgdisk --new=1:2048:133119 --typecode=1:0700 --change-name=1:"boot" /dev/mmcblk1
sgdisk --new=2:133120:3278847 --typecode=2:8300 --change-name=2:"rootfs" /dev/mmcblk1
sgdisk --new=3:3278848:7472127 --typecode=3:8300 --change-name=3:"data" /dev/mmcblk1
sgdisk --new=4:7472128:0 --typecode=4:8300 --change-name=4:"var" /dev/mmcblk1
# F2FS formatla
mkfs.f2fs -l "bbb-data" -O encrypt,extra_attr,compression -t 1 /dev/mmcblk1p3
mkfs.f2fs -l "bbb-var" -O extra_attr -t 1 /dev/mmcblk1p4
# Mount test
mount -t f2fs -o discard,lazytime,background_gc=on /dev/mmcblk1p3 /data
df -h /data
Adım 2 — /etc/fstab ve systemd mount
# /etc/fstab
UUID=$(blkid -s UUID -o value /dev/mmcblk1p3)
$UUID /data f2fs defaults,discard,lazytime,nodiratime,background_gc=on 0 2
UUID=$(blkid -s UUID -o value /dev/mmcblk1p4)
$UUID /var f2fs defaults,discard,lazytime,nodiratime,background_gc=on 0 2
# tmpfs /tmp
tmpfs /tmp tmpfs defaults,noatime,mode=1777,size=32M 0 0
Adım 3 — GC tuning scripti
#!/bin/bash
# F2FS GC parametrelerini disk doluluk oranına göre ayarla
set -e
F2FS_MOUNTS=( /data /var )
tune_gc() {
local mountpoint="$1"
local dev
dev=$(findmnt -n -o SOURCE "$mountpoint" | sed 's|/dev/||')
local sysfs="/sys/fs/f2fs/${dev}"
[ -d "$sysfs" ] || return
# Kullanım yüzdesi
local usage
usage=$(df "$mountpoint" | awk 'NR==2{gsub(/%/,""); print $5}')
if [ "$usage" -ge 85 ]; then
# Kritik — agresif GC
echo 1 > "$sysfs/gc_urgent"
echo 100 > "$sysfs/gc_min_sleep_time"
echo 1000 > "$sysfs/gc_max_sleep_time"
logger "F2FS GC: $mountpoint %$usage dolu — agresif GC modu"
elif [ "$usage" -ge 70 ]; then
# Uyarı — orta GC
echo 0 > "$sysfs/gc_urgent"
echo 1000 > "$sysfs/gc_min_sleep_time"
echo 10000 > "$sysfs/gc_max_sleep_time"
logger "F2FS GC: $mountpoint %$usage dolu — orta GC modu"
else
# Normal — yavaş GC
echo 0 > "$sysfs/gc_urgent"
echo 10000 > "$sysfs/gc_min_sleep_time"
echo 30000 > "$sysfs/gc_max_sleep_time"
fi
}
for mp in "{{F2FS_MOUNTS[@]}}"; do
tune_gc "$mp"
done
Adım 4 — Wear izleme
#!/bin/bash
# /usr/local/sbin/emmc-health-check.sh
DEVICE="/dev/mmcblk1"
LOGFILE="/data/logs/emmc-health.log"
check_health() {
local ts
ts=$(date '+%Y-%m-%d %H:%M:%S')
# eMMC yaşam süresi tahminleri
local life_a life_b eol
life_a=$(mmc extcsd read "$DEVICE" 2>/dev/null | \
grep "DEVICE_LIFE_TIME_EST_TYP_A" | awk '{print $NF}')
life_b=$(mmc extcsd read "$DEVICE" 2>/dev/null | \
grep "DEVICE_LIFE_TIME_EST_TYP_B" | awk '{print $NF}')
eol=$(mmc extcsd read "$DEVICE" 2>/dev/null | \
grep "PRE_EOL_INFO" | awk '{print $NF}')
echo "$ts LIFE_A=$life_a LIFE_B=$life_b EOL=$eol" >> "$LOGFILE"
# EOL uyarısı
if [ "$eol" = "0x02" ]; then
logger -p user.warning "eMMC EOL UYARI: $DEVICE yıpranma uyarısı!"
elif [ "$eol" = "0x03" ]; then
logger -p user.crit "eMMC EOL KRİTİK: $DEVICE acil değişim!"
fi
}
check_health
Bu bölümde
- BeagleBone eMMC data partisyonu F2FS ile formatlandı ve optimize edildi
- GC tuning scripti disk doluluk oranına göre dinamik parametre ayarlar
- eMMC health script, mmc extcsd ile JEDEC ömür tahminlerini izler