ext2: Introduce State.Block_Size
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index ccc8b31..5f28c83 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -25,11 +25,10 @@
    --------------------------------------------------------------------------
 
    SUPERBLOCK_SIZE            : constant := 1024;
-   SUPERBLOCK_BLOCKS          : constant := SUPERBLOCK_SIZE / BLOCK_SIZE;
-
    SUPERBLOCK_MAGIC           : constant := 16#ef53#;
    OLD_REV                    : constant := 0;
    DYNAMIC_REV                : constant := 1;
+
    FEATURE_INCOMPAT_EXTENTS   : constant := 16#0040#;
    FEATURE_INCOMPAT_64BIT     : constant := 16#0080#;
 
@@ -65,6 +64,7 @@
       begin
          if S_Log_Block_Size <= Unsigned_32 (Log_Block_Size'Last - 10) then
             State.Block_Size_Bits := Log_Block_Size (S_Log_Block_Size + 10);
+            State.Block_Size := 2 ** Log_Block_Size (S_Log_Block_Size + 10);
          else
             Success := False;
             return;
@@ -112,9 +112,9 @@
             declare
                S_Desc_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 63 * 4 + 2);
             begin
-               if Is_Power_Of_2 (S_Desc_Size) and then
-                  S_Desc_Size in Unsigned_16 (Desc_Size'First) ..
-                  Unsigned_16 (Positive'Min (Desc_Size'Last, 2 ** State.Block_Size_Bits))
+               if Natural (S_Desc_Size) in Desc_Size and
+                  Natural (S_Desc_Size) <= State.Block_Size and
+                  Is_Power_Of_2 (S_Desc_Size)
                then
                   State.Desc_Size := Desc_Size (S_Desc_Size);
                else
@@ -132,24 +132,22 @@
    end Mount;
 
    procedure Read_FSBlock
-     (State    : in     T;
-      Buf      :    out Buffer_Type;
+     (Buf      : in out Buffer_Type;
       FSBlock  : in     FSBlock_Offset;
+      Part_Len : in     Partition_Length;
       Success  :    out Boolean)
    with
-      Pre =>
-         Is_Mounted (State) and
-         Buf'Length = 2 ** State.Block_Size_Bits
+      Pre => Buf'Length in Block_Size
    is
-      Block_Size : constant Blockdev_Length := 2 ** State.Block_Size_Bits;
-      Max_Block_Offset : constant FSBlock_Offset :=
-         FSBlock_Offset (State.Part_Len / Block_Size - 1);
+      FSBlock_64 : constant Integer_64 := Integer_64 (FSBlock);
+      Block_Size : constant Integer_64 := Integer_64 (Buf'Length);
+      Max_Block_Offset : constant Integer_64 := Integer_64 (Part_Len) / Block_Size - 1;
    begin
-      if FSBlock > Max_Block_Offset then
+      if FSBlock_64 > Max_Block_Offset then
          Success := False;
          return;
       end if;
-      Blockdev.Read (Buf, Blockdev_Length (FSBlock) * Block_Size, Success);
+      Blockdev.Read (Buf, Blockdev_Length (FSBlock_64 * Block_Size), Success);
    end Read_FSBlock;
 
    procedure Cache_FSBlock
@@ -162,26 +160,23 @@
       Cache_End   :    out Max_Block_Index;
       Success     :    out Boolean)
    with
-      Post => Cache_End = Cache_Start + 2 ** State.Block_Size_Bits
+      Post => Cache_End = Cache_Start + State.Block_Size - 1
    is
-      Block_Size : constant Natural := 2 ** State.Block_Size_Bits;
       -- 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 :=
-         Block_Cache_Index'Min (Level, Max_Level);
+      Max_Level   : constant Block_Cache_Index := Block_Size'Last / State.Block_Size - 1;
+      Cache_Level : constant Block_Cache_Index := Block_Cache_Index'Min (Level, Max_Level);
    begin
-      Cache_Start := Cache_Level * Block_Size;
-      Cache_End   := Cache_Start + Block_Size - 1;
+      Cache_Start := Cache_Level * State.Block_Size;
+      Cache_End   := Cache_Start + State.Block_Size - 1;
       if State.Block_Cache_Logical (Cache_Level) = Logical and
          State.Block_Cache_Label (Cache_Level) = Label
       then
          Success := True;
       else
          Read_FSBlock
-           (State    => State,
-            Buf      => State.Block_Cache (Cache_Start .. Cache_End),
+           (Buf      => State.Block_Cache (Cache_Start .. Cache_End),
             FSBlock  => Phys,
+            Part_Len => State.Part_Len,
             Success  => Success);
          State.Block_Cache_Logical (Cache_Level) := Logical;
          State.Block_Cache_Label (Cache_Level) := Label;
@@ -196,7 +191,7 @@
       Cache_End   :    out Max_Block_Index;
       Success     :    out Boolean)
    with
-      Post => Cache_End = Cache_Start + 2 ** State.Block_Size_Bits
+      Post => Cache_End = Cache_Start + State.Block_Size - 1
    is
    begin
       Cache_FSBlock (State, Phys, Level, Cache_Label (Phys),
@@ -232,9 +227,8 @@
       function I_Blocks is new Ada.Unchecked_Conversion (Inode_Extents, Inode_Blocks);
       function I_Blocks (State : T) return Inode_Blocks is (I_Blocks (State.Inode.Inline));
 
-      Block_Size : constant Natural := 2 ** State.Block_Size_Bits;
-      Addr_Per_Block : constant FSBlock_Logical := FSBlock_Logical (Block_Size / 4);
-      Max_Addr_Per_Block : constant FSBlock_Logical := FSBlock_Logical (2 ** Log_Block_Size'Last / 4);
+      Addr_Per_Block : constant FSBlock_Logical := FSBlock_Logical (State.Block_Size / 4);
+      Max_Addr_Per_Block : constant FSBlock_Logical := FSBlock_Logical (Block_Size'Last / 4);
       type Addr_In_Block_Range is range 0 .. Max_Addr_Per_Block - 1;
 
       procedure Indirect_Block_Lookup
@@ -379,6 +373,7 @@
       Extent_Header_Magic : constant := 16#f03a#;
       subtype Extent_Off is Natural range 0 .. Extent_Header_Size;
       subtype Extent_Idx is Natural range 1 .. (Max_Block_Index'Last + 1) / Extent_Header_Size - 1;
+      Dynamic_Max_Index : constant Extent_Idx := State.Block_Size / Extent_Header_Size - 1;
 
       function Extent_Byte_Offset (Idx : Extent_Idx; Off : Extent_Off) return Natural
       is
@@ -469,10 +464,9 @@
       with
          Pre => Logical_Off <= Logical,
          Post => (if Success then
+                     Cache_End = Cache_Start + State.Block_Size - 1 and then
                      Extent_Logical (State.Block_Cache (Cache_Start .. Cache_End), Next) <= Logical)
       is
-         Block_Size : constant Natural := 2 ** State.Block_Size_Bits;
-         Dynamic_Max_Index : constant Natural := Block_Size / Extent_Header_Size - 1;
       begin
          Cache_FSBlock
            (State       => State,
@@ -583,10 +577,8 @@
       subtype Desc_In_Block_Index is Group_Index
          range 0 .. Group_Index (2 ** Log_Block_Size'Last / Desc_Size'First - 1);
 
-      Block_Size : constant Natural := 2 ** State.Block_Size_Bits;
-
-      Inodes_Per_Block : constant Inode_Index := Inode_Index (Block_Size / State.Inode_Size);
-      Desc_Per_Block : constant Group_Index := Group_Index (Block_Size / State.Desc_Size);
+      Inodes_Per_Block : constant Inode_Index := Inode_Index (State.Block_Size / State.Inode_Size);
+      Desc_Per_Block : constant Group_Index := Group_Index (State.Block_Size / State.Desc_Size);
 
       ------------------------
       -- Group deserialization
@@ -880,10 +872,9 @@
       Pos := Buf'First;
       while Pos <= Buf'Last and Inode_Length (File_Pos) < State.Inode.Size loop
          declare
-            Block_Size : constant File_Length := 2 ** State.Block_Size_Bits;
-            In_Block : constant Max_Block_Index := Natural (File_Pos mod Block_Size);
-            Logical : constant FSBlock_Logical := FSBlock_Logical (File_Pos / Block_Size);
-            In_Block_Space : constant Natural := Natural (Block_Size) - In_Block;
+            In_Block : constant Max_Block_Index := Natural (File_Pos) mod State.Block_Size;
+            Logical : constant FSBlock_Logical := FSBlock_Logical (File_Pos / File_Offset (State.Block_Size));
+            In_Block_Space : constant Natural := Natural (State.Block_Size) - In_Block;
             In_File_Space : constant Inode_Length := State.Inode.Size - Inode_Length (File_Pos);
             In_Buf_Space : constant Natural := Buf'Last - Pos + 1;
             Len_Here : Natural;
diff --git a/src/filo-fs-ext2.ads b/src/filo-fs-ext2.ads
index 32b1940..ba47aef 100644
--- a/src/filo-fs-ext2.ads
+++ b/src/filo-fs-ext2.ads
@@ -45,6 +45,7 @@
 
    -- maximum block size is 64KiB (2^16):
    subtype Log_Block_Size is Positive range 10 .. 16;
+   subtype Block_Size is Natural range 2 ** Log_Block_Size'First .. 2 ** Log_Block_Size'Last;
    subtype Max_Block_Index is Index_Type range 0 .. 2 ** Log_Block_Size'Last - 1;
 
    -- Minimum ext2 block size is 1KiB (two 512B blocks)
@@ -85,7 +86,8 @@
       S : State;
       Part_Len             : Partition_Length := 0;
       First_Data_Block     : FSBlock_Offset := 0;
-      Block_Size_Bits      : Log_Block_Size := 10;
+      Block_Size_Bits      : Log_Block_Size := Log_Block_Size'First;
+      Block_Size           : Ext2.Block_Size := Ext2.Block_Size'First;
       Inodes_Per_Group     : Inode_Index := Inode_Index'First;
       Inode_Size           : Ext2.Inode_Size := Ext2.Inode_Size'First;
       Desc_Size            : Ext2.Desc_Size := Ext2.Desc_Size'First;