Il y a une question similaire sur SO. La réponse actuellement acceptée par @ephemient suggère d'utiliser un ioctl appelé fiemap qui 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 (comme bmap),fiemap renvoie une liste d'étendues.
On dirait que c'est le genre 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
->fiemaprappel sur leurinode_operationsstructure.
Prise en charge du SEEK_DATA et SEEK_HOLE arguments de lseek vous avez mentionné que Solaris a été ajouté dans Linux 3.1 selon la page de manuel, vous pouvez donc également l'utiliser. Le fiemap ioctl semble être plus ancien, il pourrait donc être plus portable sur différentes versions de Linux pour le moment, alors que lseek pourrait être plus portable sur tous les systèmes d'exploitation si Solaris a le même.
Il existe une collection de programmes python appelés sparseutils qui utilisent SEEK_HOLE et SEEK_DATA pour déterminer quelles sections du fichier sont représentées comme des trous et lesquelles sont des données. L'utilisation est assez simple. mksparse peut être utilisé pour générer un fichier fragmenté selon une mise en page donnée.
$ echo hole,data,hole | mksparse --hole-size 4096 --data-size 4096 example
$ du -sh example
4.0K example
Le sparsemap programme peut être utilisé pour imprimer la mise en page sur stdout :
$ sparsemap example
HOLE 4096
DATA 4096
HOLE 4096