@@ -149,6 +149,9 @@ pub struct FatVolume {
149
149
/// The block the FAT starts in. Relative to start of partition (so add
150
150
/// `self.lba_offset` before passing to volume manager)
151
151
pub ( crate ) fat_start : BlockCount ,
152
+ /// The block the second FAT starts in. Relative to start of partition (so add
153
+ /// `self.lba_offset` before passing to volume manager)
154
+ pub ( crate ) second_fat_start : Option < BlockCount > ,
152
155
/// Expected number of free clusters
153
156
pub ( crate ) free_clusters_count : Option < u32 > ,
154
157
/// Number of the next expected free cluster
@@ -211,11 +214,15 @@ impl FatVolume {
211
214
where
212
215
D : BlockDevice ,
213
216
{
214
- let this_fat_block_num ;
217
+ let mut second_fat_block_num = None ;
215
218
match & self . fat_specific_info {
216
219
FatSpecificInfo :: Fat16 ( _fat16_info) => {
217
220
let fat_offset = cluster. 0 * 2 ;
218
- this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
221
+ let this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
222
+ if let Some ( second_fat_start) = self . second_fat_start {
223
+ second_fat_block_num =
224
+ Some ( self . lba_start + second_fat_start. offset_bytes ( fat_offset) ) ;
225
+ }
219
226
let this_fat_ent_offset = ( fat_offset % Block :: LEN_U32 ) as usize ;
220
227
trace ! ( "Reading FAT for update" ) ;
221
228
let block = block_cache
@@ -237,7 +244,11 @@ impl FatVolume {
237
244
FatSpecificInfo :: Fat32 ( _fat32_info) => {
238
245
// FAT32 => 4 bytes per entry
239
246
let fat_offset = cluster. 0 * 4 ;
240
- this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
247
+ let this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
248
+ if let Some ( second_fat_start) = self . second_fat_start {
249
+ second_fat_block_num =
250
+ Some ( self . lba_start + second_fat_start. offset_bytes ( fat_offset) ) ;
251
+ }
241
252
let this_fat_ent_offset = ( fat_offset % Block :: LEN_U32 ) as usize ;
242
253
trace ! ( "Reading FAT for update" ) ;
243
254
let block = block_cache
@@ -259,7 +270,11 @@ impl FatVolume {
259
270
}
260
271
}
261
272
trace ! ( "Updating FAT" ) ;
262
- block_cache. write_back ( ) ?;
273
+ if let Some ( duplicate) = second_fat_block_num {
274
+ block_cache. write_back_with_duplicate ( duplicate) ?;
275
+ } else {
276
+ block_cache. write_back ( ) ?;
277
+ }
263
278
Ok ( ( ) )
264
279
}
265
280
@@ -995,7 +1010,9 @@ impl FatVolume {
995
1010
}
996
1011
Err ( e) => return Err ( e) ,
997
1012
} ;
1013
+ // This new cluster is the end of the file's chain
998
1014
self . update_fat ( block_cache, new_cluster, ClusterId :: END_OF_FILE ) ?;
1015
+ // If there's something before this new one, update the FAT to point it at us
999
1016
if let Some ( cluster) = prev_cluster {
1000
1017
trace ! (
1001
1018
"Updating old cluster {:?} to {:?} in FAT" ,
@@ -1132,6 +1149,12 @@ where
1132
1149
trace ! ( "Reading BPB" ) ;
1133
1150
let block = block_cache. read ( lba_start) . map_err ( Error :: DeviceError ) ?;
1134
1151
let bpb = Bpb :: create_from_bytes ( block) . map_err ( Error :: FormatError ) ?;
1152
+ let fat_start = BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ;
1153
+ let second_fat_start = if bpb. num_fats ( ) == 2 {
1154
+ Some ( fat_start + BlockCount ( bpb. fat_size ( ) ) )
1155
+ } else {
1156
+ None
1157
+ } ;
1135
1158
match bpb. fat_type {
1136
1159
FatType :: Fat16 => {
1137
1160
if bpb. bytes_per_block ( ) as usize != Block :: LEN {
@@ -1141,7 +1164,6 @@ where
1141
1164
let root_dir_blocks = ( ( u32:: from ( bpb. root_entries_count ( ) ) * OnDiskDirEntry :: LEN_U32 )
1142
1165
+ ( Block :: LEN_U32 - 1 ) )
1143
1166
/ Block :: LEN_U32 ;
1144
- let fat_start = BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ;
1145
1167
let first_root_dir_block =
1146
1168
fat_start + BlockCount ( u32:: from ( bpb. num_fats ( ) ) * bpb. fat_size ( ) ) ;
1147
1169
let first_data_block = first_root_dir_block + BlockCount ( root_dir_blocks) ;
@@ -1152,8 +1174,9 @@ where
1152
1174
contents : bpb. volume_label ( ) ,
1153
1175
} ,
1154
1176
blocks_per_cluster : bpb. blocks_per_cluster ( ) ,
1155
- first_data_block : ( first_data_block) ,
1156
- fat_start : BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ,
1177
+ first_data_block,
1178
+ fat_start,
1179
+ second_fat_start,
1157
1180
free_clusters_count : None ,
1158
1181
next_free_cluster : None ,
1159
1182
cluster_count : bpb. total_clusters ( ) ,
@@ -1166,9 +1189,8 @@ where
1166
1189
}
1167
1190
FatType :: Fat32 => {
1168
1191
// FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz);
1169
- let first_data_block = u32:: from ( bpb. reserved_block_count ( ) )
1170
- + ( u32:: from ( bpb. num_fats ( ) ) * bpb. fat_size ( ) ) ;
1171
-
1192
+ let first_data_block =
1193
+ fat_start + BlockCount ( u32:: from ( bpb. num_fats ( ) ) * bpb. fat_size ( ) ) ;
1172
1194
// Safe to unwrap since this is a Fat32 Type
1173
1195
let info_location = bpb. fs_info_block ( ) . unwrap ( ) ;
1174
1196
let mut volume = FatVolume {
@@ -1178,8 +1200,9 @@ where
1178
1200
contents : bpb. volume_label ( ) ,
1179
1201
} ,
1180
1202
blocks_per_cluster : bpb. blocks_per_cluster ( ) ,
1181
- first_data_block : BlockCount ( first_data_block) ,
1182
- fat_start : BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ,
1203
+ first_data_block,
1204
+ fat_start,
1205
+ second_fat_start,
1183
1206
free_clusters_count : None ,
1184
1207
next_free_cluster : None ,
1185
1208
cluster_count : bpb. total_clusters ( ) ,
0 commit comments