Stat, Blocks and Sector size – ext4

filesystemsstat

While reading upon how files are stored in the filesystem, I created a testfile which happened to be of size 217 bytes. Checking the output of stat on this file, I saw that this file is occupying 8 blocks. Initially I thought that there is no way that a file of size 217 bytes can be using 8 blocks when the Block size is 4096 bytes and the value at Blocks: should be 1 instead of 8. Then I read this, this and this and realized that the Blocks: value is the number of 512 bytes space occupied by the file. And since the minimum size of a block is 4096 bytes, even a file of size 2 bytes will occupy 8 blocks (because 4096/512 = 8).

[root@server ~]# stat smallfile.txt
  File: `smallfile.txt'
  Size: 217             Blocks: 8          IO Block: 4096   regular file

I had read here that:

"Each sector stores a fixed amount of user-accessible data,
traditionally 512 bytes for hard disk drives (HDDs) and 2048 bytes for
CD-ROMs and DVD-ROMs. Newer HDDs use 4096-byte (4 KiB) sectors, which
are known as the Advanced Format (AF)."

All of the systems I have access to used HDDs with sector size 512 bytes. So I believe that the st_blocks (as explained the 2nd and 3rd hyperlinks I have given) matches the sector size of the hard-drive? So the question is:

  • In future, if I am to have the same 217 bytes sized file on an HDD with a sector size of 4096 bytes, would the stat command on the file would show Blocks: 1 instead of Blocks: 8 (since 4096/4096 = 1) ?
  • Or st_blocks will always use 512 byte as the single minimum unit regardless of the sector size?
  • Or has it something to do with the VFS?

Best Answer

The links you give explicitly state:

The st_blocks field indicates the number of blocks allocated to the file, 512-byte units.

So they're always in units of 512-byte blocks, regardless of what underlying device is used. The stat command simply displays what the stat system call returns. The 512-byte block is a historic thing, defined in POSIX. Compare for example these:

$ ls -s smallfile.txt
4 smallfile.txt
$ env POSIXLY_CORRECT=1 ls -s smallfile.txt
8 smallfile.txt

GNU ls displays blocks by default in 1kB blocks, but when forced to comply with POSIX it shows 512-byte blocks.

Related Question