grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] * grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common code for indirect block handling.
@ 2013-11-13 11:33 Colin Watson
  2013-11-13 17:58 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 2+ messages in thread
From: Colin Watson @ 2013-11-13 11:33 UTC (permalink / raw)
  To: grub-devel

Saves 185 bytes on compressed image.
---
 ChangeLog           |   7 ++++
 grub-core/fs/ext2.c | 119 +++++++++++++++++-----------------------------------
 2 files changed, 45 insertions(+), 81 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 716f69c..4454fd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2013-11-13  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  Colin Watson  <cjwatson@ubuntu.com>
+
 	* util/grub-editenv.c (help_filter, argp): Document how to delete
 	the whole environment block.
 	Reported by Dan Jacobson.  Fixes Debian bug #726265.
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
index aba5cb1..5f7a2b9 100644
--- a/grub-core/fs/ext2.c
+++ b/grub-core/fs/ext2.c
@@ -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_inode *inode = &node->inode;
-  grub_disk_addr_t blknr = -1;
   unsigned int blksz = EXT2_BLOCK_SIZE (data);
+  grub_disk_addr_t blksz_quarter = blksz / 4;
   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))
     {
@@ -448,96 +451,50 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
 
       return ret;
     }
+
   /* Direct 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.  */
-  else if (fileblock < INDIRECT_BLOCKS + blksz / 4)
+  if (fileblock < blksz_quarter)
     {
-      grub_uint32_t indir;
-
-      if (grub_disk_read (data->disk,
-			  ((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);
+      indir = inode->blocks.indir_block;
+      shift = 0;
+      goto indirect;
     }
+  fileblock -= blksz_quarter;
   /* Double indirect.  */
-  else if (fileblock < INDIRECT_BLOCKS
-	   + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1))
+  if (fileblock < blksz_quarter * blksz_quarter)
     {
-      int log_perblock = log2_blksz + 9 - 2;
-      grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS
-					     + blksz / 4);
-      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);
+      indir = inode->blocks.double_indir_block;
+      shift = 1;
+      goto indirect;
     }
-  /* triple indirect.  */
-  else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1)
-	   + ((grub_disk_addr_t) blksz / 4) * ((grub_disk_addr_t) blksz / 4)
-	   * ((grub_disk_addr_t) blksz / 4 + 1))
+  fileblock -= blksz_quarter * blksz_quarter;
+  /* Triple indirect.  */
+  if (fileblock < blksz_quarter * blksz_quarter * (blksz_quarter + 1))
     {
-      int log_perblock = log2_blksz + 9 - 2;
-      grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
-					     * (blksz / 4 + 1));
-      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);
+      indir = inode->blocks.triple_indir_block;
+      shift = 2;
+      goto indirect;
     }
-  else
-    {
-      grub_error (GRUB_ERR_BAD_FS,
-		  "ext2fs doesn't support quadruple indirect blocks");
-    }
-
-  return blknr;
+  return grub_error (GRUB_ERR_BAD_FS,
+		     "ext2fs doesn't support quadruple indirect blocks");
+
+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
-- 
1.8.4.3


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] * grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common code for indirect block handling.
  2013-11-13 11:33 [PATCH] * grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common code for indirect block handling Colin Watson
@ 2013-11-13 17:58 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 2+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-11-13 17:58 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 5953 bytes --]

On 13.11.2013 12:33, Colin Watson wrote:
> Saves 185 bytes on compressed image.
Go ahead.
> ---
>  ChangeLog           |   7 ++++
>  grub-core/fs/ext2.c | 119 +++++++++++++++++-----------------------------------
>  2 files changed, 45 insertions(+), 81 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 716f69c..4454fd8 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,12 @@
>  2013-11-13  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  Colin Watson  <cjwatson@ubuntu.com>
> +
>  	* util/grub-editenv.c (help_filter, argp): Document how to delete
>  	the whole environment block.
>  	Reported by Dan Jacobson.  Fixes Debian bug #726265.
> diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
> index aba5cb1..5f7a2b9 100644
> --- a/grub-core/fs/ext2.c
> +++ b/grub-core/fs/ext2.c
> @@ -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_inode *inode = &node->inode;
> -  grub_disk_addr_t blknr = -1;
>    unsigned int blksz = EXT2_BLOCK_SIZE (data);
> +  grub_disk_addr_t blksz_quarter = blksz / 4;
>    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))
>      {
> @@ -448,96 +451,50 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
>  
>        return ret;
>      }
> +
>    /* Direct 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.  */
> -  else if (fileblock < INDIRECT_BLOCKS + blksz / 4)
> +  if (fileblock < blksz_quarter)
>      {
> -      grub_uint32_t indir;
> -
> -      if (grub_disk_read (data->disk,
> -			  ((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);
> +      indir = inode->blocks.indir_block;
> +      shift = 0;
> +      goto indirect;
>      }
> +  fileblock -= blksz_quarter;
>    /* Double indirect.  */
> -  else if (fileblock < INDIRECT_BLOCKS
> -	   + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1))
> +  if (fileblock < blksz_quarter * blksz_quarter)
>      {
> -      int log_perblock = log2_blksz + 9 - 2;
> -      grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS
> -					     + blksz / 4);
> -      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);
> +      indir = inode->blocks.double_indir_block;
> +      shift = 1;
> +      goto indirect;
>      }
> -  /* triple indirect.  */
> -  else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1)
> -	   + ((grub_disk_addr_t) blksz / 4) * ((grub_disk_addr_t) blksz / 4)
> -	   * ((grub_disk_addr_t) blksz / 4 + 1))
> +  fileblock -= blksz_quarter * blksz_quarter;
> +  /* Triple indirect.  */
> +  if (fileblock < blksz_quarter * blksz_quarter * (blksz_quarter + 1))
>      {
> -      int log_perblock = log2_blksz + 9 - 2;
> -      grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
> -					     * (blksz / 4 + 1));
> -      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);
> +      indir = inode->blocks.triple_indir_block;
> +      shift = 2;
> +      goto indirect;
>      }
> -  else
> -    {
> -      grub_error (GRUB_ERR_BAD_FS,
> -		  "ext2fs doesn't support quadruple indirect blocks");
> -    }
> -
> -  return blknr;
> +  return grub_error (GRUB_ERR_BAD_FS,
> +		     "ext2fs doesn't support quadruple indirect blocks");
> +
> +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
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 291 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-11-13 17:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-13 11:33 [PATCH] * grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common code for indirect block handling Colin Watson
2013-11-13 17:58 ` Vladimir 'φ-coder/phcoder' Serbinenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).