New formula gives nearly perfect results (according to tests) and is
better than formula from specification.
Also all math transformations are provided in comments so it is no longer
a blindly copied formula from spec but a Math supported formula.
Old formula was not taking into account sector size (it resulted in too
big FATs for sector size different than 512) and had rounding issues for
FAT12 and FAT32.
Previous implementation did not zero allocated cluster so created directory
could have garbage contents.
Bug exists in code since version 0.2 and all code using create_dir is
affected.
This commit also improves tests of volume formatting so a dirty partition
is used allowing to detect bugs like this.
Previous code is not working correctly if sector size is different than 512.
Creating test for this issue would require another binary blob in
repository so I am leaving it without test for now.
* Update compatibility maximum cluster size when sector size is larger than 512 bytes.
* Additional validation of values in FsInfo sector.
* next_free_cluster cannot be 0 or 1, as these are reserved clusters
* next_free_cluster must be a valid cluster (using BPB to validate)
* free_cluster_count must be possible value (using BPB to validate)
* Avoid data-loss edge-case on volumes over 138GB in size.
Specifically, if the volume has more
than 0x0FFF_FFF4 clusters, then the FAT
will include an entry for clusters that
are reserved values. Specifically, cluster
number 0x0FFF_FFF7 is defined to mean
BAD_SECTOR, while numbers 0x0FFF_FFF8 ..
0x0FFF_FFFF are defined to mean end-of-chain.
This prevents these clusters from being part
of any valid cluster chain. Therefore:
1. prevent setting these clusters to point to
a valid next cluster
2. prevent reading these clusters as pointing
to a valid next cluster
Instead, always read/write these FAT entries
to have next cluster value of BAD_SECTOR.
* Reduce noisy warnings on FAT32.
* The reserved bits in FAT entry must be preserved on update.
* Change the set() implementation for FAT32 entries to return an actual Err(),
when attempting to set values for cluster numbers that have special meaning.
* Fix copy/paste errors in ls example so file sizes are correctly output.
* BPB updates.
Fix bug in bpb.active_fat(), because active_fat is
only valid when mirroring is disabled.
Add additional santiy checks to BPB deserialization:
1. bytes per sector must be a power of 2
2. 512 <= bytes per sector <= 4096
3. sectors per cluster must be a power of 2
4. 1 <= sectors per cluster <= 128
Also added some comments relating to conditions that
may be useful to WARN about for BPB deserialization:
Z. bpb.reserved_sectors should be 1
Y. bpb.fats should be either 1 or 2
X. bpb.fs_version should be validated as zero
Add syntactic sugar for:
A. bpb.is_fat32()
B. bpb.sectors_per_fat()
C. bpb.total_sectors()
Encoder is not yet used but will be in future.
This is implemented as static reference for now to avoid adding additional
type parameters to all main types. It should be enough for most of cases
where encoder/decoder does not have any state and can be implemented as
static variable.