In this post, I will briefly describe the differences between disk block size and filesystem block size.
In the computer architecture, every byte in the main memory has a unique address. In x86 arch, the CPU can read 4 bytes one time from the memory, while, in x86_64 arch, the CPU can read 8 bytes one time from the memory. However, when it comes to hard disk, the thing is different.
The unit that is addressable in hard disk is called sector. Every time when CPU needs to read some data from the disk, the disk controller will read one or more entire sectors a time. Usually the sector is 512 bytes. Modern disks now also support sectors of a larger size, e.g. 1KB. So it is impossible for CPU to just read 4 or 8 bytes from the disk. The sector in disk is also called disk block. So the disk block size is the same as the disk sector size. You can use the below command to find out the size of the disk block:
blockdev –getss devices
Take my disk for example:
[root@leonvm ~]# blockdev –getss /dev/vda2
In order for a disk to be using by an OS, the disk must be partitioned and formatted with a filesystem. There is also a block concept in filesystem. This block is different from the disk block. When a file is stored in the filesystem, the file is divided into filesystem blocks and stored into disk. The filesystem block is usually a multiple of disk blocks. So a file is finally stored in disk as a number of disk blocks. You can use the below command to find out the size of the filesystem block:
[root@leonvm ~]# blockdev –getbsz /dev/vda2
We can conclude that one filesystem block consists of 8 disk blocks. 4096 = 512 * 8. When the size of a file is smaller than the filesystem block, it still occupies the whole filesystem block. Take the below file for example,
[xiaoliang@leonvm ~]$ cat demo.txt
We can see that there is only file characters in this file. But when we list the detailed information of this file, we can see that it occupies 8 disk blocks as below:
[xiaoliang@leonvm ~]$ stat demo.txt
Size: 5 Blocks: 8 IO Block: 4096 regular file
Device: fd02h/64770d Inode: 2136918 Links: 1
Access: (0664/-rw-rw-r–) Uid: ( 1000/xiaoliang) Gid: ( 1000/xiaoliang)
Access: 2021-04-18 15:04:56.190000000 +0800
Modify: 2021-04-15 10:25:22.338000000 +0800
Change: 2021-04-18 15:04:51.438000000 +0800
From the above command output, we can see the size of the file is 5. This is correct, as this file only contains the string ‘hello’. We can also see that the file occupies 8 disk blocks, even if the file only contains 5 characters. However, if you use the ‘ls’ command to list the information about this file, you may get a different block number as below:
[xiaoliang@leonvm ~]$ ls -ls demo.txt
4 -rw-rw-r–. 1 xiaoliang xiaoliang 5 Apr 15 10:25 demo.txt
The command output indicates 4 blocks for the file. This is because the ‘ls’ command is mainly for human read. It uses 1024 as block size, so it reports 4 block for the file. To correct this, you can add another command option as below:
[xiaoliang@leonvm ~]$ ls -ls –block-size=512 demo.txt
8 -rw-rw-r–. 1 xiaoliang xiaoliang 1 Apr 15 10:25 demo.txt
If you check the manual of the ‘blockdev’ command, you can see another option ‘–getpbsz’. This option is used to get the physical block size of the disk. This option is made available in the below commit.
The physical sector is what the disk actually read or write, while the logical sector is what you can ask the disk to read or write. Usually the physical block size is equal to or greater than the logical block size.
[root@leonvm ~]# blockdev –getpbsz /dev/vda2
Below is a summary of the options I mentioned in the post:
--getbsz Print the blocksize in bytes. This size does not describe device topology. It's the size used internally by the kernel and it may be modified (for example) by filesystem driver on mount. --getpbsz Get physical block (sector) size. --getss Print logical sector size in bytes – usually 512.