@@ -360,27 +360,36 @@ where
360
360
dirty : bool ,
361
361
) -> Result < ( ) , Error < D :: Error > > {
362
362
let mut blocks = [ Block :: new ( ) ] ;
363
- self . block_device . read (
364
- & mut blocks,
365
- volume. lba_start + volume. fat_start ,
366
- "reading fat table" ,
367
- ) ?;
363
+ let fat_table1_start = volume. lba_start + volume. fat_start ;
364
+ self . block_device
365
+ . read ( & mut blocks, fat_table1_start, "reading fat table" ) ?;
368
366
let block = & mut blocks[ 0 ] ;
369
367
let mut fat_table =
370
368
fat:: FatTable :: create_from_bytes ( & mut block. contents , volume. get_fat_type ( ) )
371
369
. map_err ( Error :: FormatError ) ?;
372
370
fat_table. set_dirty ( dirty) ;
373
- let fat_table_start = volume. lba_start + volume. fat_start ;
374
371
if volume. fat_nums == 1 || volume. fat_nums == 2 {
375
- self . block_device . write ( & blocks, fat_table_start ) ?;
372
+ self . block_device . write ( & blocks, fat_table1_start ) ?;
376
373
// Synchronize also backup fat table
377
374
if volume. fat_nums == 2 {
378
375
self . block_device
379
- . write ( & blocks, fat_table_start + volume. fat_size ) ?
376
+ . write ( & blocks, fat_table1_start + volume. fat_size ) ?
380
377
}
381
378
}
382
379
Ok ( ( ) )
383
380
}
381
+ #[ cfg( test) ]
382
+ fn volume_status_dirty ( & self , volume : & FatVolume ) -> Result < bool , Error < D :: Error > > {
383
+ let mut blocks = [ Block :: new ( ) ] ;
384
+ let fat_table1_start = volume. lba_start + volume. fat_start ;
385
+ self . block_device
386
+ . read ( & mut blocks, fat_table1_start, "reading fat table" ) ?;
387
+ let block = & mut blocks[ 0 ] ;
388
+ let fat_table =
389
+ fat:: FatTable :: create_from_bytes ( & mut block. contents , volume. get_fat_type ( ) )
390
+ . map_err ( Error :: FormatError ) ?;
391
+ Ok ( fat_table. dirty ( ) )
392
+ }
384
393
385
394
/// Look in a directory for a named file.
386
395
pub fn find_directory_entry < N > (
@@ -1169,6 +1178,7 @@ mod tests {
1169
1178
use super :: * ;
1170
1179
use crate :: filesystem:: SearchId ;
1171
1180
use crate :: Timestamp ;
1181
+ use crate :: VolumeType ;
1172
1182
1173
1183
struct DummyBlockDevice ;
1174
1184
@@ -1204,7 +1214,8 @@ mod tests {
1204
1214
_reason : & str ,
1205
1215
) -> Result < ( ) , Self :: Error > {
1206
1216
// Actual blocks taken from an SD card, except I've changed the start and length of partition 0.
1207
- static BLOCKS : [ Block ; 3 ] = [
1217
+ static BLOCKS : [ Block ; 4 ] = [
1218
+ // Block 0: MBR
1208
1219
Block {
1209
1220
contents : [
1210
1221
0xfa , 0xb8 , 0x00 , 0x10 , 0x8e , 0xd0 , 0xbc , 0x00 , 0xb0 , 0xb8 , 0x00 , 0x00 ,
@@ -1273,10 +1284,11 @@ mod tests {
1273
1284
0x00 , 0x00 , 0x55 , 0xaa , // 0x1F0
1274
1285
] ,
1275
1286
} ,
1287
+ // Block 1: Partition 0 Boot block
1276
1288
Block {
1277
1289
contents : [
1278
1290
0xeb , 0x58 , 0x90 , 0x6d , 0x6b , 0x66 , 0x73 , 0x2e , 0x66 , 0x61 , 0x74 , 0x00 ,
1279
- 0x02 , 0x08 , 0x20 , 0x00 , // 0x000
1291
+ 0x02 , 0x08 , 0x02 , 0x00 , // 0x000
1280
1292
0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0xf8 , 0x00 , 0x00 , 0x10 , 0x00 , 0x04 , 0x00 ,
1281
1293
0x00 , 0x08 , 0x00 , 0x00 , // 0x010
1282
1294
0x00 , 0x20 , 0x76 , 0x00 , 0x80 , 0x1d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
@@ -1341,6 +1353,7 @@ mod tests {
1341
1353
0x00 , 0x00 , 0x55 , 0xaa , // 0x1F0
1342
1354
] ,
1343
1355
} ,
1356
+ // Partition 0 info sector (BPB_FSInfo)
1344
1357
Block {
1345
1358
contents : hex ! (
1346
1359
"52 52 61 41 00 00 00 00 00 00 00 00 00 00 00 00
@@ -1377,6 +1390,75 @@ mod tests {
1377
1390
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA"
1378
1391
) ,
1379
1392
} ,
1393
+ // Partition 0 FAT table
1394
+ Block {
1395
+ contents : [
1396
+ 0xF0 , 0xFF , 0xFF , 0x0F , 0xFF , 0xFF , 0xFF , 0x0F , 0x00 , 0x00 , 0x00 , 0x00 ,
1397
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x000
1398
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1399
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x010
1400
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1401
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x020
1402
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1403
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x030
1404
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1405
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x040
1406
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1407
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x050
1408
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1409
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x060
1410
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1411
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x070
1412
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1413
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x080
1414
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1415
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x090
1416
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1417
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0A0
1418
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1419
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0B0
1420
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1421
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0C0
1422
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1423
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0D0
1424
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1425
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0E0
1426
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1427
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0F0
1428
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1429
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x100
1430
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1431
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x110
1432
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1433
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x120
1434
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1435
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x130
1436
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1437
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x140
1438
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1439
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x150
1440
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1441
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x160
1442
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1443
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x170
1444
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1445
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x180
1446
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1447
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x190
1448
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1449
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1A0
1450
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1451
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1B0
1452
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1453
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1C0
1454
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1455
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1D0
1456
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1457
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1E0
1458
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1459
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1F0
1460
+ ] ,
1461
+ } ,
1380
1462
] ;
1381
1463
println ! (
1382
1464
"Reading block {} to {}" ,
@@ -1410,31 +1492,36 @@ mod tests {
1410
1492
let mut c: VolumeManager < DummyBlockDevice , Clock , 2 , 2 > =
1411
1493
VolumeManager :: new_with_limits ( DummyBlockDevice , Clock , 0xAA00_0000 ) ;
1412
1494
1413
- let v = c. open_raw_volume ( VolumeIdx ( 0 ) ) . unwrap ( ) ;
1495
+ let v = c. open_raw_volume ( VolumeIdx ( 0 ) , false ) . unwrap ( ) ;
1414
1496
let expected_id = RawVolume ( SearchId ( 0xAA00_0000 ) ) ;
1415
1497
assert_eq ! ( v, expected_id) ;
1416
1498
assert_eq ! (
1417
1499
& c. open_volumes[ 0 ] ,
1418
1500
& VolumeInfo {
1419
1501
volume_id: expected_id,
1420
1502
idx: VolumeIdx ( 0 ) ,
1503
+ read_only: false ,
1421
1504
volume_type: VolumeType :: Fat ( crate :: FatVolume {
1422
1505
lba_start: BlockIdx ( 1 ) ,
1423
1506
num_blocks: BlockCount ( 0x0011_2233 ) ,
1424
1507
blocks_per_cluster: 8 ,
1425
- first_data_block: BlockCount ( 15136 ) ,
1426
- fat_start: BlockCount ( 32 ) ,
1508
+ first_data_block: BlockCount ( 15106 ) ,
1509
+ fat_start: BlockCount ( 2 ) ,
1510
+ fat_size: BlockCount ( 7552 ) ,
1511
+ fat_nums: 2 ,
1427
1512
name: fat:: VolumeName :: new( * b"Pictures " ) ,
1428
1513
free_clusters_count: None ,
1429
1514
next_free_cluster: None ,
1430
- cluster_count: 965_788 ,
1515
+ cluster_count: 965_791 ,
1431
1516
fat_specific_info: fat:: FatSpecificInfo :: Fat32 ( fat:: Fat32Info {
1432
1517
first_root_dir_cluster: ClusterId ( 2 ) ,
1433
1518
info_location: BlockIdx ( 1 ) + BlockCount ( 1 ) ,
1434
1519
} )
1435
1520
} )
1436
1521
}
1437
1522
) ;
1523
+ let VolumeType :: Fat ( fat_info) = & c. open_volumes [ 0 ] . volume_type ;
1524
+ assert_eq ! ( c. volume_status_dirty( fat_info) . unwrap( ) , false ) ;
1438
1525
}
1439
1526
}
1440
1527
0 commit comments