Linux ganha dm-crypt atomic writes e promete menos corrupção de dados em quedas de energia

Como o suporte a dm-crypt atomic writes reduz torn writes em volumes LUKS e aumenta a confiabilidade de bancos de dados no Linux.

Escrito por
Emanuel Negromonte
Emanuel Negromonte é Jornalista, Mestre em Tecnologia da Informação e atualmente cursa a segunda graduação em Engenharia de Software. Com 14 anos de experiência escrevendo sobre...

Segurança e confiabilidade finalmente se alinham no stack de armazenamento do Linux. Um novo commit no Linux Kernel atualiza o alvo dm-crypt para a versão 1.29.0 e adiciona o recurso DM_TARGET_ATOMIC_WRITES, habilitando Atomic Writes em volumes criptografados com LUKS e dm-crypt. Na prática, isso mira diretamente um problema antigo: a corrupção silenciosa de dados em quedas de energia.

Imagine que você precisa guardar uma estátua de ouro, que representa seus dados, dentro de um cofre, que é o disco criptografado. Antigamente, para criptografar e transportar essa estátua, o sistema podia serrá-la em pedaços para caber nas caixas de transporte. Se a energia acabasse no meio do caminho, você poderia ficar apenas com metade da estátua. Com Atomic Writes, o dm-crypt passa a se comportar como um transporte de cofre indivisível: ou o cofre chega inteiro ao destino, ou nada é escrito. Não há mais “meias estátuas”.

O fim das escritas rasgadas (torn writes)

No modelo tradicional, o dm-crypt recebe uma operação de escrita grande do sistema de arquivos ou do banco de dados e a mapeia em várias bios (operações de Block I/O) menores. Essa divisão é importante para paralelismo e desempenho, mas tem um efeito colateral perigoso: em caso de queda de energia ou reset inesperado, parte das bios pode chegar ao disco e parte não. O resultado é uma torn write, uma escrita rasgada em que metade do bloco contém dados novos e metade contém dados antigos.

Para um banco de dados como MySQL ou PostgreSQL, isso é um pesadelo. Um único page de 8 KiB ou 16 KiB parcialmente escrito pode corromper índices, tabelas ou até todo o cluster, mesmo que o hardware subjacente ofereça garantias de atomicidade em nível de setor ou página de gravação. E quando você coloca criptografia em repouso com LUKS no caminho, o risco aumentava: a camada de criptografia podia dividir uma operação que, originalmente, tinha sido pensada como atômica pela aplicação.

O novo suporte a dm-crypt atomic writes altera essa dinâmica para as bios marcadas com a flag REQ_ATOMIC. Se a aplicação ou a camada superior sinalizar que aquela escrita precisa ser atômica, o dm-crypt não está mais autorizado a fatiá-la.

Como o kernel implementou o suporte a dm-crypt atomic writes

O coração da mudança está na função crypt_map do driver dm-crypt. O patch introduz um bool no_split, que controla quando uma bio não pode ser dividida.

Esse no_split passa a ser verdadeiro em dois cenários principais:

  • quando o alvo está em modo emulate_zone_append e a operação é de escrita
  • quando o campo bi_opf da bio contém a flag REQ_ATOMIC

Esse indicador é então passado para get_max_request_sectors. Se no_split estiver ativo, o código deixa de aplicar o limite tradicional baseado em max_write_size e passa a tratar aquela bio como “não divisível”. Em outras palavras, para uma operação atômica, o dm-crypt precisa aceitar a bio inteira ou rejeitá-la.

O comportamento em caso de excesso também mudou:

  • se o tamanho da bio exceder o limite calculado e no_split não estiver ativo, o driver continua fazendo o que sempre fez, aceitando parcialmente a bio com dm_accept_partial_bio
  • se no_split estiver ativo e o tamanho for grande demais, o dm-crypt retorna DM_MAPIO_KILL, falhando a operação de forma limpa e previsível, em vez de arriscar uma escrita rasgada

Além disso, a função crypt_io_hints passa a ajustar os limites de atomicidade na fila de I/O do dispositivo mapeado, reduzindo atomic_write_hw_unit_max e atomic_write_hw_max para valores compatíveis com o limite interno BIO_MAX_VECS << PAGE_SHIFT. Isso garante que o alvo não prometa para cima do que realmente consegue entregar.

Por fim, o struct target_type crypt_target agora anuncia explicitamente o recurso DM_TARGET_ATOMIC_WRITES e sobe a versão para {1, 29, 0}. É a forma do Linux Kernel dizer para o resto do stack: “este volume criptografado preserva a atomicidade para bios marcadas como atômicas”.

Requisitos de ponta a ponta para a atomicidade funcionar

Um detalhe crucial para o público de storage e de banco de dados: atomicidade só é verdadeira se toda a cadeia respeitar a operação atômica, da aplicação até o hardware.

No caminho típico de I/O, temos:

aplicação ou banco de dados → sistema de arquivos → camada de bloco (device-mapper, incluindo dm-crypt) → driver de dispositivo → hardware (NVMe, SCSI etc.).

Para que dm-crypt atomic writes entregue o que promete, é preciso que:

  • a aplicação ou o banco de dados use a API de escrita atômica, por exemplo via pwritev2() com a flag RWF_ATOMIC em kernels recentes
  • o sistema de arquivos (como ext4 ou XFS) reconheça essa flag e converta a chamada em bios marcadas com REQ_ATOMIC
  • a camada de bloco preserve essa marcação, sem juntar ou dividir essas bios de forma a quebrar a atomicidade
  • o dm-crypt agora tenha a obrigação de não dividir essas bios, nem emular comportamento que fira a garantia de “tudo ou nada”
  • o driver de bloco do dispositivo (tipicamente NVMe ou SCSI moderno) anuncie corretamente seus limites de atomicidade (atomic_write_unit_min, atomic_write_unit_max, atomic_write_boundary) e implemente a semântica de Atomic Writes em hardware

Quando todos esses degraus estão alinhados, a promessa de atomicidade do dispositivo NVMe não termina no disco físico. Ela sobrevive ao sistema de arquivos e, agora, também à criptografia em repouso com LUKS e dm-crypt.

Benefícios para bancos de dados em discos criptografados

Para quem administra banco de dados de missão crítica, isso é mais que um detalhe: é uma mudança de modelo.

Engines como InnoDB (MySQL) e o storage engine de PostgreSQL carregam, há anos, mecanismos caros para se defender de torn writes, como:

  • double-write buffer
  • logs de redo pesados
  • padrões agressivos de fsync e flush de cache
  • técnicas de journaling e WAL focadas em recuperar páginas parcialmente escritas

Essas defesas protegem a integridade de dados, mas custam caro em IOPS e latência. Em hardware moderno, especialmente SSDs NVMe com suporte a Atomic Writes em granularidades de página, já era possível reduzir parte desse custo em dispositivos sem criptografia. O problema estava exatamente no meio do caminho, na pilha de software: a camada de criptografia e outros filtros de bloco tendiam a quebrar a operação em pedaços menores.

Com o suporte a dm-crypt atomic writes, essa lacuna começa a se fechar. Agora, uma escrita atômica emitida pelo banco de dados pode atravessar o sistema de arquivos, passar pela camada de bloco, pela criptografia em repouso via dm-crypt e chegar ao NVMe sem ser fatiada. Em vez de depender apenas de truques de software, o banco de dados pode se apoiar mais nas garantias do hardware, mesmo em volumes criptografados.

Na prática, isso abre espaço para configurações de alto desempenho em que:

  • double-write buffer pode ser simplificado ou ajustado
  • políticas de flush podem ser otimizadas para workloads que confiam em Atomic Writes
  • pilhas de LUKS e dm-crypt deixam de ser um ponto cego de confiabilidade

Sempre com um lembrete importante: qualquer redução de mecanismos de proteção exige testes extensivos, validação em ambiente de staging e, principalmente, uma estratégia robusta de backup e recuperação.

Limitações práticas e o que ainda depende de você

Nem toda escrita se torna mágica só porque o dm-crypt entende Atomic Writes. A atomicidade continua obedecendo a limites muito concretos:

  • ela vale apenas para tamanhos e alinhamentos específicos, definidos pelos campos atomic_write_unit_min, atomic_write_unit_max e atomic_write_boundary do dispositivo de bloco
  • sistemas de arquivos como ext4 só oferecem atomicidade em cenários bem definidos, por exemplo com Direct I/O, arquivos regulares com extents e dispositivos subjacentes que anunciam Atomic Writes em hardware
  • camadas adicionais como RAID, caches de blocos, virtualização, storage distribuído ou appliances de deduplicação podem quebrar ou emular esse comportamento, dependendo de como foram implementadas

Em termos de arquitetura, o patch reduz de forma importante o risco de torn writes em volumes criptografados, mas não substitui:

  • WAL e journaling de bancos de dados e sistemas de arquivos
  • replicação síncrona ou assíncrona
  • snapshots consistentes para recuperação de desastres
  • nem muito menos backups bem testados

A mensagem para o administrador é clara: uma fonte clássica de corrupção em ambientes com criptografia de disco fica sob controle, mas o modelo de resiliência como um todo continua sendo responsabilidade do arquiteto e do DBA.

Como verificar suporte a Atomic Writes no seu ambiente Linux

Do ponto de vista operacional, é natural perguntar: “o meu stack está pronto para isso?”.

Em kernels recentes, dispositivos que suportam Atomic Writes expõem limites em /sys/block. Um primeiro passo é inspecionar o dispositivo físico, por exemplo um NVMe, e depois o dispositivo mapeado pelo dm-crypt:

# Checar suporte no NVMe físico
ls /sys/block/nvme0n1/queue/atomic_write*
cat /sys/block/nvme0n1/queue/atomic_write_hw_max
cat /sys/block/nvme0n1/queue/atomic_write_unit_min
cat /sys/block/nvme0n1/queue/atomic_write_boundary

# Checar o dispositivo dm-crypt (por exemplo, dm-0)
ls /sys/block/dm-0/queue/atomic_write*
cat /sys/block/dm-0/queue/atomic_write_hw_max

Valores diferentes de zero para esses parâmetros indicam que o dispositivo e o alvo mapeado conhecem limites de Atomic Writes. O passo seguinte é verificar se:

  • o sistema de arquivos foi criado e montado respeitando esses limites de tamanho e alinhamento
  • o banco de dados está, de fato, emitindo I/O atômico (por exemplo, via RWF_ATOMIC ou APIs específicas do motor)
  • camadas intermediárias, como RAID ou virtualização, não estão “apagando” essas garantias

Ferramentas como statx() podem expor atributos relativos a atomicidade de escrita em arquivos, permitindo que aplicações verifiquem programaticamente se o ambiente suporta as promessas que elas desejam usar.

Onde este patch se encaixa no roadmap de Atomic Writes do Linux

Este patch em dm-crypt não nasce isolado. Ele se apoia em toda a infraestrutura de block atomic writes que o Linux Kernel vem construindo desde a série 6.11, incluindo:

  • suporte no bloco para a flag REQ_ATOMIC e para a API de usuário RWF_ATOMIC
  • implementação de Atomic Writes em drivers de NVMe e SCSI modernos
  • suporte em sistemas de arquivos, como ext4 e XFS, para tirar proveito dessas capacidades em cenários de Direct I/O

A novidade é que, com a versão 1.29.0 do alvo crypt, os ambientes que já investiram em hardware com Atomic Writes passam a colher o mesmo benefício mesmo quando usam LUKS e dm-crypt para criptografia em repouso. Em outras palavras, o dm-crypt deixa de ser o elo fraco entre o banco de dados e o SSD de última geração e passa a fazer parte do caminho end-to-end de atomicidade.

Compartilhe este artigo