Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 176097 Details for
Bug 250829
support ext4 extents with sys-boot/grub 0.97
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for booting from ext4
grub-0.97-ext4extents.patch (text/plain), 8.76 KB, created by
Holger Hoffstätte
on 2008-12-21 21:48:51 UTC
(
hide
)
Description:
patch for booting from ext4
Filename:
MIME Type:
Creator:
Holger Hoffstätte
Created:
2008-12-21 21:48:51 UTC
Size:
8.76 KB
patch
obsolete
>diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c >--- grub-0.97/stage2/fsys_ext2fs.c 2008-06-03 12:54:49.502889887 +0200 >+++ grub-0.97-patch/stage2/fsys_ext2fs.c 2008-06-03 13:30:03.296031725 +0200 >@@ -50,6 +50,8 @@ typedef unsigned int __u32; > #define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) > #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) > #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) >+/* Inode flags */ >+#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ > > /* include/linux/ext2_fs.h */ > struct ext2_super_block >@@ -235,7 +237,42 @@ struct ext2_dir_entry > #define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) > #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ > ~EXT2_DIR_ROUND) >+/* linux/ext4_fs_extents.h */ >+/* >+ * This is the extent on-disk structure. >+ * It's used at the bottom of the tree. >+ */ >+struct ext4_extent { >+ __u32 ee_block; /* first logical block extent covers */ >+ __u16 ee_len; /* number of blocks covered by extent */ >+ __u16 ee_start_hi; /* high 16 bits of physical block */ >+ __u32 ee_start; /* low 32 bits of physical block */ >+}; > >+/* >+ * This is index on-disk structure. >+ * It's used at all the levels except the bottom. >+ */ >+struct ext4_extent_idx { >+ __u32 ei_block; /* index covers logical blocks from 'block' */ >+ __u32 ei_leaf; /* pointer to the physical block of the next * >+ * level. leaf or next index could be there */ >+ __u16 ei_leaf_hi; /* high 16 bits of physical block */ >+ __u16 ei_unused; >+}; >+ >+/* >+ * Each block (leaves and indexes), even inode-stored has header. >+ */ >+struct ext4_extent_header { >+ __u16 eh_magic; /* probably will support different formats */ >+ __u16 eh_entries; /* number of valid entries */ >+ __u16 eh_max; /* capacity of store in entries */ >+ __u16 eh_depth; /* has tree real underlying blocks? */ >+ __u32 eh_generation; /* generation of the tree */ >+}; >+ >+#define EXT4_EXT_MAGIC 0xf30a > > /* ext2/super.c */ > #define log2(n) ffz(~(n)) >@@ -327,6 +364,26 @@ ext2_rdfsb (int fsblock, int buffer) > EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer); > } > >+/* Walk through extents index tree to find the good leaf */ >+static struct ext4_extent_header * >+ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block) >+{ >+ int i; >+ struct ext4_extent_idx *index = (struct ext4_extent_idx *) (extent_block + 1); >+ if (extent_block->eh_magic != EXT4_EXT_MAGIC) >+ return NULL; >+ if (extent_block->eh_depth == 0) >+ return extent_block; >+ for (i = 0; i < extent_block->eh_entries; i++) >+ { >+ if (logical_block < index[i].ei_block) >+ break; >+ } >+ if (i == 0 || !ext2_rdfsb(index[i-1].ei_leaf, DATABLOCK1)) >+ return NULL; >+ return (ext4_recurse_extent_index((struct ext4_extent_header *) DATABLOCK1, logical_block)); >+} >+ > /* from > ext2/inode.c:ext2_bmap() > */ >@@ -355,83 +412,93 @@ ext2fs_block_map (int logical_block) > } > printf ("logical block %d\n", logical_block); > #endif /* E2DEBUG */ >- >- /* if it is directly pointed to by the inode, return that physical addr */ >- if (logical_block < EXT2_NDIR_BLOCKS) >- { >-#ifdef E2DEBUG >- printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); >- printf ("returning %d\n", INODE->i_block[logical_block]); >-#endif /* E2DEBUG */ >- return INODE->i_block[logical_block]; >- } >- /* else */ >- logical_block -= EXT2_NDIR_BLOCKS; >- /* try the indirect block */ >- if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) >- { >- if (mapblock1 != 1 >- && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) >- { >- errnum = ERR_FSYS_CORRUPT; >- return -1; >- } >- mapblock1 = 1; >- return ((__u32 *) DATABLOCK1)[logical_block]; >- } >- /* else */ >- logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); >- /* now try the double indirect block */ >- if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) >- { >- int bnum; >- if (mapblock1 != 2 >- && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) >- { >- errnum = ERR_FSYS_CORRUPT; >- return -1; >- } >- mapblock1 = 2; >- if ((bnum = (((__u32 *) DATABLOCK1) >- [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) >- != mapblock2 >- && !ext2_rdfsb (bnum, DATABLOCK2)) >- { >- errnum = ERR_FSYS_CORRUPT; >- return -1; >- } >- mapblock2 = bnum; >- return ((__u32 *) DATABLOCK2) >- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; >- } >- /* else */ >- mapblock2 = -1; >- logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); >- if (mapblock1 != 3 >- && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) >- { >- errnum = ERR_FSYS_CORRUPT; >- return -1; >- } >- mapblock1 = 3; >- if (!ext2_rdfsb (((__u32 *) DATABLOCK1) >- [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) >- * 2)], >- DATABLOCK2)) >- { >- errnum = ERR_FSYS_CORRUPT; >- return -1; >- } >- if (!ext2_rdfsb (((__u32 *) DATABLOCK2) >- [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) >- & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], >- DATABLOCK2)) >- { >+/* standard ext2 inode */ >+if (!(INODE->i_flags & EXT4_EXTENTS_FL)) >+ { >+/* if it is directly pointed to by the inode, return that physical addr */ >+ if (logical_block < EXT2_NDIR_BLOCKS) >+ { >+#ifdef E2DEBUG >+ printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); >+ printf ("returning %d\n", INODE->i_block[logical_block]); >+#endif /* E2DEBUG */ >+ return INODE->i_block[logical_block]; >+ } >+ /* else */ >+ logical_block -= EXT2_NDIR_BLOCKS; >+ /* try the indirect block */ >+ if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) >+ { >+ if (mapblock1 != 1 && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ mapblock1 = 1; >+ return ((__u32 *) DATABLOCK1)[logical_block]; >+ } >+ /* else */ >+ logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); >+ /* now try the double indirect block */ >+ if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) >+ { >+ int bnum; >+ if (mapblock1 != 2 && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ mapblock1 = 2; >+ if ((bnum = (((__u32 *) DATABLOCK1) [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) != mapblock2 && !ext2_rdfsb (bnum, DATABLOCK2)) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ mapblock2 = bnum; >+ return ((__u32 *) DATABLOCK2) [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; >+ } >+ /* else */ >+ mapblock2 = -1; >+ logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); >+ if (mapblock1 != 3 && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ mapblock1 = 3; >+ if (!ext2_rdfsb (((__u32 *) DATABLOCK1) [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)], DATABLOCK2)) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ if (!ext2_rdfsb (((__u32 *) DATABLOCK2) [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], DATABLOCK2)) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ return ((__u32 *) DATABLOCK2) >+ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; >+ } >+ /* inode is in extents format */ >+ else >+ { >+ int i; >+ struct ext4_extent_header *extent_hdr = ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block); >+ struct ext4_extent *extent = (struct ext4_extent *) (extent_hdr + 1); >+ if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC) >+ { >+ errnum = ERR_FSYS_CORRUPT; >+ return -1; >+ } >+ for (i = 0; i<extent_hdr->eh_entries; i++) >+ { >+ if (extent[i].ee_block <= logical_block && logical_block < extent[i].ee_block + extent[i].ee_len && !(extent[i].ee_len>>15)) >+ return (logical_block - extent[i].ee_block + extent[i].ee_start); >+ } >+ /* We should not arrive here */ > errnum = ERR_FSYS_CORRUPT; > return -1; > } >- return ((__u32 *) DATABLOCK2) >- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; > } > > /* preconditions: all preconds of ext2fs_block_map */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 250829
:
176095
| 176097 |
176556