No Linux, o openat
syscall pode ser usado para criar arquivos e testar sua existência. Falando em termos do modelo de memória C/C++, criar um arquivo e verificar sua existência cria um relacionamento sincronizado com. O que preciso saber é se essas sincronizações são sequencialmente consistentes entre si. (Certamente espero que sim, mas na verdade não vi isso documentado em lugar nenhum.)
Por exemplo, dados os processos p1 e p2 e os caminhos A e B:
se p1 fizer isso: crie(A), então crie(B)
e p2 faz isso: tente abrir(B), depois tente abrir(A)
e nenhum outro processo interfere em A ou B, é possível que p2 abra B com sucesso, mas não consiga encontrar A?
Se fizer diferença, podemos assumir que todas as operações estão dentro de um sistema de arquivos.
Responder1
Com todas as otimizações subjacentes de disco e CPU multi-core, não é necessariamente possível determinar a ordem estrita de uma sequência de operações entre dois processos. É por isso que os semáforos são empregados se houver a possibilidade de comportamento dependente do tempo.
Responder2
Somente para arquivos no mesmo diretório.
acesso de leitura. Regras de bloqueio: o chamador bloqueia o diretório que estamos acessando. O bloqueio é compartilhado.
criação de objeto. Regras de bloqueio: iguais às anteriores, mas o bloqueio é exclusivo.
remoção de objetos. Regras de bloqueio: o chamador bloqueia o pai, encontra a vítima, bloqueia a vítima e chama o método. As fechaduras são exclusivas.
rename()
aquilo énãodiretório cruzado. Regras de bloqueio: o chamador bloqueia o pai e encontra a origem e o destino. Em caso de troca (comRENAME_EXCHANGE
argumento in flags) bloqueie ambos. De qualquer forma, se o alvo já existir, bloqueie-o. Se a fonte não for um diretório, bloqueie-a. Se precisarmos bloquear ambos, bloqueie-os na ordem do ponteiro do inode. Em seguida, chame o método. Todas as fechaduras são exclusivas. NB: podemos conseguir bloquear a origem (e o destino no caso de troca) compartilhada.criação de links. Regras de bloqueio:
bloquear pai
verifique se a fonte não é um diretório
fonte de bloqueio
chame o método. Todas as fechaduras são exclusivas.
renomeação entre diretórios. O mais complicado de todo o grupo. Regras de bloqueio:
bloquear o sistema de arquivos
bloquear os pais na ordem "ancestrais primeiro".
encontre origem e destino.
se o pai antigo for igual ou descendente do alvo, falhará com -
ENOTEMPTY
se o novo pai for igual ou descendente da fonte falhará com -
ELOOP
Se for uma troca, bloqueie a origem e o destino.
Se o alvo existir, bloqueie-o. Se a fonte não for um diretório, bloqueie-a. Se precisarmos bloquear ambos, faça-o na ordem do ponteiro do inode.
chame o método. Todos
->i_rwsem
são exclusivos. Novamente, podemos conseguir bloquear a origem (e o destino no caso de troca) compartilhada.As regras acima obviamente garantem que todos os diretórios que serão lidos, modificados ou removidos pelo método serão bloqueados pelo chamador.
O bloqueio reforça a linearização, então as operaçõesem um único diretórioestão totalmente ordenados. No entanto, o acesso de leitura (1), a criação de objetos (2) e a remoção de objetos (3) não exigem bloqueios mais amplos do que o bloqueio de diretório, portanto, não há garantias sobre a ordem das operações de diretório em diretórios diferentes; diferentes observadores podem ver as histórias lineares dos diretórios intercaladas de diferentes maneiras.