Pourquoi n'y a-t-il pas de syscalls d'insertion de fichiers

11

À ma connaissance, pour manipuler des fichiers, il n'y a que le sys_write syscall sous Linux, qui écrase le contenu du fichier (ou l'étend, si à la fin).

Pourquoi n'y a-t-il pas d'appels système pour insérer ou supprimer du contenu dans des fichiers sous Linux?

Comme tous les systèmes de fichiers actuels n'exigent pas que le fichier soit stocké dans un bloc de mémoire continue, une implémentation efficace devrait être possible. (Les fichiers seraient fragmentés.)

Avec les fonctionnalités du système de fichiers telles que la «copie en écriture» ou la «compression de fichiers transparente», la manière actuelle d'insérer du contenu semble être très inefficace.

dercolamann
la source
4
Comme pour toutes les opérations de fichiers fantaisie, une telle opération est beaucoup moins utile dans la pratique qu'il n'y paraît. L'utilisation principale d'une telle chose sont des applications très spécialisées, comme les bases de données, les émulateurs et autres. La façon dont vous "éditez" généralement un fichier consiste à créer un nouveau fichier et à effectuer une opération de "sauvegarde" par l'utilisateur renommer le nouveau fichier en l'ancien.
mosvy
3
@mosvy, mais le concept "créer un nouveau fichier, puis renommer" est-il utilisé parce qu'il est bon en soi, ou exactement parce que le système ne propose pas de meilleure solution? Surtout sur les fichiers texte, les opérations comme «modifier cette ligne (changer la longueur)» ou «insérer ces lignes ici» sont assez courantes, donc on pourrait supposer que les opérations du système de fichiers pour ces fonctions exactes seraient utilisées si elles étaient là. Bien sûr, ne pas les avoir rend l'implémentation de
FS
1
@meuh OpenVMS le fait toujours, via RMS (Record Management Services).
RonJohn
1
UNIX a commencé à s'éloigner de la fourniture de systèmes de gestion des enregistrements à l'intérieur du système de fichiers.
user207421
1
@ilkkachu c'est bon en soi, absolument aucun doute ;-) Encore plus, si les inodes étaient immuables, cela rendra la mise en œuvre du partage de blocs, du versioning et presque tout beaucoup plus efficace (et beaucoup plus simple à raisonner). Pensez par analogie à la façon dont tous les langages de script sont passés à des chaînes immuables - mais je vais le raccourcir ici; il est difficile de parler de systèmes de fichiers et de ne pas ressembler à un charlatan ;-)
mosvy

Réponses:

22

Sur les systèmes Linux récents, c'est possible, mais avec le bloc (4096 la plupart du temps), pas la granularité en octets , et seulement sur certains systèmes de fichiers (ext4 et xfs).

Citant la fallocate(2)page de manuel:

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

[...]

Réduction de l'espace fichier

La spécification de l' FALLOC_FL_COLLAPSE_RANGEindicateur (disponible depuis Linux 3.15) dans modesupprime une plage d'octets d'un fichier, sans laisser de trou. La plage d'octets à réduire commence à offsetet continue pour les len octets. À la fin de l'opération, le contenu du fichier commençant à l'emplacement offset+lensera ajouté à l'emplacement offsetet le fichier sera plus lenpetit en octets.

[...]

Augmentation de l'espace fichier

La spécification de l' FALLOC_FL_INSERT_RANGEindicateur (disponible depuis Linux 4.1) dans modeaugmente l'espace fichier en insérant un trou dans la taille du fichier sans écraser les données existantes. Le trou commencera à offsetet continuera pendant des lenoctets. Lors de l'insertion du trou à l'intérieur du fichier, le contenu du fichier commençant par offsetsera déplacé vers le haut (c'est-à-dire vers un décalage de fichier supérieur) par lenoctets. L'insertion d'un trou dans un fichier augmente la taille du fichier en lenoctets.

mosvy
la source
1
"mais avec le bloc (4096), pas la granularité d'octet" - les blocs 4KiB sont très courants dans ext4, mais ce n'est pas garanti. Ext4 prend en charge les tailles de bloc de 1 Ko, 2 Ko et 4 Ko ; et je me souviens des jours ext2 que sur les processeurs Alpha, 8 Ko était également pris en charge. Vous ne pouvez pas simplement supposer que les blocs sont 4KoB, je le crains.
marcelm
1
4k (qui est la valeur par défaut) est un multiple de 1k et 2k, donc il n'y a aucun problème à supposer 4k avec ext4. Bien que xfs soit également réglé par défaut sur 4k, il est censé prendre en charge un bs supérieur à 4k - jusqu'à 64k, mais je n'ai pu créer qu'un tel fs - le montage échoue sans ENOSYS. Et de toute façon, vous ne pouvez rien supposer - cette fonctionnalité n'est pas prise en charge sur tous les fs, il est donc préférable de simplement dire block = 4096, afin que le lecteur ait un certain sens des proportions, plutôt que de le laisser flotter et de laisser les gens ce pourrait être n'importe quoi, ou pire, qu'il s'agit de 512 octets ou est en quelque sorte lié à la taille de la page vm.
mosvy
Après avoir édité (où vous dites qu'il s'agit généralement de 4 Ko), je suis entièrement d'accord! Mon problème était qu'auparavant, il était facile à lire comme «les blocs sont toujours 4KiB» , ce qui peut amener les gens à faire cette supposition et à écrire du code de bogue.
marcelm
9

Comme tous les systèmes de fichiers actuels n'exigent pas que le fichier soit stocké dans un bloc de mémoire continue,

Les systèmes de fichiers peuvent ne pas exiger que les fichiers soient stockés dans une zone continue (et cela serait en effet très rigide), mais généralement les fichiers sont stockés dans des blocs de taille fixe (ou des séquences de blocs contigus). Le faire de cette façon simplifie l'implémentation, et les blocs sont généralement des multiples de la taille de bloc du périphérique sous-jacent.

Ainsi, l'implémentation d'insertions de blocs de longueur arbitraire rendrait le format et l'implémentation du système de fichiers plus complexes ou nécessiterait le déplacement de grandes quantités de données. Ni l'un ni l'autre n'est vraiment bon, et des structures de données complexes peuvent être construites dans l'espace utilisateur au-dessus de l'API du système de fichiers.

ilkkachu
la source