@@ -577,7 +577,7 @@ fn determine_sectors_per_fat(
577
577
sectors_per_fat as u32
578
578
}
579
579
580
- fn try_fs_geometry (
580
+ fn try_fs_layout (
581
581
total_sectors : u32 ,
582
582
bytes_per_sector : u16 ,
583
583
sectors_per_cluster : u8 ,
@@ -638,25 +638,41 @@ fn determine_root_dir_sectors(root_dir_entries: u16, bytes_per_sector: u16, fat_
638
638
}
639
639
}
640
640
641
- fn determine_fs_geometry < E : IoError > (
642
- total_sectors : u32 ,
643
- bytes_per_sector : u16 ,
641
+ struct FsLayout {
642
+ fat_type : FatType ,
643
+ reserved_sectors : u16 ,
644
+ sectors_per_fat : u32 ,
644
645
sectors_per_cluster : u8 ,
645
- root_dir_entries : u16 ,
646
- fats : u8 ,
647
- ) -> Result < ( FatType , u16 , u32 ) , Error < E > > {
646
+ }
647
+
648
+ fn determine_fs_layout < E : IoError > ( options : & FormatVolumeOptions , total_sectors : u32 ) -> Result < FsLayout , Error < E > > {
649
+ let bytes_per_cluster = options. bytes_per_cluster . unwrap_or_else ( || {
650
+ let total_bytes = u64:: from ( total_sectors) * u64:: from ( options. bytes_per_sector ) ;
651
+ determine_bytes_per_cluster ( total_bytes, options. bytes_per_sector , options. fat_type )
652
+ } ) ;
653
+
654
+ let sectors_per_cluster = bytes_per_cluster / u32:: from ( options. bytes_per_sector ) ;
655
+ assert ! ( sectors_per_cluster <= u32 :: from( u8 :: MAX ) ) ;
656
+ let sectors_per_cluster = sectors_per_cluster as u8 ;
657
+
648
658
for & fat_type in & [ FatType :: Fat32 , FatType :: Fat16 , FatType :: Fat12 ] {
649
- let root_dir_sectors = determine_root_dir_sectors ( root_dir_entries, bytes_per_sector, fat_type) ;
650
- let result = try_fs_geometry (
659
+ let root_dir_sectors =
660
+ determine_root_dir_sectors ( options. max_root_dir_entries , options. bytes_per_sector , fat_type) ;
661
+ let result = try_fs_layout (
651
662
total_sectors,
652
- bytes_per_sector,
663
+ options . bytes_per_sector ,
653
664
sectors_per_cluster,
654
665
fat_type,
655
666
root_dir_sectors,
656
- fats,
667
+ options . fats ,
657
668
) ;
658
669
if let Ok ( ( reserved_sectors, sectors_per_fat) ) = result {
659
- return Ok ( ( fat_type, reserved_sectors, sectors_per_fat) ) ;
670
+ return Ok ( FsLayout {
671
+ fat_type,
672
+ reserved_sectors,
673
+ sectors_per_fat,
674
+ sectors_per_cluster,
675
+ } ) ;
660
676
}
661
677
}
662
678
@@ -668,29 +684,12 @@ fn format_bpb<E: IoError>(
668
684
options : & FormatVolumeOptions ,
669
685
total_sectors : u32 ,
670
686
) -> Result < ( BiosParameterBlock , FatType ) , Error < E > > {
671
- let bytes_per_cluster = options. bytes_per_cluster . unwrap_or_else ( || {
672
- let total_bytes = u64:: from ( total_sectors) * u64:: from ( options. bytes_per_sector ) ;
673
- determine_bytes_per_cluster ( total_bytes, options. bytes_per_sector , options. fat_type )
674
- } ) ;
675
-
676
- let sectors_per_cluster = bytes_per_cluster / u32:: from ( options. bytes_per_sector ) ;
677
- assert ! ( sectors_per_cluster <= u32 :: from( u8 :: MAX ) ) ;
678
- let sectors_per_cluster = sectors_per_cluster as u8 ;
679
-
680
- let fats = options. fats ;
681
- let root_dir_entries = options. max_root_dir_entries ;
682
- let ( fat_type, reserved_sectors, sectors_per_fat) = determine_fs_geometry (
683
- total_sectors,
684
- options. bytes_per_sector ,
685
- sectors_per_cluster,
686
- root_dir_entries,
687
- fats,
688
- ) ?;
687
+ let layout = determine_fs_layout ( options, total_sectors) ?;
689
688
690
689
// drive_num should be 0 for floppy disks and 0x80 for hard disks - determine it using FAT type
691
690
let drive_num = options
692
691
. drive_num
693
- . unwrap_or_else ( || if fat_type == FatType :: Fat12 { 0 } else { 0x80 } ) ;
692
+ . unwrap_or_else ( || if layout . fat_type == FatType :: Fat12 { 0 } else { 0x80 } ) ;
694
693
695
694
// reserved_0 is always zero
696
695
let reserved_0 = [ 0_u8 ; 12 ] ;
@@ -713,19 +712,19 @@ fn format_bpb<E: IoError>(
713
712
fs_type_label. copy_from_slice ( fs_type_label_str) ;
714
713
715
714
// create Bios Parameter Block struct
716
- let is_fat32 = fat_type == FatType :: Fat32 ;
715
+ let is_fat32 = layout . fat_type == FatType :: Fat32 ;
717
716
let sectors_per_fat_16 = if is_fat32 {
718
717
0
719
718
} else {
720
- debug_assert ! ( sectors_per_fat <= u32 :: from( u16 :: MAX ) ) ;
721
- sectors_per_fat as u16
719
+ debug_assert ! ( layout . sectors_per_fat <= u32 :: from( u16 :: MAX ) ) ;
720
+ layout . sectors_per_fat as u16
722
721
} ;
723
722
let bpb = BiosParameterBlock {
724
723
bytes_per_sector : options. bytes_per_sector ,
725
- sectors_per_cluster,
726
- reserved_sectors,
727
- fats,
728
- root_entries : if is_fat32 { 0 } else { root_dir_entries } ,
724
+ sectors_per_cluster : layout . sectors_per_cluster ,
725
+ reserved_sectors : layout . reserved_sectors ,
726
+ fats : options . fats ,
727
+ root_entries : if is_fat32 { 0 } else { options . max_root_dir_entries } ,
729
728
total_sectors_16 : if total_sectors < 0x10000 {
730
729
total_sectors as u16
731
730
} else {
@@ -738,7 +737,7 @@ fn format_bpb<E: IoError>(
738
737
hidden_sectors : 0 ,
739
738
total_sectors_32 : if total_sectors >= 0x10000 { total_sectors } else { 0 } ,
740
739
// FAT32 fields start
741
- sectors_per_fat_32 : if is_fat32 { sectors_per_fat } else { 0 } ,
740
+ sectors_per_fat_32 : if is_fat32 { layout . sectors_per_fat } else { 0 } ,
742
741
extended_flags : 0 , // mirroring enabled
743
742
fs_version : 0 ,
744
743
root_dir_first_cluster : if is_fat32 { 2 } else { 0 } ,
@@ -755,12 +754,12 @@ fn format_bpb<E: IoError>(
755
754
} ;
756
755
757
756
// Check if number of clusters is proper for used FAT type
758
- if FatType :: from_clusters ( bpb. total_clusters ( ) ) != fat_type {
757
+ if FatType :: from_clusters ( bpb. total_clusters ( ) ) != layout . fat_type {
759
758
error ! ( "Total number of clusters and FAT type does not match, please try a different volume size" ) ;
760
759
return Err ( Error :: InvalidInput ) ;
761
760
}
762
761
763
- Ok ( ( bpb, fat_type) )
762
+ Ok ( ( bpb, layout . fat_type ) )
764
763
}
765
764
766
765
pub ( crate ) fn format_boot_sector < E : IoError > (
0 commit comments