====== 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