]> git.ipfire.org Git - thirdparty/util-linux.git/commit
libfdisk: (dos) Fix determining number of heads and sectors per track from MBR
authorPali Rohár <pali.rohar@gmail.com>
Tue, 6 Jul 2021 17:43:56 +0000 (19:43 +0200)
committerPali Rohár <pali.rohar@gmail.com>
Thu, 15 Jul 2021 19:49:30 +0000 (21:49 +0200)
commit9cade4fbf8c40640d94b5cd8ed1a3ac4b20a965d
tree074b993be017fe5ca34edf7f0ab1b1ad835785b1
parent639f6507b6e2b2e9a28a602675ea50c689a2659a
libfdisk: (dos) Fix determining number of heads and sectors per track from MBR

Current algorithm implemented in get_partition_table_geometry() function
is wrong. It take head bits from CHS position from the end of the last
partition and proclaim that this value is number of heads on disk. Same
does for sectors bits from CHS and proclaim that this value is number of
sectors per tracks. As number of disk heads and head bits in CHS position
are different things this just results in bogus detected disk geometry.

Implement a new algorithm to determinate number of heads and sectors per
track from partition sector offsets. In MBR table for every partition is
stored every sector offset in two formats: one as CHS and one as LBA.

Conversion from CHS to LBA is defined by formula:

   LBA = (c * N_heads + h) * N_sectors + (s - 1)

So if we have two different offsets in both CHS and LBA formats, written as
(LBA1, c1, h1, s1) and (LBA2, c2, h2, s2) then we can calculate number of
heads and sectors per tracks by solving linear equations as:

   N_heads = (o1 * h2 - o2 * h1) / (o2 * c1 - o1 * c2)
   N_sectors = (o2 * c1 - o1 * c2) / (c1 * h2 - c2 * h1)

where

   o = LBA - (s - 1)

Integer division also verifies that offsets were calculated from same
number of heads and sectors per track as division must be always positive
with no reminder.

There is a special case when either numerator or denominator is zero. This
indicates that comparing partition offsets have also same CHS offset
divisor which leads to fact that calculation of number of heads and sector
per tracks is not possible.

In MBR table are stored up to 8 offset numbers, so it means there are up
to the 28 of candidates which can expose number of disk heads and number of
disk sectors per track. Start with offsets which belongs to same partition
and start from the first partition. As the first partition in most cases
was used by BIOS for booting.

It is required to skip CHS values 1023/254/63 and 1023/255/63 as these
indicates that values are invalid or overflowed.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
libfdisk/src/dos.c