Please test the attached patch

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

=== modified file 'grub-core/fs/ext2.c'
--- grub-core/fs/ext2.c	2010-09-14 19:07:39 +0000
+++ grub-core/fs/ext2.c	2010-10-26 09:23:09 +0000
@@ -229,7 +229,7 @@
   };
   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 @@
       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 @@
 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_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;
 

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to