Informações detalhadas sobre arquivos esparsos no Linux

11

Eu tenho um arquivo esparso, no qual apenas alguns blocos são alocados:

~% du -h --apparent-size example
100K    example
~% du -h example
52K     example

Gostaria de saber quais blocos do arquivo estão realmente alocados. Existe uma interface de chamada ou kernel do sistema que possa ser usada para obter uma lista das alocações ou dos buracos do arquivo?

Simplesmente verificar uma série de zeros longa o suficiente (a abordagem usada pelo GNU cp, rsync, etc) não funciona corretamente:

~% cp example example1  
~% du -h example1 
32K     example1

Ele detectou outras seqüências de zeros que foram realmente alocadas.

Juliano
fonte

Respostas:

7

uma pergunta semelhante no SO . A resposta atualmente aceita por @ephemient sugere o uso de uma ioctlchamada fiemapdocumentada em linux/Documentation/filesystems/fiemap.txt. Citando esse arquivo:

O fiemap ioctl é um método eficiente para o espaço do usuário obter mapeamentos de extensão de arquivo. Em vez de mapear bloco por bloco (como bmap), o fiemap retorna uma lista de extensões.

Parece que esse é o tipo de informação que você está procurando. O suporte por sistemas de arquivos é novamente opcional:

Os sistemas de arquivos que desejam oferecer suporte ao fiemap devem implementar um ->fiemap retorno de chamada em sua inode_operationsestrutura.

O suporte aos argumentos SEEK_DATAe mencionadosSEEK_HOLE a lseekvocê mencionados no Solaris foi adicionado no Linux 3.1 de acordo com a página do manual , portanto, você pode usá-lo também. Os fiemap ioctlparece ser mais velho, por isso pode ser mais portátil em diferentes versões do Linux, por agora, enquanto lseekpode ser mais portáveis entre sistemas operacionais se Solaris tem a mesma.

MvG
fonte
2
Você pode obter esta informação FIEMAP usando a --fibmapda hdparmutilidade. Veja o manual.
Totor 03/03
2

Há uma coleção de programas python chamados sparseutils que usam SEEK_HOLEe SEEK_DATAdeterminam quais seções do arquivo são representadas como buracos e quais são dados. O uso é bastante direto. mksparsepode ser usado para gerar um arquivo esparso de acordo com um determinado layout.

 $ echo hole,data,hole | mksparse --hole-size 4096 --data-size 4096 example
 $ du -sh example
 4.0K   example

O sparsemapprograma pode ser usado para imprimir o layout no stdout:

 $ sparsemap example
 HOLE 4096
 DATA 4096
 HOLE 4096
Richard
fonte
1

Depende do sistema de arquivos. Não acredito que seja uma ligação, e talvez por isso muitas ferramentas não lidam bem com a cópia de arquivos esparsos. A cadeia de ferramentas GNU usa a busca de grandes blocos de zeros, pois isso permite remover blocos alocados não utilizados. Muitas ferramentas de cópia converterão um arquivo esparso em um arquivo com todos os blocos alocados.

Você provavelmente terá que abrir o inode e analisar o resultado. O formato do inode depende do sistema de arquivos. Alguns sistemas de arquivos podem ter parte dos seus dados no próprio inode.

BillThor
fonte
1
Tem que haver alguma maneira independente de FS para obter essas informações. Ler diretamente do inode definitivamente não é uma opção. Eu estava procurando algo como SEEK_DATAe SEEK_HOLEparâmetros para lseek(), como existem no Solaris: opensolarisforum.org/man/man2/lseek.html
Juliano
@ Juliano Uma olhada na opção lseek do Linux não possui essas opções. O Solaris suporta muito poucos sistemas de arquivos, por isso seria relativamente fácil de suportar. O Linux suporta uma ampla variedade de sistemas de arquivos, alguns dos quais não suportam arquivos esparsos. O suporte para SEEK_DATA / SEEK_HOLE imporia suporte no código para todos os sistemas de arquivos. Esses métodos podem não fazer o que você espera. Consulte blogs.sun.com/bonwick/entry/seek_hole_and_seek_data para obter mais dados do lado do Sol.
BillThor
1
Os sistemas de arquivos não precisam suportar nada com a interface lseek (), o kernel lista os módulos do sistema de arquivos que suportam SEEK_DATA / SEEK_HOLE através de uma propriedade do módulo. Isso está na própria página de manual e no blog vinculado: "Para sistemas de arquivos que não fornecem informações sobre falhas, o arquivo será representado como uma região de dados inteira".
Juliano
@Juliano Ainda requer mods do kernel, bem como alterações no lseek. De acordo com a entrada do blog, essa é uma funcionalidade relativamente nova na Sun. Para que ele funcione, o código do sistema de arquivos também precisa ser modificado. Certamente exigiria alterações em todos os sistemas de arquivos que suportam arquivos esparsos para fornecer os ganchos do kernel.
BillThor