@@ -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 > (
@@ -1186,6 +1195,7 @@ mod tests {
1186
1195
use super :: * ;
1187
1196
use crate :: filesystem:: SearchId ;
1188
1197
use crate :: Timestamp ;
1198
+ use crate :: VolumeType ;
1189
1199
1190
1200
struct DummyBlockDevice ;
1191
1201
@@ -1221,7 +1231,8 @@ mod tests {
1221
1231
_reason : & str ,
1222
1232
) -> Result < ( ) , Self :: Error > {
1223
1233
// Actual blocks taken from an SD card, except I've changed the start and length of partition 0.
1224
- static BLOCKS : [ Block ; 3 ] = [
1234
+ static BLOCKS : [ Block ; 4 ] = [
1235
+ // Block 0: MBR
1225
1236
Block {
1226
1237
contents : [
1227
1238
0xfa , 0xb8 , 0x00 , 0x10 , 0x8e , 0xd0 , 0xbc , 0x00 , 0xb0 , 0xb8 , 0x00 , 0x00 ,
@@ -1290,10 +1301,11 @@ mod tests {
1290
1301
0x00 , 0x00 , 0x55 , 0xaa , // 0x1F0
1291
1302
] ,
1292
1303
} ,
1304
+ // Block 1: Partition 0 Boot block
1293
1305
Block {
1294
1306
contents : [
1295
1307
0xeb , 0x58 , 0x90 , 0x6d , 0x6b , 0x66 , 0x73 , 0x2e , 0x66 , 0x61 , 0x74 , 0x00 ,
1296
- 0x02 , 0x08 , 0x20 , 0x00 , // 0x000
1308
+ 0x02 , 0x08 , 0x02 , 0x00 , // 0x000
1297
1309
0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0xf8 , 0x00 , 0x00 , 0x10 , 0x00 , 0x04 , 0x00 ,
1298
1310
0x00 , 0x08 , 0x00 , 0x00 , // 0x010
1299
1311
0x00 , 0x20 , 0x76 , 0x00 , 0x80 , 0x1d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
@@ -1358,6 +1370,7 @@ mod tests {
1358
1370
0x00 , 0x00 , 0x55 , 0xaa , // 0x1F0
1359
1371
] ,
1360
1372
} ,
1373
+ // Partition 0 info sector (BPB_FSInfo)
1361
1374
Block {
1362
1375
contents : hex ! (
1363
1376
"52 52 61 41 00 00 00 00 00 00 00 00 00 00 00 00
@@ -1394,6 +1407,75 @@ mod tests {
1394
1407
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA"
1395
1408
) ,
1396
1409
} ,
1410
+ // Partition 0 FAT table
1411
+ Block {
1412
+ contents : [
1413
+ 0xF0 , 0xFF , 0xFF , 0x0F , 0xFF , 0xFF , 0xFF , 0x0F , 0x00 , 0x00 , 0x00 , 0x00 ,
1414
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x000
1415
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1416
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x010
1417
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1418
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x020
1419
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1420
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x030
1421
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1422
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x040
1423
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1424
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x050
1425
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1426
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x060
1427
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1428
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x070
1429
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1430
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x080
1431
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1432
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x090
1433
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1434
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0A0
1435
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1436
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0B0
1437
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1438
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0C0
1439
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1440
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0D0
1441
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1442
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0E0
1443
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1444
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x0F0
1445
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1446
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x100
1447
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1448
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x110
1449
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1450
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x120
1451
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1452
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x130
1453
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1454
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x140
1455
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1456
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x150
1457
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1458
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x160
1459
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1460
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x170
1461
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1462
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x180
1463
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1464
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x190
1465
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1466
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1A0
1467
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1468
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1B0
1469
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1470
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1C0
1471
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1472
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1D0
1473
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1474
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1E0
1475
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
1476
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x1F0
1477
+ ] ,
1478
+ } ,
1397
1479
] ;
1398
1480
println ! (
1399
1481
"Reading block {} to {}" ,
@@ -1427,31 +1509,36 @@ mod tests {
1427
1509
let mut c: VolumeManager < DummyBlockDevice , Clock , 2 , 2 > =
1428
1510
VolumeManager :: new_with_limits ( DummyBlockDevice , Clock , 0xAA00_0000 ) ;
1429
1511
1430
- let v = c. open_raw_volume ( VolumeIdx ( 0 ) ) . unwrap ( ) ;
1512
+ let v = c. open_raw_volume ( VolumeIdx ( 0 ) , false ) . unwrap ( ) ;
1431
1513
let expected_id = RawVolume ( SearchId ( 0xAA00_0000 ) ) ;
1432
1514
assert_eq ! ( v, expected_id) ;
1433
1515
assert_eq ! (
1434
1516
& c. open_volumes[ 0 ] ,
1435
1517
& VolumeInfo {
1436
1518
volume_id: expected_id,
1437
1519
idx: VolumeIdx ( 0 ) ,
1520
+ read_only: false ,
1438
1521
volume_type: VolumeType :: Fat ( crate :: FatVolume {
1439
1522
lba_start: BlockIdx ( 1 ) ,
1440
1523
num_blocks: BlockCount ( 0x0011_2233 ) ,
1441
1524
blocks_per_cluster: 8 ,
1442
- first_data_block: BlockCount ( 15136 ) ,
1443
- fat_start: BlockCount ( 32 ) ,
1525
+ first_data_block: BlockCount ( 15106 ) ,
1526
+ fat_start: BlockCount ( 2 ) ,
1527
+ fat_size: BlockCount ( 7552 ) ,
1528
+ fat_nums: 2 ,
1444
1529
name: fat:: VolumeName :: new( * b"Pictures " ) ,
1445
1530
free_clusters_count: None ,
1446
1531
next_free_cluster: None ,
1447
- cluster_count: 965_788 ,
1532
+ cluster_count: 965_791 ,
1448
1533
fat_specific_info: fat:: FatSpecificInfo :: Fat32 ( fat:: Fat32Info {
1449
1534
first_root_dir_cluster: ClusterId ( 2 ) ,
1450
1535
info_location: BlockIdx ( 1 ) + BlockCount ( 1 ) ,
1451
1536
} )
1452
1537
} )
1453
1538
}
1454
1539
) ;
1540
+ let VolumeType :: Fat ( fat_info) = & c. open_volumes [ 0 ] . volume_type ;
1541
+ assert_eq ! ( c. volume_status_dirty( fat_info) . unwrap( ) , false ) ;
1455
1542
}
1456
1543
}
1457
1544
0 commit comments