the ZERO_RANGE fallocate mode currently punches out the requested range, then reallocates it as unwritten extents. This is fine, but the re-allocation fragments the file when we could be converting in place: $ rm -rf moo ; fallocate -l 16m moo ; xfs_io -c "bmap -vp" -c 'fzero 1m 64k' -c "bmap -vp" moo moo: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS 0: [0..32767]: 187007640..187040407 2 (52789912..52822679) 32768 10000 moo: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS 0: [0..2047]: 187007640..187009687 2 (52789912..52791959) 2048 10000 1: [2048..2175]: 187040408..187040535 2 (52822680..52822807) 128 10000 2: [2176..32767]: 187009816..187040407 2 (52792088..52822679) 30592 10000 $ rm -rf moo ; xfs_io -f -c "pwrite 0 16m" -c "bmap -vp" -c 'fzero 1m 64k' -c "bmap -vp" moo wrote 16777216/16777216 bytes at offset 0 16 MiB, 4096 ops; 0.0000 sec (124.504 MiB/sec and 31873.0060 ops/sec) moo: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS 0: [0..32767]: 187605400..187638167 2 (53387672..53420439) 32768 00000 moo: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS 0: [0..2047]: 187605400..187607447 2 (53387672..53389719) 2048 00000 1: [2048..2175]: 187670808..187670935 2 (53453080..53453207) 128 10000 2: [2176..65407]: 187607576..187670807 2 (53389848..53453079) 63232 00000 We did it this way in part to utilize xfs_free_file_space's partial block zeroing capabilities, so factor that out, then use it + xfs_alloc_file_space to convert in place.