See attached test case "fallocate.c" and related program "dump_holes.c"
Build fallocate.c with:
$ cc -o fallocate fallocate.c -lposix4
posix_fallocate() is passed an "offset" and a "length" parameter; the specification makes no reference to any effects on the file outside that range of the file.
The test case creates a sparse file of length 128MB by seeking to the 128M-1th byte and writing one byte; it then calls posix_fallocate(fd, 0, 128MB) to allocate blocks backing the file.
When pointed at a UFS file, this action has the side effect of extending the file by another 128MB; there is an extended hole at the end of the file.
$ rm -f /space/sommerfeld/boom
$ ./fallocate /space/sommerfeld/boom
$ ls -ls /space/sommerfeld/boom
262288 -rw-rw-r-- 1 sommerfeld staff 268427264 May 31 15:23 /space/sommerfeld/boom
$ ./dump_holes /space/sommerfeld/boom
EOF at 268427264
Last hole starts at 134217728