ext2: Distinguish physical (always valid) and logical (per file) cached blocks
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index 32a16c3..1a151b9 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -155,7 +155,8 @@
(State : in out T;
Phys : in FSBlock_Offset;
Level : in Block_Cache_Index;
- Logical_Off : in FSBlock_Logical;
+ Label : in Cache_Label;
+ Logical : in Boolean := True;
Cache_Start : out Max_Block_Index;
Cache_End : out Max_Block_Index;
Success : out Boolean)
@@ -171,7 +172,9 @@
begin
Cache_Start := Cache_Level * Block_Size;
Cache_End := Cache_Start + Block_Size - 1;
- if State.Block_Cache_Index (Cache_Level) = Logical_Off then
+ if State.Block_Cache_Logical (Cache_Level) = Logical and
+ State.Block_Cache_Label (Cache_Level) = Label
+ then
Success := True;
else
Read_FSBlock
@@ -179,10 +182,36 @@
Buf => State.Block_Cache (Cache_Start .. Cache_End),
FSBlock => Phys,
Success => Success);
- State.Block_Cache_Index (Cache_Level) := Logical_Off;
+ State.Block_Cache_Logical (Cache_Level) := Logical;
+ State.Block_Cache_Label (Cache_Level) := Label;
end if;
end Cache_FSBlock;
+ procedure Cache_FSBlock
+ (State : in out T;
+ Phys : in FSBlock_Offset;
+ Level : in Block_Cache_Index;
+ Cache_Start : out Max_Block_Index;
+ Cache_End : out Max_Block_Index;
+ Success : out Boolean)
+ with
+ Post => Cache_End = Cache_Start + 2 ** State.Block_Size_Bits
+ is
+ begin
+ Cache_FSBlock (State, Phys, Level, Cache_Label (Phys),
+ False, Cache_Start, Cache_End, Success);
+ end Cache_FSBlock;
+
+ procedure Reset_Cache_Logical (State : in out T) is
+ begin
+ for I in Block_Cache_Index loop
+ if State.Block_Cache_Logical (I) then
+ State.Block_Cache_Logical (I) := False;
+ State.Block_Cache_Label (I) := 0;
+ end if;
+ end loop;
+ end Reset_Cache_Logical;
+
procedure Ext2_Block_Map
(State : in out T;
Logical : in FSBlock_Logical;
@@ -223,7 +252,7 @@
(State => State,
Phys => Indirect_Block_Phys,
Level => Level,
- Logical_Off => Logical_Off,
+ Label => Cache_Label (Logical_Off),
Cache_Start => Cache_Start,
Cache_End => Cache_End,
Success => Success);
@@ -448,7 +477,7 @@
(State => State,
Phys => Current,
Level => Depth,
- Logical_Off => Logical_Off,
+ Label => Cache_Label (Logical_Off),
Cache_Start => Cache_Start,
Cache_End => Cache_End,
Success => Success);
diff --git a/src/filo-fs-ext2.ads b/src/filo-fs-ext2.ads
index b1f1544..fbe6a35 100644
--- a/src/filo-fs-ext2.ads
+++ b/src/filo-fs-ext2.ads
@@ -55,9 +55,11 @@
-- to 64 1KiB blocks.
-- Cache entries can be used for blocks that map logical block offets
-- to physical ones. Then we note the first logical block offset mapped
- -- by the cached block.
+ -- by the cached block. Otherwise, we use their physical offset.
+ type Cache_Label is new Unsigned_64;
subtype Block_Cache_Index is Natural range 0 .. 63;
- type Block_Cache_Type is array (Block_Cache_Index) of FSBlock_Logical;
+ type Cache_Label_Logical is array (Block_Cache_Index) of Boolean;
+ type Cache_Label_Array is array (Block_Cache_Index) of Cache_Label;
-- Same as the 12 direct + 3 indirect blocks times 4B:
subtype Inode_Extents_Index is Natural range 0 .. 59;
@@ -72,17 +74,18 @@
type T is record
S : State;
- Part_Len : Partition_Length := 0;
- First_Data_Block : FSBlock_Offset := 0;
- Block_Size_Bits : Log_Block_Size := 10;
- Inodes_Per_Group : Positive := 1;
- Inode_Size : Ext2.Inode_Size := Ext2.Inode_Size'First;
- Desc_Size : Ext2.Desc_Size := Ext2.Desc_Size'First;
- Feature_Extents : Boolean := False;
- Feature_64Bit : Boolean := False;
- Inode : Inode_Info := (others => <>);
- Block_Cache_Index : Block_Cache_Type := (others => 0);
- Block_Cache : Buffer_Type (Max_Block_Index) := (others => 16#00#);
+ Part_Len : Partition_Length := 0;
+ First_Data_Block : FSBlock_Offset := 0;
+ Block_Size_Bits : Log_Block_Size := 10;
+ Inodes_Per_Group : Positive := 1;
+ Inode_Size : Ext2.Inode_Size := Ext2.Inode_Size'First;
+ Desc_Size : Ext2.Desc_Size := Ext2.Desc_Size'First;
+ Feature_Extents : Boolean := False;
+ Feature_64Bit : Boolean := False;
+ Inode : Inode_Info := (others => <>);
+ Block_Cache_Logical : Cache_Label_Logical := (others => False);
+ Block_Cache_Label : Cache_Label_Array := (others => 0);
+ Block_Cache : Buffer_Type (Max_Block_Index) := (others => 16#00#);
end record;
end FILO.FS.Ext2;