]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Support big ext2 files.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 13 Nov 2010 15:11:24 +0000 (16:11 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 13 Nov 2010 15:11:24 +0000 (16:11 +0100)
* grub-core/fs/ext2.c (grub_ext2_inode): Rename dir_acl to size_high.
(grub_ext2_read_block): Support triple indirect blocks.
(grub_ext2_read_file): Use 64-bit types and read size_high.
(grub_ext2_open): Read size_high.
Reported by: Ximin Luo.
Tested by: Manoel Rebelo Abranches.

ChangeLog
grub-core/fs/ext2.c

index 03ff87f74f229005d45f64755081f0c0bd84107d..9fa85cda5329da5fab208f7788678054024ad894 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-11-13  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Support big ext2 files.
+
+       * grub-core/fs/ext2.c (grub_ext2_inode): Rename dir_acl to size_high.
+       (grub_ext2_read_block): Support triple indirect blocks.
+       (grub_ext2_read_file): Use 64-bit types and read size_high.
+       (grub_ext2_open): Read size_high.
+       Reported by: Ximin Luo.
+       Tested by: Manoel Rebelo Abranches.
+
 2010-11-13  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-install.in: Handle filenames containing spaces.
index dfc75c62598309245b9c4d9000129a3cb5480a2e..ed5fafd4c62c14baf90c80a7c5042bbdd22da3ef 100644 (file)
@@ -229,7 +229,7 @@ struct grub_ext2_inode
   };
   grub_uint32_t version;
   grub_uint32_t acl;
-  grub_uint32_t dir_acl;
+  grub_uint32_t size_high;
   grub_uint32_t fragment_addr;
   grub_uint32_t osd2[3];
 };
@@ -470,10 +470,41 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
       blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
     }
   /* triple indirect.  */
+  else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1)
+          + (blksz / 4) * (blksz / 4) * (blksz / 4 + 1))
+    {
+      unsigned int perblock = blksz / 4;
+      unsigned int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
+                                        * (blksz / 4 + 1));
+      grub_uint32_t indir[blksz / 4];
+
+      if (grub_disk_read (data->disk,
+                         ((grub_disk_addr_t)
+                          grub_le_to_cpu32 (inode->blocks.triple_indir_block))
+                         << log2_blksz,
+                         0, blksz, indir))
+       return grub_errno;
+
+      if (grub_disk_read (data->disk,
+                         ((grub_disk_addr_t)
+                          grub_le_to_cpu32 (indir[(rblock / perblock) / perblock]))
+                         << log2_blksz,
+                         0, blksz, indir))
+       return grub_errno;
+
+      if (grub_disk_read (data->disk,
+                         ((grub_disk_addr_t)
+                          grub_le_to_cpu32 (indir[(rblock / perblock) % perblock]))
+                         << log2_blksz,
+                         0, blksz, indir))
+       return grub_errno;
+
+      blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
+    }
   else
     {
       grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                 "ext2fs doesn't support triple indirect blocks");
+                 "ext2fs doesn't support quadruple indirect blocks");
     }
 
   return blknr;
@@ -485,11 +516,12 @@ static grub_ssize_t
 grub_ext2_read_file (grub_fshelp_node_t node,
                     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
                                        unsigned offset, unsigned length),
-                    int pos, grub_size_t len, char *buf)
+                    grub_off_t pos, grub_size_t len, char *buf)
 {
   return grub_fshelp_read_file (node->data->disk, node, read_hook,
                                pos, len, buf, grub_ext2_read_block,
-                               node->inode.size,
+                               grub_cpu_to_le32 (node->inode.size)
+                               | (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32),
                                LOG2_EXT2_BLOCK_SIZE (node->data));
 
 }
@@ -756,6 +788,7 @@ grub_ext2_open (struct grub_file *file, const char *name)
   grub_free (fdiro);
 
   file->size = grub_le_to_cpu32 (data->inode->size);
+  file->size |= ((grub_off_t) grub_le_to_cpu32 (data->inode->size_high)) << 32;
   file->data = data;
   file->offset = 0;