Why the partitions don’t show the right capacity on a 4096 byte physical block hard drive

ext4filesystemspartitionswap

After reading a lot about why newer 4096 byte physical block hard drives should be partitioned taking care of alignment (Linux on 4KB-sector disks: Practical advice, What is partition alignment and why whould I need it?, Why do I have to “align” the partitions on my new Western Digital hard drive?, I was convinced to make sure my new disk was properly partitioned and formatted with 4096 byte blocks.

So I did partition it using fdisk -b 4096 /dev/sdb and specified a 50GB size for sdb1, 412GB for sdb2 and the remaining space to sdb3 (3.8GB for sdb3), leading to the following partition table:

    Disk /dev/sdb: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 7600 cylinders, total 122096646 sectors
Units = sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x1c7f9c20

       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1   *         256    13107455    52428800   83  Linux
    /dev/sdb2        13107456   121110783   432013312   83  Linux
    /dev/sdb3       121110784   122096645     3943448   82  Linux swap

Then I formatted both sdb1 and sdb2 with ext4:

# mkfs.ext4 /dev/sdb1 
mke2fs 1.42.4 (12-June-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
409600 inodes, 1638400 blocks
81920 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1677721600
50 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

# mkfs.ext4 /dev/sdb2 
mke2fs 1.42.4 (12-June-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
3375104 inodes, 13500416 blocks
675020 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
412 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

and setup the swap area:

# mkswap /dev/sdb3
Setting up swapspace version 1, size = 492924 KiB
no label, UUID=2d18a027-6c03-4b29-b03e-c0c7f61413c5

The first strange thing I noticed was the reported swap size of just 492924 KiB. Then, after mouting the newly formatted partitions, I found them to appear much smaller than they should be:

Filesystem                        Size  Used Avail Use% Mounted on
/dev/sdb1                         6.3G  222M  5.8G   4% /mnt/zip
/dev/sdb2                          52G  907M   48G   2% /mnt/memory

Why is that happening? Is there any way to correct this?

EDIT:

After @Alexios suggestion I tried rebooting but /proc/partitions didn't change. Both /dev/sda and /dev/sdb are identical 500GB drives, but /dev/sda I formatted unaligned (using default 512 byte sector size starting after sector 63) and /dev/sdb aligned (using 4096 sector size starting after sector 255). As we can see, the system considers /dev/sdb just has less blocks than /dev/sda, although both were partitioned with the same sizes:

# cat /proc/partitions 
major minor  #blocks  name

  11        0    4590208 sr0
   8        0  488386584 sda
   8        1   48829536 sda1
   8        2  437498145 sda2
   8        3    2058871 sda3
   8       16  488386584 sdb
   8       17    6553600 sdb1
   8       18   54001664 sdb2
   8       19     492931 sdb3

Best Answer

What is happening is that the -b switch is nonsense and should not even be there. The sector numbers recorded in the MBR are always interpreted to be in units of the drive's logical sector size ( 512 bytes ). By using the -b switch, you are causing fdisk to divide all of the sectors it records by 8, so the kernel interprets the partitions to be 1/8th the size you intended.

If you use parted instead of fdisk, it will make sure your partitions are properly aligned automatically. With fdisk, just make sure that the starting sectors are a multiple of 8.

Related Question