BTRFS ist ein modernes Copy-on-Write-Dateisystem (COW) für Linux, das auf die Implementierung erweiterter Funktionen abzielt und gleichzeitig den Schwerpunkt auf Fehlertoleranz, Reparatur und einfache Verwaltung legt. Seine Hauptfunktionen und Vorteile sind:
Ein BTRFS Dateisystem wird mit mkfs.btrfs erstellt. Die häufigsten Optionen, die bei der Erstellung des Dateisystems mit angeben werden sind:
raid56
oder quota
an/abzuschalten. Für eine vollständige Liste siehe auch -O list-all
Dieser Befehl gibt dem Dateisystem einen Namen, verwendet den xxhash
Algorithmus für Checksummen und deaktiviert die Funktionen raid56
und quota
:
# mkfs.btrfs -L "Label-Name" --csum xxhash -O ^raid56,^quota
Ein BTRFS-Subvolumen ist ein Teil eines Dateisystems mit einer eigenen, unabhängigen Datei-/Verzeichnishierarchie und einem Inode-Nummern-Namespace. Subvolumen können Dateibereiche gemeinsam nutzen.
Hinweis: Subvolumen können verwendet werden, um bei der Erstellung eines Snapshots dieses Subvolumen auszulassen. Da immer nur das angebe, Subvolumen von einem Snapshot betroffen ist und andere Subvolumen nicht mit gesichert werden.
Für weitere Informationen siehe:
Dieser Befehl geht davon aus, dass man sich im Root Verzeichnis seines Btrfs Dateisystems (Subvolume ID 5) befindet. Und legt gleich mehrere Subvolumen auf einmal an. @ für das Betriebssystem Wurzel Verzeichnis, @home für das /home
Verzeichnis @cache für /var/cache
und @.snapshots für spätere Snapshots Ablage unter /.snapshots
.
# btrfs subvolume create @ @home @cache @.snapshots
Für spätere forensische Untersuchungen der Logs, könnte man das Verzeichnis /var/log
in einem eigenen Subvolumen @log auslagern, damit bei einem Rollback des @ Subvolumes die Logs erhalten bleiben.
Die Auslagerung des /var/log
Verzeichnisses in ein separates beschreibbaren Subvolumen ist eine Voraussetzung, falls man vorhat in einem Readonly Snapshots seines @ Subvolumen zu booten.
Es folgt ein Beispiel Mount Befehl, um ein angelegtes Subvolumen direkt zu mounten. Die wichtige Mount Option ist hierbei subvol=
womit das gewünschte Subvolumen angeben wird. Andere beliebte Mount Optionen sind noatime,compress=zstd,discard
# mount -t btrfs -o noatime,subvol=@ /dev/sdX /mnt/
Es folgt ein umfangreicher Beispiel fstab Eintrag:
UUID=c6757eef-ba72-4038-847f-a2ef19cf9c52 / btrfs rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvol=/@ 0 0
Ein Snapshot ist ebenfalls ein Subvolumen, jedoch mit einem vorgegebenen Anfangsinhalt des ursprünglichen Subvolumen. Ein Subvolumen hat immer die Inode-Nummer 256. Somit kann ein Snapshot wie eine schnelle Art von Referenzierung mit dem Inhalt eines anderen Subvolumen betrachtet werden, das sich nicht mit ändert.
Hinweis: Subvolumen können verwendet werden, um bei der Erstellung eines Snapshots dieses Verzeichnis (Subvolumen) auszulassen. Da immer nur das Angebe Subvolumen von einem Snapshot betroffen ist und andere Subvolumen nicht mit gesichert werden.
Ein Snapshot wird so angelegt:
btrfs subvolume snapshot [-r] <subvolume> <Speicherort des Snapshots>
Das Anlegen von eines Snapshots lässt sich mithilfe verschiedener Tools automatisieren. Eins davon ist yabsnapAUR. Für eine Erläuterung siehe dazu:
Es ist meist nicht gewollt, aus dem Wurzelverzeichnis (ID 5) in ein Subvolume zu chrooten. Angenommen die Dateisystem Wurzel ist unter /mnt/btrfs
gemountet und hier liegt ein Subvolume @ (/mnt/btrfs/@
):
Dann möchte man nicht:
chroot /mnt/btrfs/@
sondern vielmehr in das gemountet Subvolumen chrooten:
mount --mkdir -t btrfs -o noatime,subvol=@ /dev/sdX /mnt/btrfs-@/ chroot /mnt/btrfs-@/
Wenn eine Swapdatei verwendet werden soll, gibt es ein paar Dinge zu beachten:
@swap
anzulegen. Und diese z.b. unter /swap/
zu mounten.filefrag -v
bestimmen. Da Btrfs eine Abstraktionsschicht zum Mappen der Dateien verwendet. um das Offset zu bestimmen, gibt es auch eine Hilfefunktion in den btrfs tools siehe Offset der Swapdatei bestimmen# btrfs filesystem mkswapfile -U clear -s 2G <Datei>
btrfs inspect-internal map-swapfile -r <swapdatei>
Verzeichnis und/oder Dateien, deren Inhalt sich schnell und häufig ändert, wirkt sich COW nachteilig auf die Geschwindigkeit des Dateisystems aus.
Wichtig: für NO_COW
Dateien werden keine Checksummen gebildet. Dadurch kann keine stille Datenbeschädigung festgestellt werden. Und damit auch die Selbstheilung der Dateien deaktiviert, falls diese z.b. durch ein RAID1 Profil redundant vorgehalten werden. Da Btrfs schlicht und einfach nicht mehr feststellen kann, welche Version der Datei die noch intakte Variante ist.
Beispiele hierfür sind:
Für solche Anwendungsfälle lässt sich COW
deaktivieren. Dies kann mithilfe des C
ACL Flags erreicht werden. Wird das Flag auf ein Verzeichnis angewandt, so bekommen alle neu angelegten Dateien automatisch das C
(nocow) zugewiesen.
Soll hingegen das C
Flag auf eine Datei direkt angewandt werden, muss sichergestellt sein, dass diese Datei leer ist.
Ergänzender weise sei noch die nodatacow
mount Option erwähnt. Diese lässt sich aber meist nicht verwenden, da momentan Subvolumen noch nicht mit unterschiedlichen Mount Optionen gemountet werden können. Und somit dies nicht größtenteils nicht sinnvoll genutzt werden kann.
chattr +C <Verzeichnis/Datei>
$ mv /path/to/dir /path/to/dir_old $ mkdir /path/to/dir $ chattr +C /path/to/dir $ cp -a --reflink=never /path/to/dir_old/. /path/to/dir $ rm -rf /path/to/dir_old
Für einen Snapshot ist COW erfoderlich. Aus diesem Grund wird beim anlegen eines Snapshots bei der ersten Schreibopertation auf eine NO_COW
Datei. Eine COW Kopie für den Snapshot erstellt. Die nachfolgenden Schreibforgänge erfolgen dann wieder mit NO_COW
. Da das anlegen häufiger Snapshots von solchen Dateien wieder die Geschwindigkeit negativ beinflusst. Wird empfholen solche Dateien in einen eigenes Subvolumen unterzubringen das von dem Snapshot ausgeschlossen wird.
BTRFS kann sehr Speicherplatz effizient Daten vorhalten, indem die COW Eigenart des Dateisystems genutzt wird. Statt eine Datei ein zweites Mal physikalisch zu kopieren, wird stattdessen auf diese referenziert. Das sorgt dafür, dass nur neue Änderungen tatsächlich gespeichert werden müssen, und der Kopiervorgang ist quasi sofort erledigt. Nach diesem Prinzip arbeiten auch die Snapshots.
Leider kommen übliche Tools wie z.B.df
und du
mit solch referenzierten Daten nicht mit klar. Und zeigen somit nicht die ganze Wahrheit an. Diese Tools beziehen sich nur auf die Daten des aktuellen Subvolumen, und berücksichtigen nicht das Daten vielleicht noch in einen Snapshot referenziert vorliegen.
Somit kann es vorkommen, dass Daten im Subvolumen @ gelöscht wurden, df
meldet, dass der Speicherplatz freigeben wurde, aber tatsächlich diese Daten noch in einem Snapshot vorliegen. Genau sowenig kann das normale du
keine referenzierten Daten anzeigen.
Aus diesem Grund haben die btrfs-tools
ihre eigenen Varianten von diesen Tools. Die Referenzierungen und Komprimierung mit berücksichtigen.
btrfs filesystem df zeigt somit unter anderem an:
$ btrfs filesystem df /path Data, single: total=1.15TiB, used=1.13TiB System, single: total=32.00MiB, used=144.00KiB Metadata, single: total=12.00GiB, used=6.45GiB GlobalReserve, single: total=512.00MiB, used=0.00B
btrfs filesystem du
zeigt genauso wie sein analoger Bruder du
die Speicherplatzbelegung einzelner Dateien, und/oder die Summe ganzer Verzeichnisse an. Nur mit dem Unterschied, das zusätzlich noch angezeigt wird, ob die Menge an Daten einzigartig sind (keine weiteren Referenzen besitzen) oder noch durch eine Refernez in einem Subvolumen oder Reflink Kopie geteilt wird.
$ btrfs filesystem du -s /home/ Total Exclusive Set shared Filename 21.55GiB 5.85GiB 14.94GiB /home/
btrfs filesystem usage
ist die nützlichste Speicherplatzanzeige, die, btrfs-tools
zu bieten haben, dies muss auf ein Mountpoint des Dateisystems mit Root Rechten ausgeführt werden. Sie zeigt eine komplette Übersicht des ganzen Dateisystems an für die einzelnen Datenstrukturen wie: Data, Metadaten und System und was noch viel wichtiger ist, wie viel Speicherplatz das Dateisystem für bereits allokiert hat, und wie viel unallokierter Speicherplatz noch zur Verfügung steht (Tatsächlicher freier Speicher).
Damit Allokierter Speicherplatz wieder freigeben werden kann, so müssen alle Dateien/Daten in einem Extent zur Löschung markiert worden sein. Oder ein btrfs balance durchgeführt werden, um die Extents neu effizienter zusammenzupacken.
# btrfs filesystem usage / Overall: Device size: 931.51GiB Device allocated: 119.06GiB Device unallocated: 812.45GiB Device missing: 0.00B Device slack: 0.00B Used: 111.34GiB Free (estimated): 818.18GiB (min: 411.96GiB) Free (statfs, df): 818.18GiB Data ratio: 1.00 Metadata ratio: 2.00 Global reserve: 237.06MiB (used: 0.00B) Multiple profiles: no Data,single: Size:115.00GiB, Used:109.26GiB (95.01%) /dev/mapper/luks-main 115.00GiB Metadata,DUP: Size:2.00GiB, Used:1.04GiB (51.81%) /dev/mapper/luks-main 4.00GiB System,DUP: Size:32.00MiB, Used:16.00KiB (0.05%) /dev/mapper/luks-main 64.00MiB Unallocated: /dev/mapper/luks-main 812.45GiB