* grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common code for indirect block handling.
Saves 185 bytes on compressed image.
This commit is contained in:
parent
e6050a683c
commit
5da5517288
2 changed files with 44 additions and 80 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2013-11-14 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common
|
||||||
|
code for indirect block handling.
|
||||||
|
|
||||||
|
Saves 185 bytes on compressed image.
|
||||||
|
|
||||||
2013-11-13 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
2013-11-13 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
||||||
|
|
||||||
Fix make clean.
|
Fix make clean.
|
||||||
|
|
|
@ -397,9 +397,12 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
{
|
{
|
||||||
struct grub_ext2_data *data = node->data;
|
struct grub_ext2_data *data = node->data;
|
||||||
struct grub_ext2_inode *inode = &node->inode;
|
struct grub_ext2_inode *inode = &node->inode;
|
||||||
grub_disk_addr_t blknr = -1;
|
|
||||||
unsigned int blksz = EXT2_BLOCK_SIZE (data);
|
unsigned int blksz = EXT2_BLOCK_SIZE (data);
|
||||||
|
grub_disk_addr_t blksz_quarter = blksz / 4;
|
||||||
int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
|
int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
|
||||||
|
int log_perblock = log2_blksz + 9 - 2;
|
||||||
|
grub_uint32_t indir;
|
||||||
|
int shift;
|
||||||
|
|
||||||
if (inode->flags & grub_cpu_to_le32_compile_time (EXT4_EXTENTS_FLAG))
|
if (inode->flags & grub_cpu_to_le32_compile_time (EXT4_EXTENTS_FLAG))
|
||||||
{
|
{
|
||||||
|
@ -448,96 +451,50 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Direct blocks. */
|
/* Direct blocks. */
|
||||||
if (fileblock < INDIRECT_BLOCKS)
|
if (fileblock < INDIRECT_BLOCKS)
|
||||||
blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);
|
return grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);
|
||||||
|
fileblock -= INDIRECT_BLOCKS;
|
||||||
/* Indirect. */
|
/* Indirect. */
|
||||||
else if (fileblock < INDIRECT_BLOCKS + blksz / 4)
|
if (fileblock < blksz_quarter)
|
||||||
{
|
{
|
||||||
grub_uint32_t indir;
|
indir = inode->blocks.indir_block;
|
||||||
|
shift = 0;
|
||||||
if (grub_disk_read (data->disk,
|
goto indirect;
|
||||||
((grub_disk_addr_t)
|
|
||||||
grub_le_to_cpu32 (inode->blocks.indir_block))
|
|
||||||
<< log2_blksz,
|
|
||||||
(fileblock - INDIRECT_BLOCKS) * sizeof (indir),
|
|
||||||
sizeof (indir), &indir))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
blknr = grub_le_to_cpu32 (indir);
|
|
||||||
}
|
}
|
||||||
|
fileblock -= blksz_quarter;
|
||||||
/* Double indirect. */
|
/* Double indirect. */
|
||||||
else if (fileblock < INDIRECT_BLOCKS
|
if (fileblock < blksz_quarter * blksz_quarter)
|
||||||
+ blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1))
|
|
||||||
{
|
{
|
||||||
int log_perblock = log2_blksz + 9 - 2;
|
indir = inode->blocks.double_indir_block;
|
||||||
grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS
|
shift = 1;
|
||||||
+ blksz / 4);
|
goto indirect;
|
||||||
grub_uint32_t indir;
|
|
||||||
|
|
||||||
if (grub_disk_read (data->disk,
|
|
||||||
((grub_disk_addr_t)
|
|
||||||
grub_le_to_cpu32 (inode->blocks.double_indir_block))
|
|
||||||
<< log2_blksz,
|
|
||||||
(rblock >> log_perblock) * sizeof (indir),
|
|
||||||
sizeof (indir), &indir))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
if (grub_disk_read (data->disk,
|
|
||||||
((grub_disk_addr_t)
|
|
||||||
grub_le_to_cpu32 (indir))
|
|
||||||
<< log2_blksz,
|
|
||||||
(rblock & ((1 << log_perblock) - 1)) * sizeof (indir),
|
|
||||||
sizeof (indir), &indir))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
|
|
||||||
blknr = grub_le_to_cpu32 (indir);
|
|
||||||
}
|
}
|
||||||
/* triple indirect. */
|
fileblock -= blksz_quarter * blksz_quarter;
|
||||||
else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1)
|
/* Triple indirect. */
|
||||||
+ ((grub_disk_addr_t) blksz / 4) * ((grub_disk_addr_t) blksz / 4)
|
if (fileblock < blksz_quarter * blksz_quarter * (blksz_quarter + 1))
|
||||||
* ((grub_disk_addr_t) blksz / 4 + 1))
|
|
||||||
{
|
{
|
||||||
int log_perblock = log2_blksz + 9 - 2;
|
indir = inode->blocks.triple_indir_block;
|
||||||
grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
|
shift = 2;
|
||||||
* (blksz / 4 + 1));
|
goto indirect;
|
||||||
grub_uint32_t indir;
|
|
||||||
|
|
||||||
if (grub_disk_read (data->disk,
|
|
||||||
((grub_disk_addr_t)
|
|
||||||
grub_le_to_cpu32 (inode->blocks.triple_indir_block))
|
|
||||||
<< log2_blksz,
|
|
||||||
((rblock >> log_perblock) >> log_perblock)
|
|
||||||
* sizeof (indir), sizeof (indir), &indir))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
if (grub_disk_read (data->disk,
|
|
||||||
((grub_disk_addr_t)
|
|
||||||
grub_le_to_cpu32 (indir))
|
|
||||||
<< log2_blksz,
|
|
||||||
((rblock >> log_perblock)
|
|
||||||
& ((1 << log_perblock) - 1)) * sizeof (indir),
|
|
||||||
sizeof (indir), &indir))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
if (grub_disk_read (data->disk,
|
|
||||||
((grub_disk_addr_t)
|
|
||||||
grub_le_to_cpu32 (indir))
|
|
||||||
<< log2_blksz,
|
|
||||||
(rblock & ((1 << log_perblock) - 1))
|
|
||||||
* sizeof (indir), sizeof (indir), &indir))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
blknr = grub_le_to_cpu32 (indir);
|
|
||||||
}
|
}
|
||||||
else
|
return grub_error (GRUB_ERR_BAD_FS,
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS,
|
|
||||||
"ext2fs doesn't support quadruple indirect blocks");
|
"ext2fs doesn't support quadruple indirect blocks");
|
||||||
}
|
|
||||||
|
|
||||||
return blknr;
|
indirect:
|
||||||
|
do {
|
||||||
|
if (grub_disk_read (data->disk,
|
||||||
|
((grub_disk_addr_t) grub_le_to_cpu32 (indir))
|
||||||
|
<< log2_blksz,
|
||||||
|
((fileblock >> (log_perblock * shift))
|
||||||
|
& ((1 << log_perblock) - 1))
|
||||||
|
* sizeof (indir),
|
||||||
|
sizeof (indir), &indir))
|
||||||
|
return grub_errno;
|
||||||
|
} while (shift--);
|
||||||
|
|
||||||
|
return grub_le_to_cpu32 (indir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read LEN bytes from the file described by DATA starting with byte
|
/* Read LEN bytes from the file described by DATA starting with byte
|
||||||
|
|
Loading…
Reference in a new issue