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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-11-13 16:11:24 +01:00
parent 5f0c02b3d8
commit 58c184be7b
2 changed files with 48 additions and 4 deletions

View file

@ -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> 2010-11-13 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-install.in: Handle filenames containing spaces. * util/grub-install.in: Handle filenames containing spaces.

View file

@ -229,7 +229,7 @@ struct grub_ext2_inode
}; };
grub_uint32_t version; grub_uint32_t version;
grub_uint32_t acl; grub_uint32_t acl;
grub_uint32_t dir_acl; grub_uint32_t size_high;
grub_uint32_t fragment_addr; grub_uint32_t fragment_addr;
grub_uint32_t osd2[3]; 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]); blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
} }
/* triple indirect. */ /* 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 else
{ {
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"ext2fs doesn't support triple indirect blocks"); "ext2fs doesn't support quadruple indirect blocks");
} }
return blknr; return blknr;
@ -485,11 +516,12 @@ static grub_ssize_t
grub_ext2_read_file (grub_fshelp_node_t node, grub_ext2_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length), 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, return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_ext2_read_block, 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)); LOG2_EXT2_BLOCK_SIZE (node->data));
} }
@ -756,6 +788,7 @@ grub_ext2_open (struct grub_file *file, const char *name)
grub_free (fdiro); grub_free (fdiro);
file->size = grub_le_to_cpu32 (data->inode->size); 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->data = data;
file->offset = 0; file->offset = 0;