Por que não há syscalls de inserção de arquivo

11

Para meu entendimento, para manipular arquivos, existe apenas o sys_write syscall no Linux, que sobrescreve o conteúdo do arquivo (ou o estende, se no final).

Por que não há syscalls para inserir ou excluir conteúdo em arquivos no Linux?

Como todos os sistemas de arquivos atuais não exigem que o arquivo seja armazenado em um bloco de memória contínuo, uma implementação eficiente deve ser possível. (Os arquivos seriam fragmentados.)

Com os recursos do sistema de arquivos como "copiar na gravação" ou "compactação transparente de arquivos", a maneira atual de inserir conteúdo parece ser muito ineficiente.

dercolamann
fonte
4
Como em todas as operações sofisticadas de arquivo, essa operação é muito menos útil na prática do que parece. O principal uso para isso é aplicações muito especializadas, como bancos de dados, emuladores e outros. A maneira como você geralmente "edita" um arquivo é criando um novo arquivo e tendo uma operação "salvar" pelo usuário, renomeie o novo arquivo para o antigo.
mosvy
3
@mosvy, mas o conceito "criar novo arquivo e renomear" é usado porque é bom por si só ou exatamente porque o sistema não oferece uma maneira melhor? Especialmente em operações de arquivos de texto como "modificar esta linha (alterando o comprimento)" ou "inserir essas linhas aqui" são bastante comuns, portanto, pode-se supor que as operações do sistema de arquivos para essas funções exatas seriam usadas se elas estivessem lá. Claro, não tê-los torna a implementação fs muito mais simples ...
ilkkachu
1
@meuh O OpenVMS ainda funciona, via RMS (Record Management Services).
RonJohn
1
UNIX começou um movimento longe de fornecimento de sistemas de gestão de registos dentro do sistema de arquivos.
user207421
1
@ilkkachu é bom em si mesmo, absolutamente sem dúvida ;-) Ainda mais, se os inodes fossem imutáveis, isso tornaria a implementação do compartilhamento de blocos, versão e quase tudo muito mais eficiente (e muito mais simples de raciocinar). Pense por analogia como todas as linguagens de script mudaram para seqüências imutáveis ​​- mas vou abreviar aqui; é difícil falar de improviso sobre os sistemas de arquivos e não soar como um charlatão ;-)
mosvy

Respostas:

22

Em sistemas Linux recentes isso é realmente possível, mas com bloco (4096 na maioria das vezes), não granularidade de bytes e apenas em alguns sistemas de arquivos (ext4 e xfs).

Citando a partir da página de fallocate(2)manual:

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

[...]

Recolhendo espaço no arquivo

A especificação do FALLOC_FL_COLLAPSE_RANGEsinalizador (disponível desde o Linux 3.15) moderemove um intervalo de bytes de um arquivo, sem deixar um buraco. O intervalo de bytes a ser recolhido começa em offsete continua por len bytes. Na conclusão da operação, o conteúdo do arquivo que começa no local offset+lenserá anexado no local offsete o arquivo será lenbytes menores.

[...]

Aumentando o Espaço no Arquivo

A especificação do FALLOC_FL_INSERT_RANGEsinalizador (disponível desde o Linux 4.1) modeaumenta o espaço no arquivo, inserindo um furo no tamanho do arquivo sem substituir os dados existentes. O buraco começará em offsete continuará por lenbytes. Ao inserir o furo dentro do arquivo, o conteúdo do arquivo a partir de offsetserá deslocado para cima (ou seja, para um deslocamento maior do arquivo) por lenbytes. Inserir um furo dentro de um arquivo aumenta o tamanho do arquivo em lenbytes.

mosvy
fonte
1
"mas com bloco (4096), sem granularidade de bytes" - os blocos 4KiB são muito comuns no ext4, mas isso não é garantido. O Ext4 suporta tamanhos de bloco de 1KiB, 2KiB e 4KiB ; e lembro desde os dias ext2 que, nos processadores Alpha, o 8KiB também era suportado. Você não pode simplesmente assumir que os blocos são 4KiB, receio.
marcelm
1
4k (que é o padrão) é um múltiplo de 1k e 2k, portanto não há problema em assumir 4k com ext4. Embora o xfs tenha o padrão de 4k também, ele deve suportar um bs maior que 4k - até 64k, mas eu só consegui criar uma montagem fs como essa - falhando sem ENOSYS. De qualquer forma, você não pode assumir nada - esse recurso não é suportado em todos os fs; portanto, é melhor dizer apenas block = 4096, para que o leitor tenha algum senso de proporção, em vez de deixá-lo flutuar e deixar que as pessoas possam ser qualquer coisa, ou pior, são 512 bytes ou estão de alguma forma relacionados ao tamanho da página vm.
mosvy
Depois de editar (onde você costuma dizer que é 4KiB), eu concordo plenamente! Meu problema era que anteriormente era facilmente lido como "blocos sempre 4KiB" , o que pode levar as pessoas a fazer essa suposição e escrever código de buggy.
marcelm
9

Como todos os sistemas de arquivos atuais não exigem que o arquivo seja armazenado em um bloco de memória contínuo,

Os sistemas de arquivos podem não exigir que os arquivos sejam armazenados em uma área contínua (e isso seria bastante inflexível), mas geralmente os arquivos são armazenados em blocos de tamanho fixo (ou sequências de blocos contíguos). Fazer isso dessa maneira simplifica a implementação, e os blocos geralmente são múltiplos do tamanho do bloco do dispositivo subjacente.

Portanto, implementar inserções de blocos com comprimento arbitrário tornaria o formato e a implementação do sistema de arquivos mais complexo ou exigiria a movimentação de grandes quantidades de dados. Nenhuma dessas opções é realmente boa e estruturas de dados complexas podem ser construídas no espaço do usuário na parte superior da API do sistema de arquivos.

ilkkachu
fonte