ext2: Use a more generic cache index
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index aeff958..46cd4cc 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -169,19 +169,18 @@
with
Pre => FSBlock_Logical (Addr_In_Block) < Addr_Per_Block
is
- -- Limit cache usage in case of incredibly huge block size:
+ -- Limit cache usage depending on block size:
+ Max_Level : constant Block_Cache_Index :=
+ 2 ** (Log_Block_Size'Last - State.Block_Size_Bits) - 1;
Cache_Level : constant Block_Cache_Index :=
- (if State.Block_Size_Bits > 15 then Any
- elsif State.Block_Size_Bits > 14 and Level > Any then Last_Level
- else Level);
- Cache_Index : constant Index_Type :=
- Block_Cache_Index'Pos (Cache_Level) * Block_Size;
- Cache_End : constant Index_Type := Cache_Index + Block_Size - 1;
+ Block_Cache_Index'Min (Level, Max_Level);
+ Cache_Start : constant Index_Type := Cache_Level * Block_Size;
+ Cache_End : constant Index_Type := Cache_Start + Block_Size - 1;
begin
if State.Block_Cache_Index (Cache_Level) /= Logical_Off then
Read_FSBlock
(State => State,
- Buf => State.Block_Cache (Cache_Index .. Cache_End),
+ Buf => State.Block_Cache (Cache_Start .. Cache_End),
FSBlock => Indirect_Block_Phys,
Success => Success);
State.Block_Cache_Index (Cache_Level) := Logical_Off;
@@ -191,7 +190,7 @@
end if;
Next_Physical := FSBlock_Offset (Read_LE32
- (Buf => State.Block_Cache (Cache_Index .. Cache_End),
+ (Buf => State.Block_Cache (Cache_Start .. Cache_End),
Off => Natural (Addr_In_Block) * 4));
Success := True;
end Indirect_Block_Lookup;
@@ -209,7 +208,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => FSBlock_Offset (State.Indirect_Block),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest),
- Level => Last_Level,
+ Level => 0,
Logical_Off => Logical - Logical_Rest,
Next_Physical => Physical,
Success => Success);
@@ -221,7 +220,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => FSBlock_Offset (State.Double_Indirect),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest / Addr_Per_Block),
- Level => Second_Last_Level,
+ Level => 1,
Logical_Off => Logical - Logical_Rest,
Next_Physical => Physical,
Success => Success);
@@ -232,7 +231,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => Physical,
Addr_In_Block => Addr_In_Block_Range (Logical_Rest mod Addr_Per_Block),
- Level => Last_Level,
+ Level => 0,
Logical_Off => Logical - (Logical_Rest mod Addr_Per_Block),
Next_Physical => Physical,
Success => Success);
@@ -244,7 +243,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => FSBlock_Offset (State.Triple_Indirect),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest / Addr_Per_Block ** 2),
- Level => First_Level,
+ Level => 2,
Logical_Off => Logical - Logical_Rest,
Next_Physical => Physical,
Success => Success);
@@ -255,7 +254,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => Physical,
Addr_In_Block => Addr_In_Block_Range (Logical_Rest / Addr_Per_Block mod Addr_Per_Block),
- Level => Second_Last_Level,
+ Level => 1,
Logical_Off => Logical - (Logical_Rest mod Addr_Per_Block ** 2),
Next_Physical => Physical,
Success => Success);
@@ -266,7 +265,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => Physical,
Addr_In_Block => Addr_In_Block_Range (Logical_Rest mod Addr_Per_Block),
- Level => Last_Level,
+ Level => 0,
Logical_Off => Logical - (Logical_Rest mod Addr_Per_Block),
Next_Physical => Physical,
Success => Success);
diff --git a/src/filo-fs-ext2.ads b/src/filo-fs-ext2.ads
index 96bd102..90c1ae6 100644
--- a/src/filo-fs-ext2.ads
+++ b/src/filo-fs-ext2.ads
@@ -50,15 +50,13 @@
type FSBlock_Offset is new Block_Offset range 0 .. Block_Offset'Last / 2;
type FSBlock_Logical is new Block_Offset range 0 .. Block_Offset'Last / 2;
- -- We use a 64KiB cache.
- -- * If that's the block size, only the `Any` entry is used.
- -- * For a 32KiB block size, `Any` and `Last_Level` (for indirect block
- -- lookups) are used.
- -- * For smaller block sizes, the most common case, we cache four blocks.
- -- For the `Any` entry, we note the logical block address (block offset
- -- within a file). For the indirect entries, we note the *first* logical
- -- block that they map.
- type Block_Cache_Index is (Any, Last_Level, Second_Last_Level, First_Level);
+ -- We use a 64KiB cache which fits at least one ext2 block. If a lower
+ -- block size is encountered (likely), we partition the cache into up
+ -- 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.
+ subtype Block_Cache_Index is Natural range 0 .. 63;
type Block_Cache_Type is array (Block_Cache_Index) of FSBlock_Logical;
Direct_Blocks : constant := 12;