-- Derived from GRUB  --  GRand Unified Bootloader
-- Copyright (C) 1999, 2001, 2003  Free Software Foundation, Inc.
-- Copyright (C) 2023 secunet Security Networks AG
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.

with Ada.Unchecked_Conversion;
with System;
with Interfaces;
with Interfaces.C;

with FILO.Blockdev;
with FILO.FS.VFS;

use Interfaces.C;

package body FILO.FS.Ext2 is

   function Is_Mounted (State : T) return Boolean is (State.S >= Mounted);
   function Is_Open (State : T) return Boolean is (State.S = File_Opened);

   --------------------------------------------------------------------------

   SUPERBLOCK_SIZE            : constant := 1024;
   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#;

   EXT4_EXTENTS_FL            : constant := 16#8_0000#;

   procedure Mount
     (State    : in out T;
      Part_Len : in     Partition_Length;
      Success  :    out Boolean)
   is
      Static : Mount_State renames State.Static;
      Super_Block : Buffer_Type (0 .. 64 * 4 - 1);
   begin
      if Part_Len < 2 * SUPERBLOCK_SIZE then
         Success := False;
         return;
      end if;

      Blockdev.Read (Super_Block, 1 * SUPERBLOCK_SIZE, Success);
      if not Success then
         return;
      end if;

      if Read_LE16 (Super_Block, 14 * 4) /= 16#ef53# then
         Success := False;
         return;
      end if;

      Static.Part_Len := Part_Len;
      Static.First_Data_Block := Read_LE32 (Super_Block, 5 * 4);

      declare
         S_Log_Block_Size : constant Unsigned_32 := Read_LE32 (Super_Block, 6 * 4);
      begin
         if S_Log_Block_Size <= Unsigned_32 (Log_Block_Size'Last - 10) then
            Static.Block_Size_Bits := Log_Block_Size (S_Log_Block_Size + 10);
            Static.Block_Size := 2 ** Log_Block_Size (S_Log_Block_Size + 10);
         else
            Success := False;
            return;
         end if;
      end;
      pragma Assert_And_Cut (Success and not Is_Mounted (State));

      declare
         S_Inodes_Per_Group : constant Unsigned_32 := Read_LE32 (Super_Block, 10 * 4);
      begin
         if S_Inodes_Per_Group in 1 .. Unsigned_32'Last then
            Static.Inodes_Per_Group := Inode_In_Group_Count (S_Inodes_Per_Group);
         else
            Success := False;
            return;
         end if;
      end;

      declare
         S_Rev_Level : constant Unsigned_32 := Read_LE32 (Super_Block, 19 * 4);
      begin
         if S_Rev_Level >= DYNAMIC_REV then
            declare
               S_Inode_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 22 * 4);
            begin
               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 and not Is_Mounted (State));

      declare
         S_Feature_Incompat : constant Unsigned_32 := Read_LE32 (Super_Block, 24 * 4);
      begin
         Static.Feature_Extents := (S_Feature_Incompat and FEATURE_INCOMPAT_EXTENTS) /= 0;
         Static.Feature_64Bit   := (S_Feature_Incompat and FEATURE_INCOMPAT_64BIT) /= 0;
         if Static.Feature_64Bit then
            declare
               S_Desc_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 63 * 4 + 2);
            begin
               if Natural (S_Desc_Size) in Group_Desc_Size and
                  Natural (S_Desc_Size) <= Static.Block_Size and
                  Is_Power_Of_2 (S_Desc_Size)
               then
                  Static.Group_Desc_Size := Group_Desc_Size (S_Desc_Size);
               else
                  Success := False;
                  return;
               end if;
               pragma Assert (Static.Block_Size / Static.Group_Desc_Size <= Natural (Group_In_Block_Count'Last));
            end;
            Static.Feature_64Bit := Static.Feature_64Bit and Static.Group_Desc_Size >= 64;
         else
            Static.Group_Desc_Size := Group_Desc_Size'First;
         end if;
         Static.Group_Desc_Per_Block := Group_In_Block_Count (Static.Block_Size / Static.Group_Desc_Size);
      end;

      State.S := Mounted;
   end Mount;

   procedure Read_FSBlock
     (Buf      : in out Buffer_Type;
      FSBlock  : in     FSBlock_Offset;
      Part_Len : in     Partition_Length;
      Success  :    out Boolean)
   with
      Pre => Buf'Length in Block_Size
   is
      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_64 > Max_Block_Offset then
         Success := False;
         return;
      end if;
      Blockdev.Read (Buf, Blockdev_Length (FSBlock_64 * Block_Size), Success);
   end Read_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
      -- Limit cache usage depending on block size:
      Max_Level   : constant Block_Cache_Index := Block_Size'Last / Static.Block_Size - 1;
      Cache_Level : constant Block_Cache_Index := Block_Cache_Index'Min (Level, Max_Level);
   begin
      Cache_Start := Cache_Level * Static.Block_Size;
      Cache_End   := Cache_Start + Static.Block_Size - 1;
      if Cache.Phys (Cache_Level) = Phys then
         Success := True;
      else
         Read_FSBlock
           (Buf      => Cache.Buffer (Cache_Start .. Cache_End),
            FSBlock  => Phys,
            Part_Len => Static.Part_Len,
            Success  => Success);
         Cache.Phys (Cache_Level) := Phys;
      end if;
   end Cache_FSBlock;

   procedure Ext2_Block_Map
     (State       : in out T;
      Logical     : in     FSBlock_Logical;
      Physical    :    out FSBlock_Offset;
      Success     :    out Boolean)
   with
      Post => State.Static = State.Static'Old and State.S = State.S'Old
   is
      Static : constant Mount_State := State.Static;

      Direct_Blocks : constant := 12;
      type Direct_Blocks_Array is array (Natural range 0 .. Direct_Blocks - 1) of Unsigned_32;
      type Inode_Blocks is record
         Direct_Blocks     : Direct_Blocks_Array;
         Indirect_Block    : Unsigned_32;
         Double_Indirect   : Unsigned_32;
         Triple_Indirect   : Unsigned_32;
      end record
      with Object_Size => Inode_Extents'Length * 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));

      Addr_Per_Block : constant FSBlock_Logical := FSBlock_Logical (Static.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
        (Indirect_Block_Phys  : in     FSBlock_Offset;
         Addr_In_Block        : in     Addr_In_Block_Range;
         Level                : in     Block_Cache_Index;
         Next_Physical        :    out FSBlock_Offset;
         Success              :    out Boolean)
      with
         Pre =>
            Addr_Per_Block = FSBlock_Logical (Static.Block_Size / 4) and
            FSBlock_Logical (Addr_In_Block) < Addr_Per_Block,
         Post => State.Static = State.Static'Old and State.S = State.S'Old
      is
         Cache_Start, Cache_End : Max_Block_Index;
      begin
         if Indirect_Block_Phys = 0 then
            Next_Physical := 0;
            Success := True;
            return;
         end if;

         Cache_FSBlock
           (Static      => Static,
            Cache       => State.Cache,
            Phys        => Indirect_Block_Phys,
            Level       => Level,
            Cache_Start => Cache_Start,
            Cache_End   => Cache_End,
            Success     => Success);
         Next_Physical := FSBlock_Offset (Read_LE32
           (Buf => State.Cache.Buffer (Cache_Start .. Cache_End),
            Off => Natural (Addr_In_Block) * 4));
      end Indirect_Block_Lookup;

      Logical_Rest : FSBlock_Logical := Logical;

      pragma Assert (Addr_Per_Block <= 2 ** 14);
   begin
      if Logical_Rest < Direct_Blocks then
         Physical := FSBlock_Offset (I_Blocks (State).Direct_Blocks (Natural (Logical)));
         Success := True;
         return;
      end if;

      Logical_Rest := Logical_Rest - Direct_Blocks;
      if Logical_Rest < Addr_Per_Block then
         Indirect_Block_Lookup
           (Indirect_Block_Phys  => FSBlock_Offset (I_Blocks (State).Indirect_Block),
            Addr_In_Block        => Addr_In_Block_Range (Logical_Rest),
            Level                => Block_Map_Cache_Level,
            Next_Physical        => Physical,
            Success              => Success);
         return;
      end if;

      Logical_Rest := Logical_Rest - Addr_Per_Block;
      if Logical_Rest < Addr_Per_Block ** 2 then
         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                => Block_Map_Cache_Level + 1,
            Next_Physical        => Physical,
            Success              => Success);
         if not Success then
            return;
         end if;

         Indirect_Block_Lookup
           (Indirect_Block_Phys  => Physical,
            Addr_In_Block        => Addr_In_Block_Range (Logical_Rest mod Addr_Per_Block),
            Level                => Block_Map_Cache_Level,
            Next_Physical        => Physical,
            Success              => Success);
         return;
      end if;

      Logical_Rest := Logical_Rest - Addr_Per_Block ** 2;
      if Logical_Rest < Addr_Per_Block ** 3 then
         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                => Block_Map_Cache_Level + 2,
            Next_Physical        => Physical,
            Success              => Success);
         if not Success then
            return;
         end if;

         Indirect_Block_Lookup
           (Indirect_Block_Phys  => Physical,
            Addr_In_Block        => Addr_In_Block_Range ((Logical_Rest / Addr_Per_Block) mod Addr_Per_Block),
            Level                => Block_Map_Cache_Level + 1,
            Next_Physical        => Physical,
            Success              => Success);
         if not Success then
            return;
         end if;

         Indirect_Block_Lookup
           (Indirect_Block_Phys  => Physical,
            Addr_In_Block        => Addr_In_Block_Range (Logical_Rest mod Addr_Per_Block),
            Level                => Block_Map_Cache_Level,
            Next_Physical        => Physical,
            Success              => Success);
         return;
      end if;

      -- Logical address was just too high.
      Physical := 0;
      Success := False;
   end Ext2_Block_Map;

   procedure Extent_Block_Map
     (State       : in out T;
      Logical     : in     FSBlock_Logical;
      Physical    :    out FSBlock_Offset;
      Success     :    out Boolean)
   with
      Post => State.Static = State.Static'Old and State.S = State.S'Old
   is
      Cache : Cache_Buffer renames State.Cache.Buffer;

      -- Extent blocks always start with a 12B header and contain 12B entries.
      -- Every entry starts with the number of the first logical block it
      -- covers. Entries are sorted by this number.
      -- Depth > 0 blocks have index entries, referencing further extent blocks.
      -- Depth = 0 blocks have extent entries, referencing a contiguous range
      -- of data blocks.
      --
      --                           +-----------------+
      --                       .-> | Hdr depth=0     |
      --                       |   +-----------------+
      --                       |   | Extent   0.. 12 |
      --    +-------------+    |   +-----------------+
      --    | Hdr depth=1 |    |   | Extent  13.. 13 |
      --    +-------------+    |   +-----------------+
      --    | Index     0 | --'    | Extent  14..122 |
      --    +-------------+        +-----------------+
      --    | Index   123 | --.
      --    +-------------+    |   +-----------------+
      --                       `-> | Hdr depth=0     |
      --                           +-----------------+
      --                           | Extent 123..125 |
      --                           +-----------------+
      --                           | Extent 126..234 |
      --                           +-----------------+
      --

      Extent_Header_Size : constant := 12;
      Extent_Header_Magic : constant := 16#f30a#;
      Initialized_Extent_Max_Len : constant := 2 ** 15;
      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.Static.Block_Size / Extent_Header_Size - 1;
      subtype Extent_Depth is Natural range 0 .. 32;

      function Extent_Byte_Offset (Idx : Extent_Idx; Off : Extent_Off) return Natural
      is
         (Idx * Extent_Header_Size + Off);

      function Header_Magic (Buf : Buffer_Type) return Unsigned_16
      is
         (Read_LE16 (Buf, 0))
      with
         Pre => Buf'Length >= 2;

      function Header_Entries (Buf : Buffer_Type) return Natural
      is
         (Natural (Read_LE16 (Buf, 2)))
      with
         Pre => Buf'Length >= 4;

      function Header_Depth (Buf : Buffer_Type) return Natural
      is
         (Natural (Read_LE16 (Buf, 6)))
      with
         Pre => Buf'Length >= 8;

      function Index_Logical (Buf : Buffer_Type; Idx : Extent_Idx) return FSBlock_Logical
      is
         (FSBlock_Logical (Read_LE32 (Buf, Extent_Byte_Offset (Idx, 0))))
      with
         Pre => Buf'Length >= Extent_Byte_Offset (Idx, 4);

      function Index_Physical (Buf : Buffer_Type; Idx : Extent_Idx) return FSBlock_Offset
      is
         (FSBlock_Offset
            (Shift_Left (Unsigned_64 (Read_LE16 (Buf, Extent_Byte_Offset (Idx, 8))), 32) or
                                       Unsigned_64 (Read_LE32 (Buf, Extent_Byte_Offset (Idx, 4)))))
      with
         Pre => Buf'Length >= Extent_Byte_Offset (Idx, 10);

      function Extent_Logical (Buf : Buffer_Type; Idx : Extent_Idx) return FSBlock_Logical
      renames Index_Logical;

      function Extent_Length (Buf : Buffer_Type; Idx : Extent_Idx) return FSBlock_Logical
      is
         (FSBlock_Logical (Read_LE16 (Buf, Extent_Byte_Offset (Idx, 4))))
      with
         Pre => Buf'Length >= Extent_Byte_Offset (Idx, 6);

      function Extent_Physical (Buf : Buffer_Type; Idx : Extent_Idx) return FSBlock_Offset
      is
         (FSBlock_Offset
            (Shift_Left (Unsigned_64 (Read_LE16 (Buf, Extent_Byte_Offset (Idx, 6))), 32) or
                           Unsigned_64 (Read_LE32 (Buf, Extent_Byte_Offset (Idx, 8)))))
      with
         Pre => Buf'Length >= Extent_Byte_Offset (Idx, 12);

      function Bin_Search (Buf : Buffer_Type; Refs : Extent_Idx) return Extent_Idx
      with
         Pre =>
            Buf'Length in 2 * Extent_Header_Size .. Max_Block_Index'Last and then
            Refs in 1 .. Extent_Idx (Buf'Length / Extent_Header_Size - 1) and then
            Extent_Logical (Buf, 1) <= Logical,
         Post =>
            Bin_Search'Result in 1 .. Refs and
            Extent_Logical (Buf, Bin_Search'Result) <= Logical
      is
         Left : Positive := 2;
         Right : Extent_Idx := Refs;
      begin
         while Left <= Right loop
            declare
               Mid : constant Extent_Idx := (Left + Right) / 2;
               Ext_Logical : constant FSBlock_Logical := Extent_Logical (Buf, Mid);
            begin
               if Logical < Ext_Logical then
                  Right := Mid - 1;
               else
                  Left := Mid + 1;
               end if;
               pragma Loop_Invariant
                 (Right <= Refs and then
                  Left in 2 .. Refs + 1 and then
                  Extent_Logical (Buf, Left - 1) <= Logical);
            end;
         end loop;
         return Left - 1;
      end Bin_Search;

      procedure Next_Ref
        (Current     : in     FSBlock_Offset;
         Depth       : in     Extent_Depth;
         Next        :    out Extent_Idx;
         Cache_Start :    out Max_Block_Index;
         Cache_End   :    out Max_Block_Index;
         Success     :    out Boolean)
      with
         Pre =>
            Dynamic_Max_Index = State.Static.Block_Size / Extent_Header_Size - 1,
         Post =>
            State.Static = State.Static'Old and State.S = State.S'Old and
            (if Success then
               Next <= Dynamic_Max_Index and then
               Cache_End = Cache_Start + State.Static.Block_Size - 1)
      is
      begin
         Cache_FSBlock
           (Static      => State.Static,
            Cache       => State.Cache,
            Phys        => Current,
            Level       => Block_Map_Cache_Level + Depth,
            Cache_Start => Cache_Start,
            Cache_End   => Cache_End,
            Success     => Success);
         if not Success then
            Next := 1;
            return;
         end if;

         declare
            Hdr_Magic : constant Unsigned_16 := Header_Magic (Cache (Cache_Start .. Cache_End));
            Hdr_Entries : constant Natural := Header_Entries (Cache (Cache_Start .. Cache_End));
            Hdr_Depth : constant Natural := Header_Depth (Cache (Cache_Start .. Cache_End));
            First_Logical : constant FSBlock_Logical :=
               Extent_Logical (Cache (Cache_Start .. Cache_End), 1);
         begin
            Success := Success and then
               Hdr_Magic = Extent_Header_Magic and then
               Hdr_Depth = Depth and then
               Hdr_Entries in Extent_Idx and then
               Hdr_Entries <= Dynamic_Max_Index;
            if not Success or else
               -- Is the searched `Logical' out of range?
               First_Logical > Logical
            then
               Next := 1;
            else
               pragma Assert (Cache_End - Cache_Start + 1 = State.Static.Block_Size);
               Next := Bin_Search (Cache (Cache_Start .. Cache_End), Hdr_Entries);
            end if;
         end;
      end Next_Ref;

      Inline_Extents : Ext2.Inode_Extents renames State.Inode.Inline;
      Inode_Magic : constant Unsigned_16 := Header_Magic (Inline_Extents);
      Inode_Entries : constant Natural := Header_Entries (Inline_Extents);
      First_Logical : constant FSBlock_Logical := Extent_Logical (Inline_Extents, 1);
      Depth : Natural := Header_Depth (Inline_Extents);

      Cache_Start, Cache_End : Max_Block_Index;
      Logical_Off, Length : FSBlock_Logical;
      Physical_Off : FSBlock_Offset;
      Idx : Extent_Idx;
   begin
      Physical := 0; -- Return `0' if the searched `Logical' is not allocated.
      Success :=
         Inode_Magic = Extent_Header_Magic and then
         Inode_Entries < Inline_Extents'Length / Extent_Header_Size and then
         Depth in Extent_Depth;
      if not Success or else
         -- Is there no extent or the searched `Logical' out of range?
         Inode_Entries = 0 or else First_Logical > Logical
      then
         return;
      end if;

      Idx := Bin_Search (Inline_Extents, Inode_Entries);
      if Depth = 0 then
         Physical_Off := Extent_Physical (Inline_Extents, Idx);
         Logical_Off := Extent_Logical (Inline_Extents, Idx);
         Length := Extent_Length (Inline_Extents, Idx);
      else
         Physical_Off := Index_Physical (Inline_Extents, Idx);
         Logical_Off := Index_Logical (Inline_Extents, Idx);
         loop
            pragma Loop_Invariant
              (State.Static = State.Static'Loop_Entry and then
               State.S = State.S'Loop_Entry and then
               Depth > 0 and then
               Depth in Extent_Depth and then
               Logical_Off <= Logical);
            Depth := Depth - 1;
            Next_Ref
              (Current     => Physical_Off,
               Depth       => Depth,
               Next        => Idx,
               Cache_Start => Cache_Start,
               Cache_End   => Cache_End,
               Success     => Success);
            if not Success then
               return;
            end if;

            exit when Depth = 0;
            Physical_Off := Index_Physical (Cache (Cache_Start .. Cache_End), Idx);
            Logical_Off := Index_Logical (Cache (Cache_Start .. Cache_End), Idx);

            -- Is the searched `Logical' out of range?
            if Logical_Off > Logical then
               return;
            end if;
         end loop;

         Physical_Off := Extent_Physical (Cache (Cache_Start .. Cache_End), Idx);
         Logical_Off := Extent_Logical (Cache (Cache_Start .. Cache_End), Idx);
         Length := Extent_Length (Cache (Cache_Start .. Cache_End), Idx);
      end if;

      -- Is the searched `Logical' out of range?
      if Logical_Off > Logical or else
         -- Is this an empty extent?
         (Length = 0 or Length > Initialized_Extent_Max_Len)
      then
         return;
      end if;

      Success := Logical_Off <= FSBlock_Logical'Last - Length + 1;
      if not Success or else
         -- Is the searched `Logical' after this extent?
         Logical > Logical_Off + Length - 1
      then
         return;
      end if;

      Success := FSBlock_Offset (Logical - Logical_Off) <= FSBlock_Offset'Last - Physical_Off;
      if Success then
         Physical := Physical_Off + FSBlock_Offset (Logical - Logical_Off);
      end if;
   end Extent_Block_Map;

   procedure Parse_Group
     (Static      : in     Mount_State;
      Table_Start :    out FSBlock_Offset;
      Buf         : in     Buffer_Type;
      Success     :    out Boolean)
   with
      Pre =>
         Buf'Length >= Group_Desc_Size'First and
         (if Static.Feature_64Bit then Buf'Length >= 64)
   is
      Inode_Table_Block : constant Unsigned_64 :=
         (if Static.Feature_64Bit
          then Shift_Left (Unsigned_64 (Read_LE32 (Buf, 40)), 32)
          else 0)
         or
         Unsigned_64 (Read_LE32 (Buf, 8));
   begin
         if Inode_Table_Block >= Unsigned_64 (Static.First_Data_Block) and
            Inode_Table_Block <= Unsigned_64 (FSBlock_Offset'Last)
         then
            Table_Start := FSBlock_Offset (Inode_Table_Block);
            Success := True;
         else
            Table_Start := 0;
            Success := False;
         end if;
   end Parse_Group;

   procedure Parse_Inode
     (Static   : in     Mount_State;
      Inode    : in out Inode_Info;
      Buf      : in     Buffer_Type;
      Success  :    out Boolean)
   with
      Pre => Buf'Length >= Inode_Size'First
   is
      S_IFMT   : constant := 8#170000#;
      S_IFDIR  : constant := 8#040000#;
      S_IFREG  : constant := 8#100000#;
      S_IFLNK  : constant := 8#120000#;

      I_Mode      : constant Unsigned_16 := Read_LE16 (Buf, 0);
      I_Blocks    : constant Unsigned_32 := Read_LE32 (Buf, 28);
      I_Flags     : constant Unsigned_32 := Read_LE32 (Buf, 32);
      I_File_ACL  : constant Unsigned_32 := Read_LE32 (Buf, 104);
   begin
      case I_Mode and S_IFMT is
         when S_IFDIR => Inode.Mode := Dir;
         when S_IFREG => Inode.Mode := Regular;
         when S_IFLNK => Inode.Mode := Link;
         when others  => Success := False; return;
      end case;

      if Inode.Mode = Link and
         ((I_File_ACL = 0 and I_Blocks = 0) or
          (I_File_ACL /= 0 and I_Blocks = 2 ** (Static.Block_Size_Bits - 9)))
      then
         Inode.Mode := Fast_Link;
      end if;

      declare
         I_Size : constant Unsigned_64 :=
            (if Inode.Mode = Regular
             then Shift_Left (Unsigned_64 (Read_LE32 (Buf, 108)), 32)
             else 0) or
            Unsigned_64 (Read_LE32 (Buf, 4));
      begin
         if I_Size > Unsigned_64 (Inode_Length'Last) then
            Success := False;
            return;
         end if;
         Inode.Size := Inode_Length (I_Size);
      end;

      Inode.Use_Extents := Static.Feature_Extents and (I_Flags and EXT4_EXTENTS_FL) /= 0;
      Inode.Inline := Buf (Buf'First + 40 .. Buf'First + 100 - 1);

      Success := True;
   end Parse_Inode;

   procedure Open
     (State    : in out T;
      Inode    : in     Inode_Index;
      Success  : out Boolean)
   with
      Pre => Is_Mounted (State),
      Post => Is_Mounted (State) and (Success = Is_Open (State))
   is
      Static : Mount_State renames State.Static;
      Cache : Cache_Buffer renames State.Cache.Buffer;

      Group : constant Group_Index := Group_Index ((Inode - 1) / Static.Inodes_Per_Group);
      Group_Block : constant FSBlock_Offset :=
         1 + FSBlock_Offset (Static.First_Data_Block) + FSBlock_Offset (Group / Static.Group_Desc_Per_Block);
      Group_In_Block : constant Group_In_Block_Index := Group_In_Block_Index (Group mod Static.Group_Desc_Per_Block);
      Group_In_Block_Offset : constant Natural := Natural (Group_In_Block) * Static.Group_Desc_Size;

      Cache_Start, Cache_End : Max_Block_Index;
      First_Table_Block : FSBlock_Offset;
   begin
      State.S := Mounted;

      Cache_FSBlock
        (Static      => Static,
         Cache       => State.Cache,
         Phys        => Group_Block,
         Level       => Group_Cache_Level,
         Cache_Start => Cache_Start,
         Cache_End   => Cache_End,
         Success     => Success);
      Success := Success and then
         -- TODO: Prove this using a predicate on Mount_State:
         Cache_Start <= Cache_End - Group_In_Block_Offset - Static.Group_Desc_Size + 1;
      if not Success then
         return;
      end if;

      Parse_Group
        (Static      => Static,
         Table_Start => First_Table_Block,
         Buf         => Cache (Cache_Start + Group_In_Block_Offset ..
                                 Cache_Start + Group_In_Block_Offset + Static.Group_Desc_Size - 1),
         Success     => Success);
      if not Success then
         return;
      end if;

      declare
         Inode_In_Group : constant Inode_In_Group_Index :=
            Inode_In_Group_Index ((Inode - 1) mod Static.Inodes_Per_Group);

         Inode_Block : constant FSBlock_Offset := FSBlock_Offset (Inode_In_Group / Static.Inodes_Per_Block);
         Inode_In_Block : constant Inode_In_Block_Index :=
            Inode_In_Block_Index (Inode_In_Group mod Static.Inodes_Per_Block);
         Inode_In_Block_Offset : constant Natural :=
            Natural (Inode_In_Block) * Static.Inode_Size;
      begin
         if First_Table_Block > FSBlock_Offset'Last - Inode_Block then
            Success := False;
            return;
         end if;

         Cache_FSBlock
           (Static      => Static,
            Cache       => State.Cache,
            Phys        => FSBlock_Offset (First_Table_Block + Inode_Block),
            Level       => Inode_Cache_Level,
            Cache_Start => Cache_Start,
            Cache_End   => Cache_End,
            Success     => Success);
         Success := Success and then
            -- TODO: Prove this using a predicate on Mount_State:
            Cache_Start <= Cache_End - Inode_In_Block_Offset - Static.Inode_Size + 1;
         if not Success then
            return;
         end if;

         Parse_Inode
           (Static   => State.Static,
            Inode    => State.Inode,
            Buf      => Cache (Cache_Start + Inode_In_Block_Offset ..
                                 Cache_Start + Inode_In_Block_Offset + Static.Inode_Size - 1),
            Success  => Success);

         if Success then
            State.Inode.I := Inode;
            State.Inode.Map_Cache := (others => <>);
            State.S := File_Opened;
         end if;
      end;
   end Open;

   procedure Open
     (State       : in out T;
      File_Len    :    out File_Length;
      File_Type   :    out FS.File_Type;
      File_Name   : in     String;
      In_Root     : in     Boolean;
      Success     : out    Boolean)
   is
      File_Name_Max : constant := 255;
      Root_Inode : constant := 2;

      function Str_Buf_Equal (Str : String; Buf : Buffer_Type) return Boolean
      with
         Pre => Str'Length <= Buf'Length
      is
      begin
         for I in Str'Range loop
            if Character'Pos (Str (I)) /= Buf (Buf'First + (I - Str'First)) then
               return False;
            end if;
         end loop;
         return True;
      end Str_Buf_Equal;

      File_Inode : Inode_Index;
      File_Pos : File_Length;
   begin
      File_Len := 0;
      File_Type := FS.File_Type'First;

      if File_Name'Length > File_Name_Max then
         Success := False;
         return;
      end if;

      -- Ensure dir is opened:
      --
      if State.S = File_Opened then
         if State.Cur_Dir /= State.Inode.I then
            Success := False;
            return;
         end if;
      else
         if In_Root then
            State.Cur_Dir := Root_Inode;
         end if;
         Open (State, State.Cur_Dir, Success);
         if not Success then
            return;
         end if;
      end if;

      -- Lookup file in opened dir:
      --
      File_Pos := 0;
      Success := False;
      loop
         pragma Loop_Invariant (Is_Open (State) and not Success);
         declare
            Dir_Entry_Header_Length : constant := 4 + 2 + 1 + 1;
            Dir_Entry_Header : Buffer_Type (0 .. Dir_Entry_Header_Length - 1);
            Dir_Entry_Name : Buffer_Type (0 .. File_Name_Max - 1);
            Entry_File_Pos : File_Offset := File_Pos;
            Dir_Entry_Length : File_Length;
            Inode : Inode_0_Index;
            Len : Natural;
         begin
            Read
              (State    => State,
               File_Pos => Entry_File_Pos,
               Buf      => Dir_Entry_Header,
               Len      => Len);
            if Len < Dir_Entry_Header_Length then
               return;
            end if;

            -- Only check filenames of exact same length
            Inode := Inode_0_Index (Read_LE32 (Dir_Entry_Header, 0));
            if Inode >= Root_Inode and then
               File_Name'Length = Natural (Dir_Entry_Header (6))
            then
               pragma Warnings
                 (GNATprove, Off, """Entry_File_Pos"" is set*but not used",
                  Reason => "We only care about intermedidate values.");
               Read
                 (State    => State,
                  File_Pos => Entry_File_Pos,
                  Buf      => Dir_Entry_Name,
                  Len      => Len);
               pragma Warnings (GNATprove, On, """Entry_File_Pos"" is set*but not used");
               if Len < File_Name'Length then
                  return;
               end if;

               Success := Str_Buf_Equal (File_Name, Dir_Entry_Name);
               if Success then
                  File_Inode := Inode;
                  exit;
               end if;
            end if;

            Dir_Entry_Length := File_Length (Read_LE16 (Dir_Entry_Header, 4));
            if Dir_Entry_Length = 0 or
               File_Pos > File_Length'Last - Dir_Entry_Length or
               Unsigned_64 (File_Pos) >= Unsigned_64 (State.Inode.Size) - Unsigned_64 (Dir_Entry_Length)
            then
               return;
            end if;
            File_Pos := File_Pos + Dir_Entry_Length;
         end;
      end loop;
      pragma Assert_And_Cut (Success and Is_Mounted (State));

      Open (State, File_Inode, Success);
      if not Success then
         return;
      end if;

      if State.Inode.Mode = Dir then
         State.Cur_Dir := File_Inode;
      end if;

      Success := State.Inode.Size <= Inode_Length (File_Length'Last);
      if Success then
         File_Len := File_Length (State.Inode.Size);
         File_Type := (case State.Inode.Mode is
                        when Dir                => FS.Dir,
                        when Regular            => FS.Regular,
                        when Link .. Fast_Link  => FS.Link);
      else
         Close (State);
      end if;
   end Open;

   procedure Close (State : in out T) is
   begin
      State.S := Mounted;
   end Close;

   procedure Read
     (State    : in out T;
      File_Pos : in out File_Offset;
      Buf      :    out Buffer_Type;
      Len      :    out Natural)
   is
      Static : Mount_State renames State.Static;
      Cache : Cache_Buffer renames State.Cache.Buffer;

      Pos : Natural range Buf'First .. Buf'Last + 1;
   begin
      if State.Inode.Mode = Fast_Link then
         if State.Inode.Size > Inode_Length (State.Inode.Inline'Length) or
            Inode_Length (File_Pos) >= State.Inode.Size then
            Len := 0;
         else
            Len := Natural'Min (Buf'Length, Natural (State.Inode.Size) - Natural (File_Pos));
         end if;
         Buf (Buf'First .. Buf'First + Len - 1) :=
            State.Inode.Inline (Natural (File_Pos) .. Natural (File_Pos) + Len - 1);
         Buf (Buf'First + Len .. Buf'Last) := (others => 16#00#);
         File_Pos := File_Pos + File_Length (Len);
         return;
      end if;

      Len := 0;
      Pos := Buf'First;
      while Pos <= Buf'Last and
            File_Pos < File_Offset'Last and
            Inode_Length (File_Pos) < State.Inode.Size
      loop
         pragma Loop_Invariant (for all I in Buf'First .. Pos - 1 => Buf (I)'Initialized);
         pragma Loop_Invariant (Is_Open (State));
         declare
            In_Block : constant Max_Block_Index := Natural (File_Pos) mod Static.Block_Size;
            Logical : constant FSBlock_Logical :=
               FSBlock_Logical (File_Pos / File_Offset (Static.Block_Size));
            In_Block_Space : constant Positive := Static.Block_Size - In_Block;
            In_File_Space : constant Inode_Length := State.Inode.Size - Inode_Length (File_Pos);
            In_Buf_Space : constant Positive := Buf'Last - Pos + 1;
            Len_Here : Positive;
         begin
            Len_Here := In_Block_Space;
            if In_File_Space < Inode_Length (Len_Here) then
               Len_Here := Positive (In_File_Space);
            end if;
            if In_Buf_Space < Len_Here then
               Len_Here := In_Buf_Space;
            end if;
            if File_Offset'Last - File_Pos < File_Length (Len_Here) then
               Len_Here := Positive (File_Offset'Last - File_Pos);
            end if;

            declare
               Last : constant Index_Type := Pos + Len_Here - 1;
               Cache_Start, Cache_End : Max_Block_Index;
               Physical : FSBlock_Offset;
               Success : Boolean;
            begin
               if State.Inode.Map_Cache.Logical = Block_Offset (Logical) then
                  Physical := State.Inode.Map_Cache.Phys;
                  Success := True;
               elsif State.Inode.Use_Extents then
                  Extent_Block_Map (State, Logical, Physical, Success);
               else
                  Ext2_Block_Map (State, Logical, Physical, Success);
               end if;
               exit when not Success;
               State.Inode.Map_Cache := (Phys => Physical, Logical => Block_Offset (Logical));

               if Physical > 0 then
                  Cache_FSBlock
                    (Static      => Static,
                     Cache       => State.Cache,
                     Phys        => Physical,
                     Level       => File_Cache_Level,
                     Cache_Start => Cache_Start,
                     Cache_End   => Cache_End,
                     Success     => Success);
                  pragma Assert (Cache_Start <= Cache_End - (In_Block + Len_Here - 1));
                  exit when not Success;

                  Buf (Pos .. Last) := Cache (
                     Cache_Start + In_Block .. Cache_Start + In_Block + Len_Here - 1);
               else
                  -- Treat unallocated and unwritten blocks as all 00 (sparse files).
                  Buf (Pos .. Last) := (others => 16#00#);
               end if;

               File_Pos := File_Pos + File_Length (Len_Here);
               Pos := Pos + Len_Here;
               Len := Pos - Buf'First;
            end;
         end;
      end loop;
      Buf (Pos .. Buf'Last) := (others => 16#00#);
   end Read;

   --------------------------------------------------------------------------

   package C is new VFS (T => T, Initial => (S => Unmounted, others => <>));

   function C_Mount return int
   with
      Export,
      Convention => C,
      External_Name => "ext2fs_mount";
   function C_Mount return int
   with
      SPARK_Mode => Off
   is
   begin
      return C.C_Mount;
   end C_Mount;

   function C_Open (File_Path : System.Address) return int
   with
      Export,
      Convention => C,
      External_Name => "ext2fs_dir";
   function C_Open (File_Path : System.Address) return int
   with
      SPARK_Mode => Off
   is
   begin
      return C.C_Open (File_Path);
   end C_Open;

   function C_Read (Buf : System.Address; Len : int) return int
   with
      Export,
      Convention => C,
      External_Name => "ext2fs_read";
   function C_Read (Buf : System.Address; Len : int) return int
   with
      SPARK_Mode => Off
   is
   begin
      return C.C_Read (Buf, Len);
   end C_Read;

end FILO.FS.Ext2;
