SSDs, Sektorgrößen, und das Jahr 2022

Ich dachte ja eigentlich, dass ich mich Jahr 2022 mit solchen Details nicht mehr auseinandersetzen müsste, aber da habe ich mich wohl geirrt.

Worum geht's?

Die nicht mehr ganz so jungen Generationen erinnern sich, Festplatten hatten historisch bedingt eine Sektorgröße von 512 Byte. Mit Aufkommen des Advanced Format (AF) hatte man das auf 4096 Byte (4K) geändert. Vorteil war, dass man mit einer Leseoperation die 8-fache Menge an Daten bekam, das Ganze besser zur Größe der Speicherseite („page size“) moderner Prozessoren passt, insgesamt bessere Performance liefert, und generell auch erlaubt mehr Daten bei gleicher Adressierung anzusprechen. Seit ca. 2011 unterstützt so ziemlich jeder Datenträger (ausgenommen microSD-Karten/USB-Sticks und anderes eher Low-Level Flash-Gedöns) dieses Format.

Und wie immer gibt's einen fetten Haken an der Sache: Aufgrund der Abwärtskompatibilität können die meisten (wenn nicht alle) dieser Datenträger auch mit 512 Byte Sektorgröße umgehen, womit auch alle oben genannten Vorteile verschwinden.

Und mein Dateisystem möchte?

Und da wird's jetzt unangenehm. Es ist nämlich so, dass moderne Dateisysteme mit Sektorgrößen von 4K arbeiten, d.h. eine Sektorgröße von 512 Byte auf dem Datenträger, der intern eigentlich auch 4K verwendet, ergibt mal so überhaupt gar keinen Sinn.

Ich hab mal für die IMHO gebräuchlichsten Dateisysteme nachgesehen:

  • btrfs will mindestens 4K
  • ext4 will mindestens 1K (Standard ist trotzdem 4K)
  • f2fs 512 Byte (was insofern Sinn ergibt, weil es eher für Flashspeicher in microSD-Karten und USB-Sticks konzipiert ist)
  • ZFS nutzt mindestens 4K
  • XFS will mindestens 512 Byte, nutzt aber 4K falls möglich
  • NTFS nutzt ab Windows 7 durchgängig mindestens 4K
  • FAT (FAT16/32) nutzt ab 128MB Größe der Partition auch 4K
  • ...und exFAT nutzt ebenfalls Sektorgrößen ab 4K aufwärts

Sektorgrößen auslesen

Mittels parted -l lassen sich Sektorgrößen ausgeben, sieht bei einer SATA-SSD bspw. wie folgt aus:

[root:~] # parted -l
Modell: ATA SK hynix SC311 S (scsi)
Festplatte  /dev/sda:  256GB
Sektorgröße (logisch/physisch): 512B/4096B
Partitionstabelle: gpt
Disk-Flags:
[…]

Bei einer NVMe-SSD sieht's etwas anders aus, diese lassen sich in der Regel intern umformatieren. Heißt: Die Ausgabe von parted -l zeigt bspw. folgendes an:

[root:~] # parted -l
Modell: TOSHIBA-RC100 (nvme)
Festplatte  /dev/nvme0n1:  240GB
Sektorgröße (logisch/physisch): 4096B/4096B
Partitionstabelle: gpt
[…]

In Wahrheit kann das Ding aber viel mehr, je nach Konfiguration. Das bekommt man mittels smartctl -a /dev/<device> heraus:

[root:~] # smartctl -a /dev/nvme0n1
smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.15.12-200.fc35.x86_64] (local build)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
[…]
Namespace 1 Formatted LBA Size:     4096

[…]

Supported LBA Sizes (NSID 0x1)
Id Fmt  Data  Metadt  Rel_Perf
 0 +    4096       0         0
 1 -     512       0         3

[…]

[root:~] # 

Wie man sehen kann, nutzt die NVMe-SSD aktuell eine Sektorgröße von 4K, könnte aber auch 512 Byte. Was man hier nicht sieht: Die 512 Byte waren ursprünglich vorkonfiguriert, aufgrund der AbWäRtSkOmPaTiBiLiTäT, was mal eben die Datenrate von 1,4GB/s auf nicht ganz so schöne 700MB/s halbiert. Kannste dir nicht ausdenken, dass sowas als Standard ausgeliefert wird...

Noch schöner finde ich in der Tabelle hinten den Eintrag Rel_Perf, der gibt nämlich schon an, dass 4K Sektorgröße deutlich schneller sind als 512 Byte Sektorgröße. Warum man dann trotzdem 512 Byte als Standard anbietet, wenn literally jedes Betriebssystem heutzutage mit 4K umgehen kann? Keine Ahnung.

Aber zumindest LUKS nutzt 4K, ja?

Noch lustiger wird's allerdings, weil meine Datenträger alle verschlüsselt sind. Man würde jetzt denken, hey, wenn logisch 512 Byte angegeben sind, und physisch 4K, dann nimmt doch LUKS auf jeden Fall auch 4K Sektorgröße, nicht? Oder noch besser: Standardmäßig einfach immer 4K nehmen, weil insgesamt die bessere Wahl? Vor allem, wenn das Dateisystem, welches sich später innerhalb der LUKS-Partition befindet, mit unglaublich hoher Wahrscheinlichkeit ebenfalls 4K Sektorgrößen verwendet? Denkste.

Aufgrund der oben genannten AbWäRtSkOmPaTiBiLiTäT nutzt LUKS, wenn's die Wahl hat, auch lieber 512 Byte.

Bevor man weitermacht…

Um's nochmal kurz zu umreißen: Wer ein Dateisystem mit 4K Sektorgröße einsetzt, und evtl. auch noch LUKS, auf einer SSD die angibt mit 512 Byte Sektorgröße zu arbeiten, kann durch Umstellung auf 4K etwas mehr Datenrate herausholen.

„etwas mehr“ bedeutet hierbei, soweit ich das ermitteln konnte, zwischen 0 und 100 Prozent. Eine Umstellung bringt im schlechtesten Falle also nichts, im besten Falle verdoppelt sich die Datenrate (wie bei mir geschehen).

Vorher empfiehlt sich wie immer ein Backup zu machen, und natürlich auch zu schauen womit die Hardware und womit die Software wirklich arbeitet (via parted -l, cryptsetup luksDump, und dateisystemspezifischen Tools zum Auslesen der Sektorgröße).

LUKS-Partition auf SATA-SSDs umstellen

Das Gute: LUKS-Partitionen auf SATA-SSDs lassen sich im laufenden Betrieb von 512 Byte auf 4K umstellen. Dazu muss zwar die komplette Partition gelesen und neu verschlüsselt werden, aber LUKS ist in der Hinsicht wirklich durchdacht, denn auch ein Absturz des Rechners richtet hier i.d.R. keinen Schaden an. Man kann den Prozess jederzeit unterbrechen und später fortsetzen.

Zuerst sollte man aber prüfen, ob LUKS nicht doch schon zufälligerweise die richtige Sektorgröße verwendet:

[root:~] # cryptsetup luksDump /dev/sdxY
LUKS header information
Version:       	2
[…]
Data segments:
  0: crypt
	offset: 16777216 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 512 [bytes]
[…]

Wie man sehen kann ist das nicht der Fall. Eine Umstellung kann mittels cryptsetup reencrypt erfolgen:

[root:~] # cryptsetup --type luks2 --sector-size 4096 reencrypt /dev/sdxY

Wichtig: Der Vorgang kann (muss aber nicht) das darin befindliche Dateisystem unbrauchbar machen. Ich hab's bei insgesamt vier Partitionen getestet (mit darin befindlichem btrfs-Dateisystem), und hatte keine Probleme.

NVMe-SSDs neu formatieren auf 4K

Bei NVMe-SSDs sieht die Sache etwas anders aus, hier muss man nämlich erst die interne Sektorgröße umstellen, was bei mir zum Verlust aller Daten geführt hat. Mittels nvme id-ns kann man die unterstützten LBA-Größen auswählen, und dann mittels nvme format die NVMe-SSD entsprechend formatieren:

[root:~] # nvme id-ns /dev/nvme0n1 | grep lbaf
[…]
lbaf  0 : ms:0   lbads:12 rp:0
lbaf  1 : ms:0   lbads:9  rp:0x3 (in use)

[root:~] # nvme format --lbaf 0 /dev/nvme0n1
[…]

[root:~] # nvme id-ns /dev/nvme0n1 | grep lbaf
[…]
lbaf  0 : ms:0   lbads:12 rp:0 (in use)
lbaf  1 : ms:0   lbads:9  rp:0x3

Dann eine neue Partitionstabelle erstellen, eine LUKS-Partition mit Sektorgröße 4K anlegen, und darin dann das gewünschte Dateisystem erstellen. Gut, und Daten zurückspielen, die man vorher natürlich™ gesichert hat.

Wie sieht's bei HDDs aus?

Kann ich ehrlich nicht beantworten. Ich kann mir vorstellen, dass HDDs in der Hinsicht wie SATA-SSDs funktionieren: Intern also 4K verwenden, logisch aber 512 Byte angeben. Tests dazu habe ich aber noch nicht gemacht - ich habe zur Zeit HDDs ausschließlich als Storage im Einsatz, d.h. mit relativ langsamen Datenraten und dafür relativ groß. Diese im laufenden Betrieb neu zu formatieren ist mir dann doch etwas zu heikel - da muss sich erst die Chance ergeben günstig irgendwo eine 4TB-Platte zu erwerben, die ich dann auch gleich meinem RAID hinzufügen kann. Ich kann aber sagen, dass die Ausgabe von parted -l für meine 4TB-Platten 512/4096 ausgibt, und für meine 1TB-Platte aus dem Jahr 2009 512/512 (was logisch ist, da das eingangs erwähnte Advanced Format 2009 noch nicht standardisiert war - hier waren 512 Byte Sektorgrößen noch der Standard).

Fazit

Anregung zu dem Artikel hat übrigens dieser Post auf Reddit gegeben. Ich persönlich ärgere mich ja, dass mir das zum einen nicht früher aufgefallen ist (normalerweise™ teste ich meine Hardware vor Inbetriebnahme, aber bei meinem aktuellen ThinkPad war damals keine Zeit, und dann habe ich einfach alle Defaults übernommen), zum anderen verstehe ich nicht ganz, warum man im Jahr 2022 überhaupt noch Datenträger bekommt die etwas von 512 Byte vorgaukeln. Abgesehen davon hat die Umstellung von 512 Byte auf 4K die Datenrate auf meiner NVMe-SSD verdoppelt.

Nerdige Notiz am Rande: Ich habe selbstverständlich nicht ein extra Backup meiner NVMe-SSD gemacht (generell Backups existieren natürlich schon), diese dann neu formatiert, und alle Daten zurückgespielt. Da ich btrfs verwende habe ich einfach die Daten im laufenden Betrieb auf eine andere SSD geschoben, dann die NVMe-SSD formatiert, und dann wieder zurückgeschoben. Alles im laufenden Betrieb. Zero Downtime 😎

Und die restlichen LUKS-Partitionen auf den SATA-SSDs wurden auch im laufenden Betrieb konvertiert. Alles andere wäre ja langweilig 😉