MBR and alignment on 4K disks

wblock@

Developer
Aligning MBR Partitions With 4K Drives

The Problem

The MBR specification says that partitions must be aligned to "cylinder" values. This works fine on old drives where each track had the same number of blocks, but drives like that have not been made in a decade or two. Modern drives pack more blocks in the longer, outer tracks. They have no real concept of cylinders, it's all just blocks.

FreeBSD aspires to be standards-compliant, so gpart(8) insists on rounding values for MBR partitions to something even. With the fake cylinder/heads/sectors (CHS) numbers provided for modern drives, this usually has the same effect as using -a 63 with gpart: partition boundaries are rounded to 63-block values. You can ask it to start an MBR partition at a specific place, but it probably will not go there. FreeBSD allocates the first 63 512-byte blocks to the MBR, probably due to CHS alignment.

The Problem, Part Two

New, large-capacity drives use 4K blocks to more efficiently deal with all that space. They use "logical" 512-byte blocks mapped into those 4K physical blocks to remain compatible with existing systems.

FreeBSD's UFS filesystem uses 4K blocks by default since FreeBSD 9.0 or so. This is fine if a filesystem block corresponds exactly with a physical block, and that's what we mean by "being aligned".

But what happens if they are not aligned? The UFS block overlaps two physical blocks. When the filesystem writes that 4K, it takes twice as long as necessary, because the drive must read one 4K block, change half of it, write it back out, and then do the same for the second block.

If you use the standard defaults, the first partition will start at block 63... misaligned.

Solution One: fdisk(8)

The old partitioning program fdisk(8) will actually let you enter arbitrary values for the starting block of an MBR partition ("slice"). It will complain if they are not CHS aligned, but still use them if you insist. Note: start your first filesystem partition at block 2048, or 1M. I've talked about reasons for that elsewhere.

Solution Two: Align FreeBSD Partitions Within The Slice

Use gpart(8) to try to create an MBR partition ("slice") starting at 2048. Usually, this results in a partition that starts at block 2079 (an even multiple of 63). Leave that alone, and create FreeBSD partitions inside the slice, but use -a to align them:
gpart add -t freebsd-ufs -a4k -s20g ada0s1

Extra space will be added before those partitions, so the partition itself ends up aligned.
 
This is what I presently have for partitioning. I used MBR because I have UEFI and for some reason GPT does not boot on this machine. The extra 37 GB is incase I want to dual boot Windows 7. I have no idea whether my values are right or not, I'm not very good at math, but I looked at several guides out there to come up with this and the partitions listed below /dev/ada0s1 were created with the gpart add-a 4096 flag.

Code:
 gpart show
=>        63  1465149105  ada0  MBR  (698G)
          63          63        - free -  (31k)
         126  1465148979     1  freebsd  [active]  (698G)
  1465149105          63        - free -  (31k)

=>         0  1465148979  ada0s1  BSD  (698G)
           0           2          - free -  (1.0k)
           2    20971520       1  freebsd-ufs  (10G)
    20971522    62914560       2  freebsd-ufs  (30G)
    83886082    33554432       4  freebsd-swap  (16G)
   117440514   209715200       5  freebsd-ufs  (100G)
   327155714    10485760       6  freebsd-ufs  (5.0G)
   337641474  1048576000       7  freebsd-ufs  (500G)
  1386217474    78931505          - free -  (37G)


Thanks for the tutorial and sorry I posted it in the other place.
 
Figure out the starting block of each partition by adding the starting block of the slice (126) and the starting block of the partition inside that slice (2):

126 + 2 = 128

If the resulting number is evenly divisible by 8 (there are eight 512-byte blocks in a 4K block), then it is aligned.
 
Thanks for this. Upon first reading I thought I would find I had misaligned partitions, but when I checked, I found them to be all aligned. Then I realized it was because I followed your disk setup tutorial, which already included the -a4k parameter in the examples. So thanks for that too.
 
Ok, I'm working through these with the formula you provided.

I have...

126 + 20971522 / 8 = 2621456, which is apparently evenly divisible by 8.
126 + 83886208 / 8 = 10485776, which is apparently evenly divisible by 8.
126 + 117440514 / 8 = 14680080, which is apparently evenly divisible by 8.
126 + 327155714 / 8 = 40894480, which is apparently evenly divisible by 8.
126 + 337641474 / 8 = 42205184, which is apparently evenly divisible by 8.

So unless the math is off that means they are aligned.

Thanks @wblock@. :)
 
Last edited by a moderator:
Back
Top