[syslinux] [PATCH 1/5] fat: fix minfatsize for large FAT32

Pete Batard pete at akeo.ie
Fri Feb 26 04:51:55 PST 2016

Hi Ady,

I won't comment on the reasons why the original computation was wrong, 
but thanks for the detailed analysis.

On 2016.02.26 08:05, Ady via Syslinux wrote:
>> Thus we can finally get a formula for Fs that satisfies the above:
>>      Fs = (To - Rs + Nf * Cs)  / ((Ss * Cs / Fe) + Nf) + 1
> I believe such formula is slightly inaccurate too.
> My resulting inequation is
>          ( To - Rs ) + ( 2 * Cs )
>   Fs >= __________________________
>           ( Ss * Cs / Fe ) + Nf

I believe you're right. I assumed that the 2 that eventually ends up in 
the numerator was the Number of FATs, but looking further, and 
especially at Wikipedia [1], I see that it is the number of special 
clusters, which is fixed to 2 regardless of the number of FATs:

"The first two entries in a FAT store special values: The first entry 
(cluster 0 in the FAT) holds the FAT ID (...) The second entry (cluster 
1 in the FAT) nominally stores the end-of-cluster-chain marker (...)"

So as you point out, this should be hardcoded to 2. Thanks for picking 
this up.

Wouldn't have been a dramatic mistake, since I don't see any possibility 
of using a number of FATs that's anything but 2 in the context of Rufus, 
but we should indeed get our variables right.

> instead of _always_ adding "+1" (which would be
> incorrect and inefficient from the point of view of the resulting
> allocatable size).

I carefully considered this, and I dispute the fact that this is incorrect.

The problem is we're dealing with a fraction, which will be limited by 
the number of bits the computer uses to store the data *and might be 
rounded down behind the scenes*. E.g. unless you use a crazy number of 
bits to store your numbers, something like (10^100 + 1) / (10^100) will 
produce 1 and the modulo (10^100 + 1) % (10^100) will produce 0. So if 
you use the modulo to figure out if you need to round up, you're going 
to miss some cases. And while I'd like to believe that all of "roundup", 
"ceiling" and friends are smart enough to know the precision they're 
dealing with, and compensate accordingly, or, more realistically here, 
that the numbers we're dealing with in this case will never be large 
enough to test the limits of our precision (especially our numerator and 
denominator are set to 64bit and our disks will never be larger than 2TB 
anyway, because FAT32), I'd rather not take any risks here, even more so 
as I am fixing code that was missing addressable sectors and the last 
thing I'd want is find out that, because of a dodgy rounding or a wrong 
assumption, we might still end up missing some sectors after all.

And yeah, we could add the actual roundup in the equations themselves (I 
actually did that when I was trying to figure out if the original wrong 
computation wasn't due to the roundup), but since the "only going to be 
*very slightly* wasteful in an exceedingly limited set of cases" +1 is a 
safe and sure way to address the rounding "issue", I have to admit that 
I'm not that interested in trying to come up with a more mathematically 
satisfying solution.

Working and relatively efficient code is what I am after, and as far as 
I'm concerned, using +1 is both a "correct" and "efficient" way of 
achieving that.

Still, I won't prevent you (or anybody else interested) to provide a 
proper formula if you want. ;)




More information about the Syslinux mailing list