Re: Understanding reported block count for sparse files
- In reply to: Alan Somers : "Re: Understanding reported block count for sparse files"
 - Go to: [ bottom of page ] [ top of archives ] [ this month ]
 
Date: Thu, 24 Jul 2025 02:49:16 UTC
On Wed, Jul 23, 2025 at 12:52:11PM -0600, Alan Somers wrote: > On Wed, Jul 23, 2025 at 12:33 PM Roman Bogorodskiy <novel@freebsd.org> > wrote: > > > Hi, > > > > I'm porting a test from Linux, and this test checks the allocated block > > count for the sparse file. Its expectation is that the block count > > should be close to zero. > > > > To isolate things, it roughly does the following: > > > > Linux: > > > > $ truncate -s +52428800 test.raw > > $ stat test.raw > > File: test.raw > > Size: 52428800 Blocks: 0 IO Block: 4096 regular file > > Device: 252,0 Inode: 25218599 Links: 1 > > Access: (0644/-rw-r--r--) Uid: ( 1000/ novel) Gid: ( 1000/ novel) > > Context: unconfined_u:object_r:user_home_t:s0 > > Access: 2025-07-23 14:20:31.640547511 -0400 > > Modify: 2025-07-23 14:20:31.642105574 -0400 > > Change: 2025-07-23 14:20:31.642105574 -0400 > > Birth: 2025-07-23 14:20:31.640547511 -0400 > > > > It reports 0 blocks. > > Filesystem here is xfs. > > > > FreeBSD: > > > > $ truncate -s +52428800 test.raw > > $ stat -f "%z %k %b" test.raw > > 52428800 32768 128 > > > > This reports 128 blocks. Filesystem here is UFS. > > > > What's reason behind this difference? > > > > Thanks, > > Roman > > > That "Blocks" figure comes from the "st_blocks" field, returned by > VOP_STAT. It is entirely up to the file system what to put in that field. > For example, if the file system is compressed, should st_blocks describe > the blocks used before or after compression? ZFS reports blocks after > compression, but IIRC btrfs reports blocks before compression. Both are > legal. > > In this very specific case I can tell you why you are seeing this > difference. UFS organizes files in a tree of indirect blocks. The tree > can be up to 4 levels high, IIRC. So what's probably happening is that UFS > is actually allocating all of the L2 and/or L1 blocks for the file, even > though it's totally sparse, but not allocating any L0 blocks. If you > really want to know exactly what's going on, we can probably explore the > file in detail with filesystems/fuse-ufs. > > XFS, OTOH, is different. It's an extent-based file system. There's no > such thing as indirect blocks. So when you create a huge but sparse file > in XFS, all it needs to allocate is the inode. The number of metadata > blocks is determined not so much by the file's size as by its > fragmentation. It's technically possible, if the file is fully > defragmented, to represent a 1 TB file with no metadata blocks except for > the inode. But unlikely in practice. You could try using > filesystems/xfuse or filesystems/lkl to see what that XFS file system looks > like when mounted on FreeBSD, too. UFS always allocates (partial) block for the last byte of the file.