ext2: Simplify block cache
The original idea to additionally speed up the block mapping procedures
would need more complex code. And it would help in special cases (uncom-
mon block sizes) anyway. So we use a rather simple strategy: Cache at
most a single block of file contents, a single inode block and a single
group block. All other potentially available cache space would be used
for the block mapping.
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index 3c8578b..cfd3e0d 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -162,8 +162,6 @@
Cache : in out Block_Cache;
Phys : in FSBlock_Offset;
Level : in Block_Cache_Index;
- Label : in Cache_Label;
- Logical : in Boolean := True;
Cache_Start : out Max_Block_Index;
Cache_End : out Max_Block_Index;
Success : out Boolean)
@@ -176,9 +174,7 @@
begin
Cache_Start := Cache_Level * Static.Block_Size;
Cache_End := Cache_Start + Static.Block_Size - 1;
- if Cache.Logical (Cache_Level) = Logical and
- Cache.Label (Cache_Level) = Label
- then
+ if Cache.Phys (Cache_Level) = Phys then
Success := True;
else
Read_FSBlock
@@ -186,37 +182,10 @@
FSBlock => Phys,
Part_Len => Static.Part_Len,
Success => Success);
- Cache.Logical (Cache_Level) := Logical; -- FIXME: Level needs to be part of Label
- Cache.Label (Cache_Level) := Label;
+ Cache.Phys (Cache_Level) := Phys;
end if;
end Cache_FSBlock;
- procedure Cache_FSBlock
- (Static : in Mount_State;
- Cache : in out Block_Cache;
- 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 + Static.Block_Size - 1
- is
- begin
- Cache_FSBlock (Static, Cache, Phys, Level, Cache_Label (Phys),
- False, Cache_Start, Cache_End, Success);
- end Cache_FSBlock;
-
- procedure Reset_Cache_Logical (Cache : in out Block_Cache) is
- begin
- for I in Block_Cache_Index loop
- if Cache.Logical (I) then
- Cache.Logical (I) := False;
- Cache.Label (I) := 0;
- end if;
- end loop;
- end Reset_Cache_Logical;
-
procedure Ext2_Block_Map
(State : in out T;
Logical : in FSBlock_Logical;
@@ -248,7 +217,6 @@
(Indirect_Block_Phys : in FSBlock_Offset;
Addr_In_Block : in Addr_In_Block_Range;
Level : in Block_Cache_Index;
- Logical_Off : in FSBlock_Logical;
Next_Physical : out FSBlock_Offset;
Success : out Boolean)
with
@@ -264,7 +232,6 @@
Cache => State.Cache,
Phys => Indirect_Block_Phys,
Level => Level,
- Label => Cache_Label (Logical_Off),
Cache_Start => Cache_Start,
Cache_End => Cache_End,
Success => Success);
@@ -288,8 +255,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => FSBlock_Offset (I_Blocks (State).Indirect_Block),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest),
- Level => 0,
- Logical_Off => Logical - Logical_Rest,
+ Level => Block_Map_Cache_Level,
Next_Physical => Physical,
Success => Success);
return;
@@ -300,8 +266,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => FSBlock_Offset (I_Blocks (State).Double_Indirect),
Addr_In_Block => Addr_In_Block_Range ((Logical_Rest / Addr_Per_Block) mod Addr_Per_Block),
- Level => 1,
- Logical_Off => Logical - Logical_Rest,
+ Level => Block_Map_Cache_Level + 1,
Next_Physical => Physical,
Success => Success);
if not Success then
@@ -311,8 +276,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => Physical,
Addr_In_Block => Addr_In_Block_Range (Logical_Rest mod Addr_Per_Block),
- Level => 0,
- Logical_Off => Logical - (Logical_Rest mod Addr_Per_Block),
+ Level => Block_Map_Cache_Level,
Next_Physical => Physical,
Success => Success);
return;
@@ -323,8 +287,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => FSBlock_Offset (I_Blocks (State).Triple_Indirect),
Addr_In_Block => Addr_In_Block_Range ((Logical_Rest / Addr_Per_Block ** 2) mod Addr_Per_Block),
- Level => 2,
- Logical_Off => Logical - Logical_Rest,
+ Level => Block_Map_Cache_Level + 2,
Next_Physical => Physical,
Success => Success);
if not Success then
@@ -334,8 +297,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 => 1,
- Logical_Off => Logical - (Logical_Rest mod Addr_Per_Block ** 2),
+ Level => Block_Map_Cache_Level + 1,
Next_Physical => Physical,
Success => Success);
if not Success then
@@ -345,8 +307,7 @@
Indirect_Block_Lookup
(Indirect_Block_Phys => Physical,
Addr_In_Block => Addr_In_Block_Range (Logical_Rest mod Addr_Per_Block),
- Level => 0,
- Logical_Off => Logical - (Logical_Rest mod Addr_Per_Block),
+ Level => Block_Map_Cache_Level,
Next_Physical => Physical,
Success => Success);
return;
@@ -509,8 +470,7 @@
(Static => State.Static,
Cache => State.Cache,
Phys => Current,
- Level => Depth,
- Label => Cache_Label (Logical_Off),
+ Level => Block_Map_Cache_Level + Depth,
Cache_Start => Cache_Start,
Cache_End => Cache_End,
Success => Success);
@@ -716,8 +676,7 @@
(Static => Static,
Cache => State.Cache,
Phys => Group_Block,
- Level => Natural (Group_Index'Min (Group / Static.Group_Desc_Per_Block,
- Group_Index (Block_Cache_Index'Last))),
+ Level => Group_Cache_Level,
Cache_Start => Cache_Start,
Cache_End => Cache_End,
Success => Success);
@@ -757,7 +716,7 @@
(Static => Static,
Cache => State.Cache,
Phys => FSBlock_Offset (First_Table_Block + Inode_Block),
- Level => Block_Cache_Index'Last,
+ Level => Inode_Cache_Level,
Cache_Start => Cache_Start,
Cache_End => Cache_End,
Success => Success);
@@ -777,7 +736,6 @@
if Success then
State.Inode.I := Inode;
- Reset_Cache_Logical (State.Cache);
State.S := File_Opened;
end if;
end;
@@ -990,7 +948,7 @@
(Static => Static,
Cache => State.Cache,
Phys => Physical,
- Level => Block_Cache_Index'Last,
+ Level => File_Cache_Level,
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 1757da8..8e64a5d 100644
--- a/src/filo-fs-ext2.ads
+++ b/src/filo-fs-ext2.ads
@@ -56,13 +56,13 @@
-- 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. Otherwise, we use their physical offset.
- type Cache_Label is new Unsigned_64;
subtype Block_Cache_Index is Natural range 0 .. 63;
- type Cache_Label_Logical is array (Block_Cache_Index) of Boolean;
- type Cache_Label_Array is array (Block_Cache_Index) of Cache_Label;
+ File_Cache_Level : constant := 0; -- Use a single cache block each for
+ Inode_Cache_Level : constant := 1; -- file contents, the inode block,
+ Group_Cache_Level : constant := 2; -- the group block.
+ Block_Map_Cache_Level : constant := 3; -- Use all other cache blocks for
+ -- mapping file content blocks.
+ type Cache_Label is array (Block_Cache_Index) of FSBlock_Offset;
subtype Cache_Buffer is Buffer_Type (Max_Block_Index);
-- Same as the 12 direct + 3 indirect blocks times 4B:
@@ -114,8 +114,7 @@
end record;
type Block_Cache is record
- Logical : Cache_Label_Logical := (others => False);
- Label : Cache_Label_Array := (others => 0);
+ Phys : Cache_Label := (others => 0);
Buffer : Cache_Buffer := (others => 16#00#);
end record;