@@ -360,27 +360,36 @@ where
360360 dirty : bool ,
361361 ) -> Result < ( ) , Error < D :: Error > > {
362362 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" ) ?;
368366 let block = & mut blocks[ 0 ] ;
369367 let mut fat_table =
370368 fat:: FatTable :: create_from_bytes ( & mut block. contents , volume. get_fat_type ( ) )
371369 . map_err ( Error :: FormatError ) ?;
372370 fat_table. set_dirty ( dirty) ;
373- let fat_table_start = volume. lba_start + volume. fat_start ;
374371 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 ) ?;
376373 // Synchronize also backup fat table
377374 if volume. fat_nums == 2 {
378375 self . block_device
379- . write ( & blocks, fat_table_start + volume. fat_size ) ?
376+ . write ( & blocks, fat_table1_start + volume. fat_size ) ?
380377 }
381378 }
382379 Ok ( ( ) )
383380 }
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+ }
384393
385394 /// Look in a directory for a named file.
386395 pub fn find_directory_entry < N > (
@@ -1169,6 +1178,7 @@ mod tests {
11691178 use super :: * ;
11701179 use crate :: filesystem:: SearchId ;
11711180 use crate :: Timestamp ;
1181+ use crate :: VolumeType ;
11721182
11731183 struct DummyBlockDevice ;
11741184
@@ -1204,7 +1214,8 @@ mod tests {
12041214 _reason : & str ,
12051215 ) -> Result < ( ) , Self :: Error > {
12061216 // 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
12081219 Block {
12091220 contents : [
12101221 0xfa , 0xb8 , 0x00 , 0x10 , 0x8e , 0xd0 , 0xbc , 0x00 , 0xb0 , 0xb8 , 0x00 , 0x00 ,
@@ -1273,10 +1284,11 @@ mod tests {
12731284 0x00 , 0x00 , 0x55 , 0xaa , // 0x1F0
12741285 ] ,
12751286 } ,
1287+ // Block 1: Partition 0 Boot block
12761288 Block {
12771289 contents : [
12781290 0xeb , 0x58 , 0x90 , 0x6d , 0x6b , 0x66 , 0x73 , 0x2e , 0x66 , 0x61 , 0x74 , 0x00 ,
1279- 0x02 , 0x08 , 0x20 , 0x00 , // 0x000
1291+ 0x02 , 0x08 , 0x02 , 0x00 , // 0x000
12801292 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0xf8 , 0x00 , 0x00 , 0x10 , 0x00 , 0x04 , 0x00 ,
12811293 0x00 , 0x08 , 0x00 , 0x00 , // 0x010
12821294 0x00 , 0x20 , 0x76 , 0x00 , 0x80 , 0x1d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
@@ -1341,6 +1353,7 @@ mod tests {
13411353 0x00 , 0x00 , 0x55 , 0xaa , // 0x1F0
13421354 ] ,
13431355 } ,
1356+ // Partition 0 info sector (BPB_FSInfo)
13441357 Block {
13451358 contents : hex ! (
13461359 "52 52 61 41 00 00 00 00 00 00 00 00 00 00 00 00
@@ -1377,6 +1390,75 @@ mod tests {
13771390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA"
13781391 ) ,
13791392 } ,
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+ } ,
13801462 ] ;
13811463 println ! (
13821464 "Reading block {} to {}" ,
@@ -1410,31 +1492,36 @@ mod tests {
14101492 let mut c: VolumeManager < DummyBlockDevice , Clock , 2 , 2 > =
14111493 VolumeManager :: new_with_limits ( DummyBlockDevice , Clock , 0xAA00_0000 ) ;
14121494
1413- let v = c. open_raw_volume ( VolumeIdx ( 0 ) ) . unwrap ( ) ;
1495+ let v = c. open_raw_volume ( VolumeIdx ( 0 ) , false ) . unwrap ( ) ;
14141496 let expected_id = RawVolume ( SearchId ( 0xAA00_0000 ) ) ;
14151497 assert_eq ! ( v, expected_id) ;
14161498 assert_eq ! (
14171499 & c. open_volumes[ 0 ] ,
14181500 & VolumeInfo {
14191501 volume_id: expected_id,
14201502 idx: VolumeIdx ( 0 ) ,
1503+ read_only: false ,
14211504 volume_type: VolumeType :: Fat ( crate :: FatVolume {
14221505 lba_start: BlockIdx ( 1 ) ,
14231506 num_blocks: BlockCount ( 0x0011_2233 ) ,
14241507 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 ,
14271512 name: fat:: VolumeName :: new( * b"Pictures " ) ,
14281513 free_clusters_count: None ,
14291514 next_free_cluster: None ,
1430- cluster_count: 965_788 ,
1515+ cluster_count: 965_791 ,
14311516 fat_specific_info: fat:: FatSpecificInfo :: Fat32 ( fat:: Fat32Info {
14321517 first_root_dir_cluster: ClusterId ( 2 ) ,
14331518 info_location: BlockIdx ( 1 ) + BlockCount ( 1 ) ,
14341519 } )
14351520 } )
14361521 }
14371522 ) ;
1523+ let VolumeType :: Fat ( fat_info) = & c. open_volumes [ 0 ] . volume_type ;
1524+ assert_eq ! ( c. volume_status_dirty( fat_info) . unwrap( ) , false ) ;
14381525 }
14391526}
14401527
0 commit comments