C'è una domanda simile su SO. La risposta attualmente accettata da @ephemient suggerisce di utilizzare un ioctl chiamato fiemap che è documentato in linux/Documentation/filesystems/fiemap.txt . Citando da quel file:
Il fiemap ioctl è un metodo efficiente per lo spazio utente per ottenere mappature fileextent. Invece della mappatura blocco per blocco (come bmap), fiemap restituisce un elenco di estensioni.
Sembra che questo sia il tipo di informazioni che stai cercando. Il supporto dei filesystem è di nuovo facoltativo:
I file system che desiderano supportare fiemap devono implementare un
->fiemaprichiamare sul loroinode_operationsstruttura.
Supporto per il SEEK_DATA e SEEK_HOLE argomenti a lseek che hai citato da Solaris è stato aggiunto in Linux 3.1 secondo la pagina man, quindi potresti usarlo anche tu. L'fiemap ioctl sembra essere più vecchio, quindi potrebbe essere più portabile tra diverse versioni di Linux per ora, mentre lseek potrebbe essere più portabile tra i sistemi operativi se Solaris ha lo stesso.
Esiste una raccolta di programmi Python chiamati sparseutils che usano SEEK_HOLE e SEEK_DATA per determinare quali sezioni del file sono rappresentate come buchi e quali sono dati. L'utilizzo è abbastanza semplice. mksparse può essere utilizzato per generare un file sparse secondo un dato layout.
$ echo hole,data,hole | mksparse --hole-size 4096 --data-size 4096 example
$ du -sh example
4.0K example
Il sparsemap programma può essere utilizzato per stampare il layout su stdout:
$ sparsemap example
HOLE 4096
DATA 4096
HOLE 4096