Un file è (approssimativamente) tre cose separate:
- Un "inode", una struttura di metadati che tiene traccia di chi possiede il file, le autorizzazioni e un elenco di blocchi sul disco che contengono effettivamente i dati.
- Una o più voci di directory (i nomi dei file) che puntano a quell'inode
- Gli effettivi blocchi di dati stessi
Quando crei un file vuoto, crei solo l'inode e una voce di directory che punta a quell'inode. Lo stesso per i file sparsi (dd if=/dev/null of=sparse_file bs=10M seek=1
).
Quando crei collegamenti fisici a un file esistente, crei solo voci di directory aggiuntive che puntano allo stesso inode.
Ho semplificato le cose qui, ma hai capito.
touch
creerà un inode e ls -i
o stat
mostrerà informazioni sull'inode:
$ touch test
$ ls -i test
28971114 test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fc01h/64513d Inode: 28971114 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/1000) Gid: ( 1000/1000)
Access: 2017-03-28 17:38:07.221131925 +0200
Modify: 2017-03-28 17:38:07.221131925 +0200
Change: 2017-03-28 17:38:07.221131925 +0200
Birth: -
Nota che test
utilizza 0 blocchi. Per memorizzare i dati visualizzati, l'inode utilizza alcuni byte. Questi byte sono memorizzati nella tabella degli inode. Guarda la pagina ext2 per un esempio di struttura inode.
ls
(o meglio, il stat(2)
chiamata di sistema) ti dice la dimensione dei contenuti del fascicolo. Quanto spazio ha bisogno il filesystem per la contabilità non fa parte di questo, e come dettaglio di implementazione, non è qualcosa che i programmi in generale dovrebbero cura o addirittura conoscere. Rendere visibili i dettagli dell'implementazione renderebbe meno utile l'astrazione del filesystem.