@@ -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
@@ -1106,7 +1121,9 @@ impl FatVolume {
1106
1121
}
1107
1122
Err ( e) => return Err ( e) ,
1108
1123
} ;
1124
+ // This new cluster is the end of the file's chain
1109
1125
self . update_fat ( block_cache, new_cluster, ClusterId :: END_OF_FILE ) ?;
1126
+ // If there's something before this new one, update the FAT to point it at us
1110
1127
if let Some ( cluster) = prev_cluster {
1111
1128
trace ! (
1112
1129
"Updating old cluster {:?} to {:?} in FAT" ,
@@ -1136,6 +1153,7 @@ impl FatVolume {
1136
1153
Err ( e) => return Err ( e) ,
1137
1154
} ;
1138
1155
debug ! ( "Next free cluster is {:?}" , self . next_free_cluster) ;
1156
+ // Record that we've allocated a cluster
1139
1157
if let Some ( ref mut number_free_cluster) = self . free_clusters_count {
1140
1158
* number_free_cluster -= 1 ;
1141
1159
} ;
@@ -1243,6 +1261,12 @@ where
1243
1261
trace ! ( "Reading BPB" ) ;
1244
1262
let block = block_cache. read ( lba_start) . map_err ( Error :: DeviceError ) ?;
1245
1263
let bpb = Bpb :: create_from_bytes ( block) . map_err ( Error :: FormatError ) ?;
1264
+ let fat_start = BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ;
1265
+ let second_fat_start = if bpb. num_fats ( ) == 2 {
1266
+ Some ( fat_start + BlockCount ( bpb. fat_size ( ) ) )
1267
+ } else {
1268
+ None
1269
+ } ;
1246
1270
match bpb. fat_type {
1247
1271
FatType :: Fat16 => {
1248
1272
if bpb. bytes_per_block ( ) as usize != Block :: LEN {
@@ -1252,7 +1276,6 @@ where
1252
1276
let root_dir_blocks = ( ( u32:: from ( bpb. root_entries_count ( ) ) * OnDiskDirEntry :: LEN_U32 )
1253
1277
+ ( Block :: LEN_U32 - 1 ) )
1254
1278
/ Block :: LEN_U32 ;
1255
- let fat_start = BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ;
1256
1279
let first_root_dir_block =
1257
1280
fat_start + BlockCount ( u32:: from ( bpb. num_fats ( ) ) * bpb. fat_size ( ) ) ;
1258
1281
let first_data_block = first_root_dir_block + BlockCount ( root_dir_blocks) ;
@@ -1263,8 +1286,9 @@ where
1263
1286
contents : bpb. volume_label ( ) ,
1264
1287
} ,
1265
1288
blocks_per_cluster : bpb. blocks_per_cluster ( ) ,
1266
- first_data_block : ( first_data_block) ,
1267
- fat_start : BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ,
1289
+ first_data_block,
1290
+ fat_start,
1291
+ second_fat_start,
1268
1292
free_clusters_count : None ,
1269
1293
next_free_cluster : None ,
1270
1294
cluster_count : bpb. total_clusters ( ) ,
@@ -1277,9 +1301,8 @@ where
1277
1301
}
1278
1302
FatType :: Fat32 => {
1279
1303
// FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz);
1280
- let first_data_block = u32:: from ( bpb. reserved_block_count ( ) )
1281
- + ( u32:: from ( bpb. num_fats ( ) ) * bpb. fat_size ( ) ) ;
1282
-
1304
+ let first_data_block =
1305
+ fat_start + BlockCount ( u32:: from ( bpb. num_fats ( ) ) * bpb. fat_size ( ) ) ;
1283
1306
// Safe to unwrap since this is a Fat32 Type
1284
1307
let info_location = bpb. fs_info_block ( ) . unwrap ( ) ;
1285
1308
let mut volume = FatVolume {
@@ -1289,8 +1312,9 @@ where
1289
1312
contents : bpb. volume_label ( ) ,
1290
1313
} ,
1291
1314
blocks_per_cluster : bpb. blocks_per_cluster ( ) ,
1292
- first_data_block : BlockCount ( first_data_block) ,
1293
- fat_start : BlockCount ( u32:: from ( bpb. reserved_block_count ( ) ) ) ,
1315
+ first_data_block,
1316
+ fat_start,
1317
+ second_fat_start,
1294
1318
free_clusters_count : None ,
1295
1319
next_free_cluster : None ,
1296
1320
cluster_count : bpb. total_clusters ( ) ,
0 commit comments