[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[1699] 2008-07-13 Bean <address@hidden>
From: |
Bean |
Subject: |
[1699] 2008-07-13 Bean <address@hidden> |
Date: |
Sun, 13 Jul 2008 01:13:13 +0000 |
Revision: 1699
http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1699
Author: bean
Date: 2008-07-13 01:13:12 +0000 (Sun, 13 Jul 2008)
Log Message:
-----------
2008-07-13 Bean <address@hidden>
* fs/ext2.c (EXT4_EXTENTS_FLAG): New macro.
(grub_ext4_extent_header): New structure.
(grub_ext4_extent): Likewise.
(grub_ext4_extent_idx): Likewise.
(grub_ext4_find_leaf): New function.
(grub_ext2_read_block): Handle extents.
Modified Paths:
--------------
trunk/grub2/ChangeLog
trunk/grub2/fs/ext2.c
Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog 2008-07-12 15:40:50 UTC (rev 1698)
+++ trunk/grub2/ChangeLog 2008-07-13 01:13:12 UTC (rev 1699)
@@ -1,3 +1,12 @@
+2008-07-13 Bean <address@hidden>
+
+ * fs/ext2.c (EXT4_EXTENTS_FLAG): New macro.
+ (grub_ext4_extent_header): New structure.
+ (grub_ext4_extent): Likewise.
+ (grub_ext4_extent_idx): Likewise.
+ (grub_ext4_find_leaf): New function.
+ (grub_ext2_read_block): Handle extents.
+
2008-07-12 Robert Millan <address@hidden>
* util/i386/pc/grub-mkrescue.in: s/grub-install/grub-mkrescue/g.
Modified: trunk/grub2/fs/ext2.c
===================================================================
--- trunk/grub2/fs/ext2.c 2008-07-12 15:40:50 UTC (rev 1698)
+++ trunk/grub2/fs/ext2.c 2008-07-13 01:13:12 UTC (rev 1699)
@@ -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 @@
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,7 +291,46 @@
sizeof (struct grub_ext2_block_group), (char *)
blkgrp);
}
+static struct grub_ext4_extent_header *
+grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf,
+ struct grub_ext4_extent_header *ext_block,
+ grub_uint32_t fileblock)
+{
+ 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, EXT2_BLOCK_SIZE(data), 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 +340,50 @@
unsigned int blksz = EXT2_BLOCK_SIZE (data);
int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
+ if (inode->flags & EXT4_EXTENTS_FLAG)
+ {
+ char buf[EXT2_BLOCK_SIZE(data)];
+ struct grub_ext4_extent_header *leaf;
+ struct grub_ext4_extent *ext;
+ int i;
+
+ leaf = grub_ext4_find_leaf (data, buf,
+ (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))
+ break;
+ }
+
+ if (--i >= 0)
+ {
+ fileblock -= grub_le_to_cpu32 (ext[i].block);
+ if (fileblock >= grub_le_to_cpu16 (ext[i].len))
+ return 0;
+ else
+ {
+ 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 + start;
+ }
+ }
+ else
+ {
+ grub_error (GRUB_ERR_BAD_FS, "something wrong with extent");
+ return -1;
+ }
+ }
/* Direct blocks. */
if (fileblock < INDIRECT_BLOCKS)
blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [1699] 2008-07-13 Bean <address@hidden>,
Bean <=