Informations détaillées sur les fichiers épars sous Linux

11

J'ai un fichier clairsemé, dans lequel seuls certains blocs sont alloués:

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

Je voudrais savoir quels blocs du fichier sont réellement alloués. Existe-t-il un appel système ou une interface noyau qui pourrait être utilisé pour obtenir une liste des allocations ou des trous de fichier?

La simple vérification d'une chaîne de zéros suffisamment longue (l'approche utilisée par GNU cp, rsync, etc.) ne fonctionne pas correctement:

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

Il a détecté d'autres séquences de zéros réellement allouées.

Juliano
la source

Réponses:

7

Il y a une question similaire sur SO . La réponse actuellement acceptée par @ephemient suggère d'utiliser un ioctlappelé fiemapqui est documenté dans linux/Documentation/filesystems/fiemap.txt. Citant ce fichier:

Le fiemap ioctl est une méthode efficace pour l'espace utilisateur pour obtenir des mappages d'étendue de fichier. Au lieu d'un mappage bloc par bloc (tel que bmap), fiemap renvoie une liste d'étendues.

Cela ressemble au type d'informations que vous recherchez. La prise en charge par les systèmes de fichiers est à nouveau facultative:

Les systèmes de fichiers souhaitant prendre en charge fiemap doivent implémenter un ->fiemap rappel sur leur inode_operationsstructure.

La prise en charge des arguments SEEK_DATAet de Solaris que vous avez mentionnés a été ajoutée dans Linux 3.1 selon la page de manuel , vous pouvez donc également l'utiliser. Le semble être plus ancien, donc il pourrait être plus portable sur différentes versions de Linux pour le moment, alors qu'il pourrait être plus portable sur plusieurs systèmes d'exploitation si Solaris en avait le même.SEEK_HOLElseekfiemap ioctllseek

MvG
la source
2
Vous pouvez obtenir ces informations FIEMAP en utilisant le --fibmapde l' hdparmutilitaire. Voir le manuel.
Totor
2

Il existe une collection de programmes python appelés sparseutils qui utilisent SEEK_HOLEet SEEK_DATAdéterminent quelles sections du fichier sont représentées comme des trous et lesquelles sont des données. L'utilisation est assez simple. mksparsepeut être utilisé pour générer un fichier clairsemé selon une disposition donnée.

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

Le sparsemapprogramme peut être utilisé pour imprimer la mise en page sur stdout:

 $ sparsemap example
 HOLE 4096
 DATA 4096
 HOLE 4096
Richard
la source
1

Cela dépend du système de fichiers. Je ne pense pas que ce soit un appel, ce qui peut expliquer pourquoi de nombreux outils ne gèrent pas bien la copie de fichiers épars. La chaîne d'outils GNU utilise la recherche de gros blocs de zéros car cela leur permet de supprimer les blocs alloués inutilisés. De nombreux outils de copie convertissent un fichier clairsemé en un fichier avec tous les blocs alloués.

Vous devrez probablement ouvrir l'inode et analyser le résultat. Le format d'inode dépend du système de fichiers. Certains systèmes de fichiers peuvent contenir une partie de vos données dans l'inode lui-même.

BillThor
la source
1
Il doit y avoir un moyen indépendant de FS pour obtenir ces informations. La lecture directement depuis l'inode n'est certainement pas une option. Je cherchais quelque chose comme SEEK_DATAet des SEEK_HOLEparamètres lseek(), comme il en existe dans Solaris: opensolarisforum.org/man/man2/lseek.html
Juliano
@Juliano Un regard sur l'option Linux lseek n'a pas ces options. Solaris prend en charge très peu de systèmes de fichiers, il serait donc relativement facile à prendre en charge. Linux prend en charge une grande variété de systèmes de fichiers, dont certains ne prennent pas en charge les fichiers clairsemés. La prise en charge de SEEK_DATA / SEEK_HOLE imposerait la prise en charge du code pour tous les systèmes de fichiers. Ces méthodes peuvent ne pas faire ce que vous attendez. Voir blogs.sun.com/bonwick/entry/seek_hole_and_seek_data pour plus de données du côté Soleil.
BillThor
1
Les systèmes de fichiers n'ont pas besoin de prendre en charge quoi que ce soit avec l'interface lseek (), le noyau répertorie les modules du système de fichiers qui prennent en charge SEEK_DATA / SEEK_HOLE via une propriété de module. C'est dans la page de manuel elle-même et le blog lié: "Pour les systèmes de fichiers qui ne fournissent pas d'informations sur les trous, le fichier sera représenté comme une région de données entière."
Juliano
@Juliano nécessite toujours des mods du noyau ainsi que des changements dans lseek. Selon l'entrée de blog, il s'agit d'une fonctionnalité assez nouvelle chez Sun. Pour que cela fonctionne, le code du système de fichiers doit également être modifié. Cela nécessiterait certainement des modifications de tous les systèmes de fichiers prenant en charge des fichiers épars pour fournir les crochets du noyau.
BillThor