Search code examples
raspberry-pimountpartitionbuildrootlinux-disk-free

Partition's size in df -h is totally different than the size in /proc/partitions


I'm using buildroot to build a custom linux system for my raspi A+.

Using genimage, I've created two partitions on a 1 GB sdcard. The first partion is the boot partition. It's vfat and it is 32 MB. The second partition is ext4, it is the rootfs and it is 512 MB.

Once I boot my raspi with the newly burned sdcard and that I type df -h I get this in the output:

Filesystem                Size      Used Available Use% Mounted on
/dev/root                17.1M     14.0M      1.8M  89% /
devtmpfs                200.6M         0    200.6M   0% /dev
tmpfs                   200.7M         0    200.7M   0% /dev/shm
tmpfs                   200.7M         0    200.7M   0% /tmp
tmpfs                   200.7M      4.0K    200.7M   0% /run

as you can see, /dev/root is 17.1 MB instead of 512 MB.

Then, I issue cat /proc/partitions:

major minor  #blocks  name

  1        0       4096 ram0
  1        1       4096 ram1
  1        2       4096 ram2
  1        3       4096 ram3
  1        4       4096 ram4
  1        5       4096 ram5
  1        6       4096 ram6
  1        7       4096 ram7
  1        8       4096 ram8
  1        9       4096 ram9
  1       10       4096 ram10
  1       11       4096 ram11
  1       12       4096 ram12
  1       13       4096 ram13
  1       14       4096 ram14
  1       15       4096 ram15
179        0     969728 mmcblk0
179        1      32768 mmcblk0p1
179        2     524288 mmcblk0p2

We clearly see that the sdcard (mmcblk0) is 1 GB, the boot partition (mmcblk0p1) is 32 MB and the rootfs partition (mmcblk0p2) is 512 MB.

So, to convince myself that the mmcblk0p2 partition may have been imporperly mounted, I mount it again with mount -t ext4 -o rw /dev/mmcblk0p2 /mnt and then I issue df -h again:

Filesystem                Size      Used Available Use% Mounted on
/dev/root                17.1M     14.0M      1.8M  89% /
devtmpfs                200.6M         0    200.6M   0% /dev
tmpfs                   200.7M         0    200.7M   0% /dev/shm
tmpfs                   200.7M         0    200.7M   0% /tmp
tmpfs                   200.7M      4.0K    200.7M   0% /run
/dev/mmcblk0p2           17.1M     14.0M      1.8M  89% /mnt

Again, I see that mmcblk0p2 size is 17.1 MB.

So, my question is Why is cat /proc/partitions returning the expected size for my rootfs partition while df -h returns a totally different and bogus size ?


Solution

  • TL;DR: set BR2_TARGET_ROOTFS_EXT2_BLOCKS to 524288.

    You have to distinguish the partition from the filesystem on the partition.

    The partition sizes and offsets are specified in the partition table, and you can view them with cat /proc/partitions. Paritions are created with a tool like fdisk (or when you're using Buildroot, it's often created by genimage).

    The filesystem size is specified in the filesystem superblock, a piece of metadata that specifies the size of the filesystem, any options (e.g. if journalling is used), cluster sizes, etc. This is created by a tool like mke2fs. When you use mke2fs directly on a partition, it will use the full space of the partition for the filesystem, which is typically what you want. However, when you create the filesystem before partitioning the SD card (as is often the case when you generate an image with e.g. Buildroot), you have to specify the size to mke2fs (cfr. the man page: the second argument is blocks-count).

    In Buildroot, you typically create an image as a file and don't write directly to the SD card. That is because the size of the SD card is not known a priori, and because you have to be root to be able to write the SD card. Therefore, there is no way for Buildroot to know how large the ext4 filesystem should be when you create the filesystem. Before the 2017.05 release of Buildroot, it would try to estimate how large the filesystem should be to fit everything, and create a filesystem of exactly that size. You are probably in that situation.

    To fix this, you should set the configuration variable BR2_TARGET_ROOTFS_EXT2_BLOCKS to 524288 (= 512MB in 1024-byte blocks). Or if you use Buildroot more recent than the 2017.05 release, set BR2_TARGET_ROOTFS_EXT2_SIZE to 512M (the new option is in bytes but allows suffixes K, M, G).