ext2: Better organize per inode info
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
index 93fff8a..32a16c3 100644
--- a/src/filo-fs-ext2.adb
+++ b/src/filo-fs-ext2.adb
@@ -7,6 +7,7 @@
-- 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;
@@ -188,6 +189,19 @@
Physical : out FSBlock_Offset;
Success : out Boolean)
is
+ 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 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.Extents));
+
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);
@@ -221,7 +235,7 @@
Logical_Rest : FSBlock_Logical := Logical;
begin
if Logical_Rest < Direct_Blocks then
- Physical := FSBlock_Offset (State.Direct_Blocks (Natural (Logical)));
+ Physical := FSBlock_Offset (I_Blocks (State).Direct_Blocks (Natural (Logical)));
Success := True;
return;
end if;
@@ -229,7 +243,7 @@
Logical_Rest := Logical_Rest - Direct_Blocks;
if Logical_Rest < Addr_Per_Block then
Indirect_Block_Lookup
- (Indirect_Block_Phys => FSBlock_Offset (State.Indirect_Block),
+ (Indirect_Block_Phys => FSBlock_Offset (I_Blocks (State).Indirect_Block),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest),
Level => 0,
Logical_Off => Logical - Logical_Rest,
@@ -241,7 +255,7 @@
Logical_Rest := Logical_Rest - Addr_Per_Block;
if Logical_Rest < Addr_Per_Block ** 2 then
Indirect_Block_Lookup
- (Indirect_Block_Phys => FSBlock_Offset (State.Double_Indirect),
+ (Indirect_Block_Phys => FSBlock_Offset (I_Blocks (State).Double_Indirect),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest / Addr_Per_Block),
Level => 1,
Logical_Off => Logical - Logical_Rest,
@@ -264,7 +278,7 @@
Logical_Rest := Logical_Rest - Addr_Per_Block ** 2;
if Logical_Rest < Addr_Per_Block ** 3 then
Indirect_Block_Lookup
- (Indirect_Block_Phys => FSBlock_Offset (State.Triple_Indirect),
+ (Indirect_Block_Phys => FSBlock_Offset (I_Blocks (State).Triple_Indirect),
Addr_In_Block => Addr_In_Block_Range (Logical_Rest / Addr_Per_Block ** 2),
Level => 2,
Logical_Off => Logical - Logical_Rest,
@@ -466,10 +480,10 @@
end;
end Next_Ref;
- Inode_Magic : constant Unsigned_16 := Header_Magic (State.Inode_Extents);
- Inode_Entries : constant Natural := Header_Entries (State.Inode_Extents);
- First_Logical : constant FSBlock_Logical := Extent_Logical (State.Inode_Extents, 1);
- Depth : Natural := Header_Depth (State.Inode_Extents);
+ Inode_Magic : constant Unsigned_16 := Header_Magic (State.Inode.Extents);
+ Inode_Entries : constant Natural := Header_Entries (State.Inode.Extents);
+ First_Logical : constant FSBlock_Logical := Extent_Logical (State.Inode.Extents, 1);
+ Depth : Natural := Header_Depth (State.Inode.Extents);
Cache_Start, Cache_End : Max_Block_Index;
Logical_Off, Length : FSBlock_Logical;
@@ -478,21 +492,21 @@
Success :=
Inode_Magic = Extent_Header_Magic and then
Inode_Entries > 0 and then
- Inode_Entries < State.Inode_Extents'Length / Extent_Header_Size and then
+ Inode_Entries < State.Inode.Extents'Length / Extent_Header_Size and then
First_Logical <= Logical;
if not Success then
Physical := 0;
return;
end if;
- Idx := Bin_Search (State.Inode_Extents, Inode_Entries);
+ Idx := Bin_Search (State.Inode.Extents, Inode_Entries);
if Depth = 0 then
- Physical := Extent_Physical (State.Inode_Extents, Idx);
- Logical_Off := Extent_Logical (State.Inode_Extents, Idx);
- Length := Extent_Length (State.Inode_Extents, Idx);
+ Physical := Extent_Physical (State.Inode.Extents, Idx);
+ Logical_Off := Extent_Logical (State.Inode.Extents, Idx);
+ Length := Extent_Length (State.Inode.Extents, Idx);
else
- Physical := Index_Physical (State.Inode_Extents, Idx);
- Logical_Off := Index_Logical (State.Inode_Extents, Idx);
+ Physical := Index_Physical (State.Inode.Extents, Idx);
+ Logical_Off := Index_Logical (State.Inode.Extents, Idx);
loop
Depth := Depth - 1;
Next_Ref
diff --git a/src/filo-fs-ext2.ads b/src/filo-fs-ext2.ads
index 63f817e..b1f1544 100644
--- a/src/filo-fs-ext2.ads
+++ b/src/filo-fs-ext2.ads
@@ -59,15 +59,17 @@
subtype Block_Cache_Index is Natural range 0 .. 63;
type Block_Cache_Type is array (Block_Cache_Index) of FSBlock_Logical;
- Direct_Blocks : constant := 12;
- type Direct_Blocks_Array is array (Natural range 0 .. Direct_Blocks - 1) of Unsigned_32;
-
-- Same as the 12 direct + 3 indirect blocks times 4B:
subtype Inode_Extents_Index is Natural range 0 .. 59;
+ subtype Inode_Extents is Buffer_Type (Inode_Extents_Index);
subtype Inode_Size is Positive range 128 .. Positive (Unsigned_16'Last);
subtype Desc_Size is Positive range 32 .. 2 ** 15; -- power-of-2 that fits in 16 bits
+ type Inode_Info is record
+ Extents : Buffer_Type (Inode_Extents_Index) := (others => 16#00#);
+ end record;
+
type T is record
S : State;
Part_Len : Partition_Length := 0;
@@ -78,11 +80,7 @@
Desc_Size : Ext2.Desc_Size := Ext2.Desc_Size'First;
Feature_Extents : Boolean := False;
Feature_64Bit : Boolean := False;
- Direct_Blocks : Direct_Blocks_Array := (others => 0);
- Indirect_Block : Unsigned_32 := 0;
- Double_Indirect : Unsigned_32 := 0;
- Triple_Indirect : Unsigned_32 := 0;
- Inode_Extents : Buffer_Type (Inode_Extents_Index) := (others => 16#00#);
+ Inode : Inode_Info := (others => <>);
Block_Cache_Index : Block_Cache_Type := (others => 0);
Block_Cache : Buffer_Type (Max_Block_Index) := (others => 16#00#);
end record;