Implement Ext2.Read()
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index 06909c0..ace8c6a 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -756,9 +756,73 @@
       Buf      :    out Buffer_Type;
       Len      :    out Natural)
    is
+      Pos : Natural;
    begin
-      Buf := (others => 0);
+      if State.Inode.Mode = Fast_Link then
+         if File_Len > State.Inode.Inline'Length or
+            File_Pos >= File_Len then
+            Len := 0;
+         else
+            Len := Natural'Min (Buf'Length, Natural (File_Len - 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 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_File_Space : constant Natural := Natural (File_Len - File_Pos);
+            In_Buf_Space : constant Natural := Buf'Last - Pos + 1;
+            Len_Here : Natural;
+         begin
+            Len_Here := In_Block_Space;
+            if In_File_Space < Len_Here then
+               Len_Here := In_File_Space;
+            end if;
+            if In_Buf_Space < Len_Here then
+               Len_Here := In_Buf_Space;
+            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.Use_Extents then
+                  Extent_Block_Map (State, Logical, Physical, Success);
+               else
+                  Ext2_Block_Map (State, Logical, Physical, Success);
+               end if;
+               if Success then
+                  Cache_FSBlock
+                    (State       => State,
+                     Phys        => Physical,
+                     Level       => Block_Cache_Index'Last,
+                     Cache_Start => Cache_Start,
+                     Cache_End   => Cache_End,
+                     Success     => Success);
+               end if;
+               exit when not Success;
+
+               Buf (Pos .. Last) := State.Block_Cache (
+                  Cache_Start + In_Block .. Cache_Start + In_Block + Len_Here - 1);
+               File_Pos := File_Pos + File_Length (Len_Here);
+               Pos := Pos + Len_Here;
+               Len := Len + Len_Here;
+            end;
+         end;
+      end loop;
+      Buf (Pos .. Buf'Last) := (others => 16#00#);
    end Read;
 
    --------------------------------------------------------------------------