====== std.xattr — Erweiterte Dateiattribute & Dateisystem-Statistik ======
''import std.xattr;''
Drei Themenblöcke:
* **xattr**: Erweiterte Dateiattribute — beliebige Name-Wert-Paare an Dateien/Verzeichnissen speichern
* **statfs**: Dateisystem-Statistiken (Gesamtgröße, freier Speicher, Blockgröße)
* **fallocate**: Speicherplatz-Vorabzuweisung und Hole-Punching
Syscalls: ''setxattr(188)'', ''getxattr(191)'', ''listxattr(194)'', ''removexattr(197)'', ''fsetxattr(190)'', ''fgetxattr(193)'', ''flistxattr(196)'', ''fremovexattr(199)'', ''fallocate(285)'', ''statfs(137)''.
→ [[lyx_-_programmiersprache:units:fs|std.fs]] · [[lyx_-_programmiersprache:units:sysadmin|std.sysadmin]]
----
===== xattr-Konstanten =====
^ Konstante ^ Wert ^ Bedeutung ^
| ''XATTR_CREATE'' | 1 | Fehler wenn Attribut schon existiert |
| ''XATTR_REPLACE'' | 2 | Fehler wenn Attribut nicht existiert |
Namespace-Konvention für Attributnamen:
^ Namespace ^ Zugriffsrecht ^ Beispiel ^
| ''user.'' | Normale Anwendungen | ''user.comment'' |
| ''security.'' | Kernel-intern (SELinux) | ''security.selinux'' |
| ''trusted.'' | Nur root | ''trusted.md5sum'' |
| ''system.'' | ACLs | ''system.posix_acl_access'' |
----
===== xattr-Funktionen =====
==== Pfad-basiert ====
^ Funktion ^ Signatur ^ Beschreibung ^
| ''XattrSet'' | ''(path: pchar, name: pchar, val: int64, size: int64, flags: int64): int64'' | Setzt Attribut; ''flags=0'' = anlegen oder ersetzen |
| ''XattrGet'' | ''(path: pchar, name: pchar, buf: int64, size: int64): int64'' | Liest Attribut; ''buf=0, size=0'' liefert benötigte Größe |
| ''XattrList'' | ''(path: pchar, buf: int64, size: int64): int64'' | Listet alle Attributnamen (null-separiert) |
| ''XattrRemove'' | ''(path: pchar, name: pchar): int64'' | Löscht Attribut |
==== fd-basiert ====
^ Funktion ^ Signatur ^ Beschreibung ^
| ''FXattrSet'' | ''(fd: int64, name: pchar, val: int64, size: int64, flags: int64): int64'' | Wie XattrSet, via Dateideskriptor |
| ''FXattrGet'' | ''(fd: int64, name: pchar, buf: int64, size: int64): int64'' | Wie XattrGet, via Dateideskriptor |
| ''FXattrList'' | ''(fd: int64, buf: int64, size: int64): int64'' | Wie XattrList, via Dateideskriptor |
| ''FXattrRemove'' | ''(fd: int64, name: pchar): int64'' | Wie XattrRemove, via Dateideskriptor |
----
===== statfs-Konstanten =====
''STATFS_SIZE'': 120 Bytes (struct statfs auf x86-64).
^ Konstante ^ Offset ^ Beschreibung ^
| ''STATFS_BSIZE'' | 8 | Optimale Blockgröße in Bytes |
| ''STATFS_BLOCKS'' | 16 | Gesamtanzahl Datenblöcke |
| ''STATFS_BFREE'' | 24 | Freie Blöcke (nur root sichtbar) |
| ''STATFS_BAVAIL'' | 32 | Freie Blöcke für nicht-root |
| ''STATFS_FILES'' | 40 | Gesamtanzahl Inodes |
| ''STATFS_FFREE'' | 48 | Freie Inodes |
| ''STATFS_NAMELEN'' | 64 | Maximale Dateinamenslänge |
===== statfs-Funktionen =====
^ Funktion ^ Signatur ^ Beschreibung ^
| ''StatFs'' | ''(path: pchar, buf: int64): int64'' | Füllt statfs-Puffer (''STATFS_SIZE'' Bytes) |
| ''StatFsBlockSize'' | ''(buf: int64): int64'' | Blockgröße in Bytes |
| ''StatFsTotalBlocks'' | ''(buf: int64): int64'' | Gesamtanzahl Datenblöcke |
| ''StatFsFreeBlocks'' | ''(buf: int64): int64'' | Verfügbare freie Blöcke (für nicht-root) |
| ''StatFsTotalBytes'' | ''(buf: int64): int64'' | Gesamtkapazität in Bytes |
| ''StatFsFreeBytes'' | ''(buf: int64): int64'' | Verfügbarer Speicher in Bytes |
----
===== fallocate-Konstanten =====
^ Konstante ^ Wert ^ Bedeutung ^
| ''FALLOC_FL_KEEP_SIZE'' | 1 | Dateigröße nicht ändern |
| ''FALLOC_FL_PUNCH_HOLE'' | 2 | Hole stanzen (benötigt KEEP_SIZE) |
| ''FALLOC_FL_COLLAPSE_RANGE'' | 8 | Bereich entfernen und zusammenführen |
| ''FALLOC_FL_INSERT_RANGE'' | 32 | Bereich einfügen (Lücke öffnen) |
===== fallocate-Funktionen =====
^ Funktion ^ Signatur ^ Beschreibung ^
| ''FileAllocate'' | ''(fd: int64, offset: int64, size: int64): int64'' | Reserviert Speicherplatz ohne zu schreiben (keine Nullen) |
| ''FileAllocateMode'' | ''(fd: int64, mode: int64, offset: int64, size: int64): int64'' | Wie FileAllocate mit explizitem Modus-Flag |
----
===== Verwendung =====
==== Attribut setzen und lesen ====
import std.xattr;
import std.alloc;
fn main(): int64 {
var val: pchar := "Wichtige Datei";
var r: int64 := XattrSet("/tmp/test.txt", "user.comment",
val as int64, 14, 0);
if (r < 0) { return r; }
// Größe abfragen
var sz: int64 := XattrGet("/tmp/test.txt", "user.comment", 0, 0);
if (sz < 0) { return sz; }
// Wert lesen
var buf: int64 := alloc(sz + 1);
XattrGet("/tmp/test.txt", "user.comment", buf, sz);
poke8(buf + sz, 0); // NUL-terminieren
free(buf, sz + 1);
return 0;
}
==== Alle Attribute auflisten ====
import std.xattr;
import std.alloc;
fn ListAttrs(path: pchar): void {
// Benötigte Größe abfragen
var sz: int64 := XattrList(path, 0, 0);
if (sz <= 0) { return; }
var buf: int64 := alloc(sz);
XattrList(path, buf, sz);
// Null-separierte Namen ausgeben
var pos: int64 := 0;
while (pos < sz) {
var name: pchar := (buf + pos) as pchar;
// name ist ein \0-terminierter String
pos := pos + StrLen(name) + 1;
}
free(buf, sz);
}
==== Freien Speicher prüfen ====
import std.xattr;
import std.alloc;
fn GetFreeBytes(path: pchar): int64 {
var buf: int64 := alloc(STATFS_SIZE);
var r: int64 := StatFs(path, buf);
if (r < 0) { free(buf, STATFS_SIZE); return r; }
var freeBytes: int64 := StatFsFreeBytes(buf);
free(buf, STATFS_SIZE);
return freeBytes;
}
==== Speicherplatz vorab reservieren ====
import std.xattr;
import std.fs;
fn PreallocFile(path: pchar, size: int64): int64 {
var fd: int64 := OpenFile(path, 1); // O_WRONLY
if (fd < 0) { return fd; }
// Speicher reservieren — Kernel muss keine Blöcke on-demand allokieren
var r: int64 := FileAllocate(fd, 0, size);
CloseFile(fd);
return r;
}
==== Hole in Datei stanzen ====
import std.xattr;
fn PunchHole(fd: int64, offset: int64, len: int64): int64 {
// Gibt Blöcke im Bereich frei, Dateigröße bleibt gleich
return FileAllocateMode(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
offset, len);
}
----
===== Hinweise =====
* **xattr-Namespace**: Der ''user.''-Namespace ist für normale Anwendungen auf normalen Dateisystemen (ext4, xfs, btrfs) zugänglich. tmpfs und FAT unterstützen xattr nicht.
* **Größe abfragen**: ''XattrGet'' mit ''buf=0, size=0'' gibt die benötigte Puffergröße zurück — immer zuerst aufrufen bevor Speicher alloziert wird.
* **StatFsFreeBytes vs. StatFsFreeBlocks**: ''StatFsFreeBytes'' verwendet ''BAVAIL'' (für nicht-root verfügbar), nicht ''BFREE'' (root-reservierter Anteil zusätzlich). Das ist der relevante Wert für Anwendungen.
* **FileAllocate vs. Schreiben**: ''FileAllocate'' reserviert Blöcke, schreibt aber keine Daten — schneller als Nullen zu schreiben. Die reservierten Blöcke enthalten zufällige Daten bis überschrieben.
* **Hole-Punching**: Nicht alle Dateisysteme unterstützen ''FALLOC_FL_PUNCH_HOLE'' — ext4/xfs/btrfs ja, FAT/tmpfs nein. Bei Fehler ''-EOPNOTSUPP''.
----
Letzte Aktualisierung: 2026-06-06