All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ext4 extent support
@ 2008-07-04 17:59 Bean
  2008-07-04 18:39 ` Robert Millan
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Bean @ 2008-07-04 17:59 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 59 bytes --]

Hi,

This patch add support for extents in ext4.

-- 
Bean

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: extent.diff --]
[-- Type: text/x-diff; name=extent.diff, Size: 3839 bytes --]

diff --git a/fs/ext2.c b/fs/ext2.c
index 22fd272..3518dcf 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -86,6 +86,8 @@
 #define EXT3_JOURNAL_FLAG_DELETED	4
 #define EXT3_JOURNAL_FLAG_LAST_TAG	8
 
+#define EXT4_EXTENTS_FLAG		0x80000
+
 /* The ext2 superblock.  */
 struct grub_ext2_sblock
 {
@@ -226,6 +228,33 @@ struct grub_ext3_journal_sblock
   grub_uint32_t start;
 };
 
+#define EXT4_EXT_MAGIC		0xf30a
+
+struct grub_ext4_extent_header
+{
+  grub_uint16_t magic;
+  grub_uint16_t entries;
+  grub_uint16_t max;
+  grub_uint16_t depth;
+  grub_uint32_t generation;
+};
+
+struct grub_ext4_extent
+{
+  grub_uint32_t block;
+  grub_uint16_t len;
+  grub_uint16_t start_hi;
+  grub_uint32_t start;
+};
+
+struct grub_ext4_extent_idx
+{
+  grub_uint32_t block;
+  grub_uint32_t leaf;
+  grub_uint16_t leaf_hi;
+  grub_uint16_t unused;
+};
+
 struct grub_fshelp_node
 {
   struct grub_ext2_data *data;
@@ -262,6 +291,46 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
 			 sizeof (struct grub_ext2_block_group), (char *) blkgrp);
 }
 
+static struct grub_ext4_extent_header *
+grub_ext4_find_leaf (struct grub_ext2_data *data,
+                     struct grub_ext4_extent_header *ext_block,
+                     grub_uint32_t fileblock)
+{
+  char buf[EXT2_BLOCK_SIZE(data)];
+  struct grub_ext4_extent_idx *index;
+
+  while (1)
+    {
+      int i;
+      grub_disk_addr_t block;
+
+      index = (struct grub_ext4_extent_idx *) (ext_block + 1);
+
+      if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC)
+        return 0;
+
+      if (ext_block->depth == 0)
+        return ext_block;
+
+      for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++)
+        {
+          if (fileblock < grub_le_to_cpu32(index[i].block))
+            break;
+        }
+
+      if (i == 0)
+        return 0;
+
+      block = grub_le_to_cpu16 (index[i].leaf_hi);
+      block = (block << 32) + grub_le_to_cpu32 (index[i].leaf);
+      if (grub_disk_read (data->disk,
+                          block << LOG2_EXT2_BLOCK_SIZE (data),
+                          0, sizeof (buf), buf))
+        return 0;
+
+      ext_block = (struct grub_ext4_extent_header *) buf;
+    }
+}
 
 static grub_disk_addr_t
 grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
@@ -272,6 +341,41 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
   unsigned int blksz = EXT2_BLOCK_SIZE (data);
   int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
   
+  if (inode->flags & EXT4_EXTENTS_FLAG)
+    {
+      struct grub_ext4_extent_header *leaf;
+      struct grub_ext4_extent *ext;
+      int i;
+
+      leaf = grub_ext4_find_leaf (data,
+                                  (struct grub_ext4_extent_header *) inode->blocks.dir_blocks,
+                                  fileblock);
+      if (! leaf)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "invalid extent");
+          return -1;
+        }
+
+      ext = (struct grub_ext4_extent *) (leaf + 1);
+      for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++)
+        if ((fileblock >= grub_le_to_cpu32 (ext[i].block)) &&
+            (fileblock < grub_le_to_cpu32 (ext[i].block) +
+             grub_le_to_cpu16 (ext[i].len)) &&
+            ((grub_le_to_cpu16 (ext[i].len) >> 15) == 0))
+          {
+            grub_disk_addr_t start;
+
+            start = grub_le_to_cpu16 (ext[i].start_hi);
+            start = (start << 32) + grub_le_to_cpu32 (ext[i].start);
+            return fileblock - grub_le_to_cpu32 (ext[i].block) + start;
+          }
+
+
+
+      grub_printf ("HH\n");
+      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                         "ext2fs doesn't support extents");
+    }
   /* Direct blocks.  */
   if (fileblock < INDIRECT_BLOCKS)
     blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);

^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2008-07-13  1:17 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-04 17:59 [PATCH] ext4 extent support Bean
2008-07-04 18:39 ` Robert Millan
2008-07-04 18:47   ` Bean
2008-07-05  9:39 ` Felix Zielcke
2008-07-05 13:25   ` Javier Martín
2008-07-05 17:15     ` Felix Zielcke
2008-07-05 18:09       ` Javier Martín
2008-07-06  4:51         ` Bean
2008-07-06 13:12           ` Felix Zielcke
2008-07-06  8:44         ` Felix Zielcke
2008-07-05 11:01 ` Marco Gerards
2008-07-05 17:25   ` Bean
2008-07-10 21:30 ` Felix Zielcke
2008-07-11  7:25   ` Bean
2008-07-11  7:35     ` Felix Zielcke
2008-07-11  8:17       ` Bean
2008-07-11  8:39         ` Felix Zielcke
2008-07-11 15:34           ` Bean
2008-07-11 17:11             ` Felix Zielcke
2008-07-11 17:42               ` Bean
2008-07-13  1:17                 ` Bean

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.