Hi Bean, Bean <[EMAIL PROTECTED]> writes:
> This patch add support for extents in ext4. This is really great! :D Can you also provide a changelog entry? > 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"); Whoops? ;-) > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, > + "ext2fs doesn't support extents"); Why the error? I thought you have added extent support? Doesn't this mean the extent has another error of some kind? -- Marco _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel