Warum gibt es keine Syscalls zum Einfügen von Dateien?

11

Nach meinem Verständnis gibt es für die Bearbeitung von Dateien unter Linux nur den sys_write-Syscall, der den Dateiinhalt überschreibt (oder ihn erweitert, wenn am Ende).

Warum gibt es unter Linux keine Systemaufrufe zum Einfügen oder Löschen von Inhalten in Dateien?

Da bei allen aktuellen Dateisystemen die Datei nicht in einem fortlaufenden Speicherblock gespeichert werden muss, sollte eine effiziente Implementierung möglich sein. (Die Dateien würden fragmentiert.)

Mit Dateisystemfunktionen wie "Beim Schreiben kopieren" oder "Transparente Dateikomprimierung" scheint die derzeitige Art des Einfügens von Inhalten sehr ineffizient zu sein.

dercolamann
quelle
4
Wie bei allen ausgefallenen Dateioperationen ist eine solche Operation in der Praxis viel weniger nützlich als es scheint. Die Hauptanwendung für so etwas sind sehr spezielle Anwendungen wie Datenbanken, Emulatoren und dergleichen. Normalerweise "bearbeiten" Sie eine Datei, indem Sie eine neue Datei erstellen und den Benutzer beim Speichern der neuen Datei in die alte umbenennen.
Mosvy
3
@mosvy, aber wird das Konzept "Neue Datei erstellen, dann umbenennen" verwendet, weil es an sich gut ist oder weil das System keinen besseren Weg bietet? Insbesondere bei Textdateien sind Operationen wie "Diese Zeile ändern (Länge ändern)" oder "Diese Zeilen hier einfügen" eher üblich, sodass man davon ausgehen könnte, dass Dateisystemoperationen für genau diese Funktionen verwendet würden, wenn sie vorhanden wären.
Wenn
1
@meuh OpenVMS funktioniert weiterhin über RMS (Record Management Services).
RonJohn
1
UNIX begann eine Bewegung weg von der Bereitstellung von Records - Management - Systeme innerhalb des Dateisystems.
user207421
1
@ilkkachu es ist an sich gut, kein Zweifel ;-) Noch mehr, wenn Inodes unveränderlich wären, würde dies die Implementierung von Block-Sharing, Versionierung und fast allem viel effizienter machen (und viel einfacher zu überlegen sein). Denken Sie analog darüber nach, wie alle Skriptsprachen auf unveränderliche Zeichenfolgen umgestellt haben - aber ich werde es hier kurz machen. Es ist schwer, über Dateisysteme zu reden und nicht wie ein Quacksalber zu klingen
;-)

Antworten:

22

Auf neueren Linux-Systemen ist dies tatsächlich möglich, jedoch mit Block (meistens 4096), nicht mit Byte- Granularität und nur auf einigen Dateisystemen (ext4 und xfs).

Zitat aus der fallocate(2)Manpage:

int fallocate(int fd, int mode, off_t offset, off_t len);

[...]

Reduzieren des Dateibereichs

Durch Angabe des FALLOC_FL_COLLAPSE_RANGEFlags (verfügbar seit Linux 3.15) in modewird ein Bytebereich aus einer Datei entfernt, ohne ein Loch zu hinterlassen. Der zu reduzierende Bytebereich beginnt bei offsetund setzt sich für len Bytes fort. Nach Abschluss des Vorgangs wird der Inhalt der Datei, die am Speicherort beginnt, an den Speicherort offset+lenangehängt offset, und die Datei wird um lenBytes kleiner.

[...]

Dateibereich vergrößern

Durch Angabe des FALLOC_FL_INSERT_RANGEFlags (verfügbar seit Linux 4.1) in modewird der Dateibereich vergrößert, indem ein Loch in die Dateigröße eingefügt wird, ohne dass vorhandene Daten überschrieben werden. Das Loch beginnt bei offsetund setzt sich für lenBytes fort. Beim Einfügen des Lochs in die Datei wird der Inhalt der Datei ab beginnend offsetum lenBytes nach oben (dh zu einem höheren Dateiversatz) verschoben . Durch das Einfügen eines Lochs in eine Datei wird die Dateigröße um lenBytes erhöht .

Mosvy
quelle
1
"aber mit Block (4096), nicht Byte-Granularität" - 4KiB-Blöcke sind in ext4 sehr verbreitet, aber das ist nicht garantiert. Ext4 unterstützt Blockgrößen von 1 KB, 2 KB und 4 KB . und ich erinnere mich an die ext2-Tage, dass auf Alpha-Prozessoren auch 8KiB unterstützt wurden. Sie können leider nicht einfach davon ausgehen, dass die Blöcke 4 KB groß sind.
Marcelm
1
4k (dies ist die Standardeinstellung) ist ein Vielfaches von 1k und 2k, sodass es kein Problem gibt, 4k mit ext4 anzunehmen. Während xfs standardmäßig auch 4k verwendet, soll es ein bs unterstützen, das größer als 4k ist - bis zu 64k, aber ich konnte nur ein solches fs erstellen - das Mounten schlägt ohne ENOSYS fehl. Und wie auch immer, Sie können nichts annehmen - diese Funktion wird nicht auf allen fs unterstützt, daher ist es besser, einfach block = 4096 zu sagen, damit der Leser ein gewisses Maß an Proportionen hat, anstatt es schweben zu lassen und die Leute alles sein zu lassen. oder schlimmer noch, dass es 512 Bytes sind oder irgendwie mit der VM-Seitengröße zusammenhängen.
Mosvy
Nachdem Sie bearbeitet haben (wo Sie sagen, dass es normalerweise 4 KB sind), stimme ich voll und ganz zu! Mein Problem war, dass es zuvor leicht zu lesen war, da "Blöcke immer 4 KB groß sind" , was dazu führen kann, dass Leute diese Annahme machen und fehlerhaften Code schreiben.
Marcelm
9

Da bei allen aktuellen Dateisystemen die Datei nicht in einem fortlaufenden Speicherblock gespeichert werden muss,

Bei Dateisystemen müssen Dateien möglicherweise nicht in einem kontinuierlichen Bereich gespeichert werden (und das wäre in der Tat sehr unflexibel), aber normalerweise werden Dateien in Blöcken fester Größe (oder Sequenzen zusammenhängender Blöcke) gespeichert. Auf diese Weise wird die Implementierung vereinfacht, und die Blöcke sind normalerweise ein Vielfaches der Blockgröße des zugrunde liegenden Geräts.

Das Implementieren von Einfügungen von Blöcken mit beliebiger Länge würde das Format und die Implementierung des Dateisystems ziemlich komplexer machen oder das Verschieben potenziell großer Datenmengen erfordern. Beides ist nicht wirklich gut, und komplexe Datenstrukturen können im Benutzerbereich über der Dateisystem-API erstellt werden.

ilkkachu
quelle