[arch-commits] Commit in grub/trunk (PKGBUILD ext4.patch)

Tobias Powalowski tpowa at archlinux.org
Mon Dec 29 18:25:08 UTC 2008


    Date: Monday, December 29, 2008 @ 13:25:08
  Author: tpowa
Revision: 22874

upgpkg: grub 0.97-15

Added:
  grub/trunk/ext4.patch
Modified:
  grub/trunk/PKGBUILD

------------+
 PKGBUILD   |   12 +-
 ext4.patch |  263 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 271 insertions(+), 4 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2008-12-29 14:54:17 UTC (rev 22873)
+++ PKGBUILD	2008-12-29 18:25:08 UTC (rev 22874)
@@ -3,7 +3,7 @@
 
 pkgname=grub
 pkgver=0.97
-pkgrel=14
+pkgrel=15
 pkgdesc="A GNU multiboot boot loader"
 arch=('i686' 'x86_64')
 license=('GPL')
@@ -19,7 +19,8 @@
         special-devices.patch
         more-raid.patch
         intelmac.patch
-        grub-inode-size.patch)
+        grub-inode-size.patch
+	ext4.patch)
 backup=('boot/grub/menu.lst')
 install=grub.install
 md5sums=('cd3f3eb54446be6003156158d51f4884'
@@ -31,7 +32,8 @@
          '49f6d4bcced0bc8bbcff273f3254bbfa'
          'f41f702014a064918d7afc6fc23baa6e'
          '175dc6b9f4ab94e8056c3afb3e34460a'
-         'ada26cbc681907823cc4ff2a55b97866')
+         'ada26cbc681907823cc4ff2a55b97866'
+         '39e0f9a05b7e04aceb24fc7bc4893e3d')
 
 build() {
   cd $srcdir/$pkgname-$pkgver
@@ -39,7 +41,6 @@
   #set destination architecture here
   DESTARCH="i686"
   #DESTARCH="x86_64"
-
   # optimizations break the build -- disable them
   # adding special devices to grub, patches are from fedora
   patch -Np1 -i ../special-devices.patch || return 1
@@ -48,6 +49,9 @@
   patch -Np1 -i ../intelmac.patch || return 1
   # Add support for bigger inode size to e2fs_stage1_5
   patch -Np1 -i ../grub-inode-size.patch || return 1
+  # Add ext4 support
+  # http://www.mail-archive.com/bug-grub@gnu.org/msg11458.html
+  patch -Np1 -i ../ext4.patch || return 1
 
   #arch64 fixes for static build
   if [ "$CARCH" = "x86_64" ]; then

Added: ext4.patch
===================================================================
--- ext4.patch	                        (rev 0)
+++ ext4.patch	2008-12-29 18:25:08 UTC (rev 22874)
@@ -0,0 +1,263 @@
+diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
+--- grub-0.97/stage2/fsys_ext2fs.c      2004-08-08 20:19:18.000000000 +0200
++++ grub-0.97-patch/stage2/fsys_ext2fs.c        2007-12-29 16:25:19.000000000 
++0100
+@@ -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,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()
+ */
+--- grub-0.97/stage2/fsys_ext2fs.c~	2008-12-28 20:19:00.000000000 +0100
++++ grub-0.97/stage2/fsys_ext2fs.c	2008-12-28 20:19:00.000000000 +0100
+@@ -366,83 +366,106 @@
+     }
+   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))
++  /* standard ext2 inode */
++  if (!(INODE->i_flags & EXT4_EXTENTS_FL))
+     {
+-      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)];
+-    }
+-  /* 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;
++       [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 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 */




More information about the arch-commits mailing list