Lembro-me vagamente de ler em algum lugar que, em alguns Unices, havia uma maneira de abrir um arquivo existente para gravação, com uma bandeira que pedia ao kernel que usasse a versão antiga (para outros processos acessando-o para leitura), até o "novo "versão foi totalmente gravada (fd fechado), a partir do qual o arquivo apareceu como a nova versão.
Em outras palavras, outros processos viram a versão antiga, ou a nova, nunca uma versão incompleta.
Alguém experiente pode me indicar uma referência?
kernel
open-files
eudoxos
fonte
fonte
Respostas:
O que você está descrevendo soa exatamente como uma renomeação básica para substituir um arquivo.
Quando você renomeia / move um arquivo por cima de outro, o arquivo antigo é desvinculado. Significa que o arquivo ainda existe, mas não está mais na árvore do sistema de arquivos. Assim, os aplicativos antigos continuarão sendo capazes de acessar o arquivo, desde que o mantenham aberto. Depois que todos os aplicativos fecham o arquivo antigo, ele não é alocado no disco.
A
rename
chamada do sistema é uma operação atômica. Para fazer isso, você criaria um novo arquivo com um nome diferente e chamariarename
para renomear o arquivo temporário como o que você deseja substituir. Como a operação é atômica, não há absolutamente nenhum período em que o arquivo está ausente. Ele passa instantaneamente do arquivo antigo para o novo arquivo.Observe que o arquivo temporário e o arquivo que está sendo substituído precisam residir no mesmo ponto de montagem.
fonte
rename
troca. Mesmo que existisse um 'recurso do SO' como você está falando, o programa ainda precisaria ser escrito para tirar proveito disso. Qual é a diferença?open
syscall ou se precisar fazer o que você descreve manualmente.Como Patrick escreve , a maneira usual de fazer isso é gravar a nova versão em um arquivo separado e, quando terminar, renomeie a nova versão para o nome do arquivo antigo, substituindo-o atomicamente. Essa segunda operação é chamada sobrescrever por renomear .
Agora, algumas referências:
ISO C requer
rename
ser atômico. Das especificações básicas do grupo aberto :As versões antigas do Mac OS X não tinham renomeação atômica; isso está consertado no Lion.
Aparentemente, o Btrfs viola intencionalmente o padrão, não garantindo renomeação atômica , por razões de desempenho. No entanto, a substituição por renomeação ainda é atômica , o que é tudo o que você precisa para esse fim.
fonte
man 3p rename
me diz querename
é realmente atômico, e acho que isso se destina a todos os sistemas de arquivos Linux. E quando li o primeiro artigo que você vinculou, ainda acho que as operações de renomeação do Btrfs são atômicas.Isso me lembra Allocate On Flush . Quando um sistema de arquivos usa esse recurso, em vez de gravar dados diretamente no disco, subtrai o tamanho dos dados a serem gravados do contador de espaço livre do disco e mantém os dados na memória até que uma chamada de sistema de sincronização seja executada ou o kernel decida para lavar os tampões sujos.
Nesse caso, se o arquivo estiver sendo modificado por um processo e for aberto por outro, o último processo "verá" a versão não modificada ( ou "antiga", se você preferir ) do arquivo.
Obviamente, os itens acima são teóricos e dependem de vários fatores, e eu diria um pouco imprevisível - já que você não sabe exatamente quando o kernel vai liberar as páginas sujas. Por exemplo, no Linux ( como você também pode ler na seção 15.3 de Entendendo o kernel do Linux ), as páginas sujas são gravadas no disco nas seguintes condições:
O cache da página fica muito cheio e são necessárias mais páginas ou o número de páginas sujas se torna muito grande.
Muito tempo se passou desde que uma página ficou suja.
Um processo solicita que todas as alterações pendentes de um dispositivo de bloco ou de um arquivo específico sejam liberadas; isso é feito chamando uma chamada de sistema sync (), fsync () ou fdatasync ().
Sabe-se que esse recurso é implementado nos sistemas de arquivos HFS +, XFS, Reiser4, ZFS, Btrfs e ext4.
fonte