Holes in a file don’t have any block associated with them at all. A file created with fallocate
can end up with no blocks associated with it, only a size. Reads from unallocated blocks always return all zeroes; writes to an unallocated block cause the file system to allocate a block (filling the hole, at least partially) before writing.
Files with holes can’t be used for swap because the kernel expects to be able to access the file’s blocks without help from the file system (once the list of blocks is determined). Any file which isn’t fully allocated (containing holes, or copy-on-write) can’t be used for swap because some writes will involve the file system.
You can see how many blocks are really used by a file with stat
:
$ truncate -s 16K holes
$ stat holes
File: holes
Size: 16384 Blocks: 0 IO Block: 4096 regular file
Device: fd13h/64787d Inode: 36708573 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ steve) Gid: ( 1000/ steve)
Access: 2019-05-12 20:04:22.498258356 +0200
Modify: 2019-05-12 20:04:22.498258356 +0200
Change: 2019-05-12 20:04:22.498258356 +0200
Birth: -
filefrag
will tell you what’s allocated:
$ /usr/sbin/filefrag holes
holes: 0 extents found
Forcing partial allocation of the file will reduce the hole:
$ fallocate -z -l 8K holes
$ stat holes
File: holes
Size: 16384 Blocks: 16 IO Block: 4096 regular file
Device: fd13h/64787d Inode: 36708573 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ steve) Gid: ( 1000/ steve)
Access: 2019-05-12 20:04:22.498258356 +0200
Modify: 2019-05-12 20:10:12.520380272 +0200
Change: 2019-05-12 20:10:12.520380272 +0200
Birth: -
$ /usr/sbin/filefrag -e holes
Filesystem type is: ef53
File size of holes is 16384 (4 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 1: 116741448.. 116741449: 2: last,unwritten
holes: 1 extent found
filefrag -e myfile
to see the extents in the file. Modern filesystems are based on extents, not blockmaps, so there will be one big extent (start + length) not a separate record for each filesystem block. (Or better on XFS usexfs_bmap -vpl myfile
for more detailed info which distinguishes unwritten but pre-allocated extents from sparse hole) – Peter Cordes May 12 '19 at 17:40