ext2: Pre-compute Inodes_Per_Block & Desc_Per_Block

Eases proving that they are in range.
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index 3d6c0eb..c7ea867 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -71,6 +71,7 @@
             return;
          end if;
       end;
+      pragma Assert_And_Cut (Success);
 
       declare
          S_Inodes_Per_Group : constant Unsigned_32 := Read_LE32 (Super_Block, 10 * 4);
@@ -82,6 +83,7 @@
             return;
          end if;
       end;
+      pragma Assert_And_Cut (Success);
 
       declare
          S_Rev_Level : constant Unsigned_32 := Read_LE32 (Super_Block, 19 * 4);
@@ -90,17 +92,22 @@
             declare
                S_Inode_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 22 * 4);
             begin
-               if Natural (S_Inode_Size) in Inode_Size then
+               if Natural (S_Inode_Size) in Inode_Size and then
+                  Natural (S_Inode_Size) <= Static.Block_Size
+               then
                   Static.Inode_Size := Inode_Size (S_Inode_Size);
                else
                   Success := False;
                   return;
                end if;
+               pragma Assert (Static.Block_Size / Static.Inode_Size <= Natural (Inode_In_Block_Count'Last));
             end;
          else
             Static.Inode_Size := Inode_Size'First;
          end if;
+         Static.Inodes_Per_Block := Inode_In_Block_Count (Static.Block_Size / Static.Inode_Size);
       end;
+      pragma Assert_And_Cut (Success);
 
       declare
          S_Feature_Incompat : constant Unsigned_32 := Read_LE32 (Super_Block, 24 * 4);
@@ -125,7 +132,9 @@
          else
             Static.Desc_Size := Desc_Size'First;
          end if;
+         Static.Desc_Per_Block := Group_Index (Static.Block_Size / Static.Desc_Size);
       end;
+      pragma Assert_And_Cut (Success);
 
       State.S := Mounted;
    end Mount;
@@ -607,13 +616,6 @@
       Static : Mount_State renames State.Static;
       Cache : Cache_Buffer renames State.Cache.Buffer;
 
-      type Group_Index is new Natural;
-      subtype Desc_In_Block_Index is Group_Index
-         range 0 .. Group_Index (2 ** Log_Block_Size'Last / Desc_Size'First - 1);
-
-      Inodes_Per_Block : constant Inode_Index := Inode_Index (Static.Block_Size / Static.Inode_Size);
-      Desc_Per_Block : constant Group_Index := Group_Index (Static.Block_Size / Static.Desc_Size);
-
       ------------------------
       -- Group deserialization
 
@@ -676,14 +678,14 @@
 
       Group : constant Group_Index := Group_Index ((Inode - 1) / Static.Inodes_Per_Group);
       Desc_Block : constant FSBlock_Offset :=
-         1 + Static.First_Data_Block + FSBlock_Offset (Group / Desc_Per_Block);
+         1 + Static.First_Data_Block + FSBlock_Offset (Group / Static.Desc_Per_Block);
       Cache_Start, Cache_End : Max_Block_Index;
    begin
       Cache_FSBlock
         (Static      => Static,
          Cache       => State.Cache,
          Phys        => Desc_Block,
-         Level       => Natural'Min (Natural (Group / Desc_Per_Block), Block_Cache_Index'Last),
+         Level       => Natural'Min (Natural (Group / Static.Desc_Per_Block), Block_Cache_Index'Last),
          Cache_Start => Cache_Start,
          Cache_End   => Cache_End,
          Success     => Success);
@@ -692,11 +694,12 @@
       end if;
 
       declare
-         Desc : constant Desc_In_Block_Index := Group mod Desc_Per_Block;
-         Inode_In_Group : constant Inode_Index := (Inode - 1) mod Static.Inodes_Per_Group;
+         Desc : constant Desc_In_Block_Index := Desc_In_Block_Index (Group mod Static.Desc_Per_Block);
+         Inode_In_Group : constant Inode_In_Group_Index :=
+            Inode_In_Group_Index ((Inode - 1) mod Static.Inodes_Per_Group);
          Inode_Block : constant FSBlock_Offset :=
             Group_Inode_Table (Cache (Cache_Start .. Cache_End), Group) +
-            FSBlock_Offset (Inode_In_Group / Inodes_Per_Block);
+            FSBlock_Offset (Inode_In_Group / Static.Inodes_Per_Block);
       begin
          Cache_FSBlock
            (Static      => Static,
@@ -716,7 +719,7 @@
             S_IFREG  : constant := 8#100000#;
             S_IFLNK  : constant := 8#120000#;
 
-            Inode_In_Block : constant Inode_Index := Inode_In_Group mod Inodes_Per_Block;
+            Inode_In_Block : constant Inode_Index := Inode_Index (Inode_In_Group mod Static.Inodes_Per_Block);
             I_Mode : constant Unsigned_16 :=
                Inode_Mode (Cache (Cache_Start .. Cache_End), Inode_In_Block);
             I_Flags : constant Unsigned_32 :=
@@ -750,6 +753,7 @@
                   State.Inode.Size := Inode_Length (I_Size);
                else
                   Success := False;
+                  return;
                end if;
             end;
             State.Inode.Use_Extents := Static.Feature_Extents and (I_Flags and EXT4_EXTENTS_FL) /= 0;
diff --git a/src/filo-fs-ext2.ads b/src/filo-fs-ext2.ads
index 7c1e467..5537507 100644
--- a/src/filo-fs-ext2.ads
+++ b/src/filo-fs-ext2.ads
@@ -86,6 +86,16 @@
       Inline      : Inode_Extents := (others => 16#00#);
    end record;
 
+   type Group_Index is new Natural range 0 .. Natural (Inode_Index'Last / 2);
+   subtype Group_In_Block_Count is Group_Index
+      range 1 .. Group_Index (Block_Size'Last / Desc_Size'First);
+   type Desc_In_Block_Index is new Natural range 0 .. Natural (Group_In_Block_Count'Last - 1);
+
+   type Inode_In_Group_Index is new Natural range 0 .. Natural (Inode_Index'Last / 2);
+   subtype Inode_In_Block_Count is Inode_In_Group_Index
+      range 1 .. Inode_In_Group_Index (Block_Size'Last / Inode_Size'First);
+   type Inode_In_Block_Index is new Natural range 0 .. Natural (Inode_In_Block_Count'Last - 1);
+
    type Mount_State is record
       Part_Len             : Partition_Length := 0;
       First_Data_Block     : FSBlock_Offset := 0;
@@ -93,7 +103,9 @@
       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;
+      Inodes_Per_Block     : Inode_In_Block_Count := Inode_In_Block_Count'First;
       Desc_Size            : Ext2.Desc_Size := Ext2.Desc_Size'First;
+      Desc_Per_Block       : Group_In_Block_Count := Group_In_Block_Count'First;
       Feature_Extents      : Boolean := False;
       Feature_64Bit        : Boolean := False;
    end record;