diff options
Diffstat (limited to 'package/grub/patches/020-ext4_support.patch')
-rw-r--r-- | package/grub/patches/020-ext4_support.patch | 267 |
1 files changed, 0 insertions, 267 deletions
diff --git a/package/grub/patches/020-ext4_support.patch b/package/grub/patches/020-ext4_support.patch deleted file mode 100644 index 06cd2c261..000000000 --- a/package/grub/patches/020-ext4_support.patch +++ /dev/null @@ -1,267 +0,0 @@ ---- a/stage2/fsys_ext2fs.c -+++ b/stage2/fsys_ext2fs.c -@@ -51,6 +51,9 @@ typedef unsigned int __u32; - #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 - { -@@ -191,6 +194,42 @@ struct ext2_dir_entry - #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)) -@@ -279,6 +318,27 @@ 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() - */ -@@ -287,7 +347,6 @@ ext2_rdfsb (int fsblock, int buffer) - static int - ext2fs_block_map (int logical_block) - { -- - #ifdef E2DEBUG - unsigned char *i; - for (i = (unsigned char *) INODE; -@@ -308,82 +367,106 @@ 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) -+ if (!(INODE->i_flags & EXT4_EXTENTS_FL)) - { --#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; -+ /* 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)]; -+ [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)) -+ /* 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 */ |