FreeBSD 13.1 manual page mmap() has the following warning:
WARNING! Extending a file with ftruncate(2), thus creating a big hole, and then filling the hole by modifying a shared mmap() can lead to severe file fragmentation. In order to avoid such fragmentation you should always pre-allocate the file's backing store by write()ing zero's into the newly extended area prior to modifying the area via your mmap(). The fragmentation problem is especially sensitive to MAP_NOSYNC pages, because pages may be flushed to disk in a totally random order.
Questions:
ftruncate()
has the effect of creating it; and why write()
is a proposed solution to the problem?ftruncate()
and before mmap()
? Repeatedly calling write()
sounds like more system calls that maybe necessary.You can avoid this problem by using posix_fallocate
to preallocate desired areas.
The hole is created because files can be sparse, taking up only the space required for the actually used areas, so when using just ftruncate
, the backing for the new area is virtual, it isn't reserved on disk until you allocate it or write to it.
It applies to Linux as well, it's just not mentioned. You can expect most filesystem implementations to do similarly; often they do try to be smart, and will defragment your writes if time-wise close one to another, but can't do magic.