The list of blocks that make up the file has to be stored somewhere. Typically there's a little space in the inode, but if there are too many blocks to fit in the inode, the filesystem allocates indirect blocks to store the address of the blocks, in addition to the blocks that contain file data. At least for ext2/ext3/ext4 on Linux, and I think for most Unix-like filesystems on most Unix-like operating systems, the indirect blocks are taken into account in the file's disk usage.
Ext4 uses extent trees to store block lists. If a file uses a list of consecutive blocks in order, this takes up a single entry in the tree. Thus a file with little fragmentation doesn't need any indirect blocks, just one entry in the tree that specifies the first block and the number of blocks. A maximally fragmented file needs a lot of indirect blocks to store one tree entry per block. If the file is not fragmented or only very slightly then no indirect block is needed and the file's disk usage is the file size rounded up to a whole number of filesystem blocks. Fragmented files require indirect blocks.
Ext2 and ext3 have a simpler scheme where the block list is not compressed so the number of entries scales slightly more than linearly with the size of the file, requiring indirect blocks if the file uses more than 12 blocks (that's how many blocks can be recorded directly in the inode).
You can explore an ext2/ext3/ext4 filesystem with the
debugfs command. In debugfs,
blocks /path/to/file lists the blocks used by a file; this shows how fragmented the file is. The command
filefrag /path/to/file gives the number of fragments; for ext4 this correlates with the number of indirect blocks and hence with the difference between file size and file disk usage.