[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Info-mtools] Bug: mformat does not format FAT32 correctly
From: |
Pali Rohár |
Subject: |
Re: [Info-mtools] Bug: mformat does not format FAT32 correctly |
Date: |
Sat, 11 Aug 2018 12:45:09 +0200 |
User-agent: |
NeoMutt/20170113 (1.7.2) |
On Tuesday 12 December 2017 10:41:26 Pali Rohár wrote:
> On Monday 04 December 2017 19:29:53 Pali Rohár wrote:
> > 2) mformat refuse to create FAT32 if disk size is less then 257 MB.
> >
> > Test to reproduce (-F means to format as FAT32):
> >
> > $ truncate -s 100M fat.img
> > $ mformat -F -h 64 -s 32 -t 100 -m 0xf8 :: -i fat.img
> >
> > mformay show just error message:
> >
> > Too few clusters for this fat size. Please choose a 16-bit fat in your
> > /etc/mtools.conf or .mtoolsrc file
> >
> > Fix is to set size of cluster (in number of sectors) to 1. So mformat
> > parameter: -c 1
> >
> > It is pity that mformat cannot calculate cluster size for smaller FAT32
> > disks (when size is less then 257 MB). Note that mformat can calculate
> > it correctly for FAT16 (when -F is not used).
Also there is a problem with large disks. By default, 2TB disk formatted
by mformat to FAT32 is not readable by Linux kernel. It just says:
FAT-fs (loop0): count of clusters too big (536739966)
FAT-fs (loop0): Can't find a valid FAT filesystem
To workaround this problem, it is needed to specify -c 64 parameter due
to the same problem. mformat does not calculates cluster size correctly.
> > 3) Cluster size is not calculated correctly according to Microsoft FAT
> > specification. This also answer why there is a bug 2).
> >
> > Function which calculate cluster size is named calc_cluster_size and can
> > be found in mformat.c source code. Relevant part for FAT32 is:
> >
> > switch(abs(fat_bits)) {
> > ...
> > case 32:
> > Fs->cluster_size = 8;
> > /* According to
> > *
> > http://support.microsoft.com/support/kb/articles/q154/9/97.asp
> > * Micro$oft does not support FAT32 with less than 4K
> > */
> > return;
> > ...
> >
> > It means that cluster size is hardcoded to 8 sectors for FAT32. This is
> > also reason for problem 3). For FAT16 there is autodetection code. I do
> > not know what that comment mean or what it try to refer as link is dead.
> >
> > So I would like to know, why is hardcoded 8 sectors as cluster size for
> > FAT32? I suspect this is a bug which needs fixing. At least to have
> > working mformat in FAT32 mode for small disk (or disk images).
>
> Also please note that current versions of Windows (probably since 2000)
> allow user to specify cluster size in Format dialog also for FAT32. And
> default value depends on disk size, it is not hardcoded to 8 (=4kB).
>
> See also:
> https://support.microsoft.com/en-us/help/192322/description-of-default-cluster-sizes-for-fat32-file-system
> https://support.microsoft.com/en-us/help/140365/default-cluster-size-for-ntfs--fat--and-exfat
>
> So I would really suggest to change above hardcoded value 8 to either
> mapping table or use similar algorithm as is already present for FAT16
> in mformat.c
>
> > Because, in Microsoft FAT32 specification (fatgen103.doc) on page 20 for
> > FAT32 is written calculation table. For disk size there is cluster size
> > (in number of sectors), see table below:
> >
> > 32.5 MB - 260 MB cluster_size = 1
> > 260 MB - 8 GB cluster_size = 8
> > 8 GB - 16 GB cluster_size = 16
> > 16 GB - 32 GB cluster_size = 32
> > 32 GB - 2 TB cluster_size = 64
> >
> > Note that in that Microsoft FAT specification is written: "The rest of
> > this section is totally specific to drives that have 512 bytes per
> > sector.". So there is need to recalculate values when (logical) sector
> > size is not 512 bytes.
In attachment is a patch for mtools which calculates FAT32 cluster size
according to that Microsoft specification. With that patch I'm able to
correctly format small FAT32 disks (below 100M) and also big disks (2TB)
and even also very huge disks 16TB with 4k sectors.
Examples:
small 100 MB FAT32 disk image
$ truncate -s 100MB /tmp/fat
$ mformat -F -h 64 -s 32 -t $((100-1)) :: -i /tmp/fat
big 2 TB FAT32 disk image (this is maximal size for 512 byte sectors)
$ truncate -s 2TB /tmp/fat
$ mformat -F -h 64 -s 32 -t $((2*1024*1024-1)) :: -i /tmp/fat
very huge 16 TB FAT32 disk image with 4k sectors
$ truncate -s 16TB /tmp/fat
$ mformat -F -M 4096 -h 8 -s 32 -t $((16*1024*1024-1)) :: -i /tmp/fat
Everything is correctly detected and mounted on Linux.
--
Pali Rohár
address@hidden
mtools_fat32_cluster_size.patch
Description: Text Data
signature.asc
Description: PGP signature