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;