Quoting Bean <[EMAIL PROTECTED]>:

This should be all right, but we need to move the journal support from
fshelp.c to disk.c, anyone objects ?

I've converted ext2.c. The patch is attached. The interface should be OK for reiserfs. It looks like the call to grub_fshelp_map_block() from grub_ext2_read_inode() was also wrong. I'm afraid there are some wrong places in reiserfs as well.

I would like to commit the patch as soon as possible. It's a serious issue, and we don't want to scare away potential testers and contributors.

ChangeLog:
        * fs/fshelp.c (grub_fshelp_read): New function.  Implement linear
        disk read with journal translation.
        * fs/ext2.c: Use grub_fshelp_read() instead of grub_disk_read().
        * include/grub/fshelp.h: Declare grub_fshelp_read().

--
Regards,
Pavel Roskin

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..999bd80 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -257,12 +257,11 @@ inline static grub_err_t
 grub_ext2_blockgroup (struct grub_ext2_data *data, int group, 
                      struct grub_ext2_block_group *blkgrp)
 {
-  return grub_disk_read (data->disk,
-                        (grub_fshelp_map_block (data->journal,
-                                                 grub_le_to_cpu32 
(data->sblock.first_data_block) + 1)
-                         << LOG2_EXT2_BLOCK_SIZE (data)),
-                        group * sizeof (struct grub_ext2_block_group), 
-                        sizeof (struct grub_ext2_block_group), (char *) 
blkgrp);
+  return grub_fshelp_read (data->disk, data->journal,
+                          grub_le_to_cpu32 (data->sblock.first_data_block) + 1,
+                          group * sizeof (struct grub_ext2_block_group),
+                          sizeof (struct grub_ext2_block_group),
+                          (char *) blkgrp, LOG2_EXT2_BLOCK_SIZE (data));
 }
 
 
@@ -283,11 +282,9 @@ grub_ext2_read_block (grub_fshelp_node_t node, 
grub_disk_addr_t fileblock)
     {
       grub_uint32_t indir[blksz / 4];
 
-      if (grub_disk_read (data->disk, 
-                         grub_fshelp_map_block(data->journal,
-                                                grub_le_to_cpu32 
(inode->blocks.indir_block))
-                         << log2_blksz,
-                         0, blksz, (char *) indir))
+      if (grub_fshelp_read (data->disk, data->journal,
+                           grub_le_to_cpu32 (inode->blocks.indir_block),
+                           0, blksz, (char *) indir, log2_blksz))
        return grub_errno;
          
       blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
@@ -300,18 +297,14 @@ grub_ext2_read_block (grub_fshelp_node_t node, 
grub_disk_addr_t fileblock)
                                         + blksz / 4);
       grub_uint32_t indir[blksz / 4];
 
-      if (grub_disk_read (data->disk, 
-                         grub_fshelp_map_block(data->journal,
-                                                grub_le_to_cpu32 
(inode->blocks.double_indir_block))
-                         << log2_blksz,
-                         0, blksz, (char *) indir))
+      if (grub_fshelp_read (data->disk, data->journal,
+                           grub_le_to_cpu32 (inode->blocks.double_indir_block),
+                           0, blksz, (char *) indir, log2_blksz))
        return grub_errno;
 
-      if (grub_disk_read (data->disk,
-                         grub_fshelp_map_block(data->journal,
-                                                grub_le_to_cpu32 (indir[rblock 
/ perblock]))
-                         << log2_blksz,
-                         0, blksz, (char *) indir))
+      if (grub_fshelp_read (data->disk, data->journal,
+                           grub_le_to_cpu32 (indir[rblock / perblock]),
+                           0, blksz, (char *) indir, log2_blksz))
        return grub_errno;
 
       
@@ -372,12 +365,11 @@ grub_ext2_read_inode (struct grub_ext2_data *data,
     % inodes_per_block;
   
   /* Read the inode.  */
-  if (grub_disk_read (data->disk, 
-                     grub_fshelp_map_block(data->journal,
-                                            grub_le_to_cpu32 
(blkgrp.inode_table_id) + blkno)
-                      << LOG2_EXT2_BLOCK_SIZE (data),
-                     EXT2_INODE_SIZE (data) * blkoff,
-                     sizeof (struct grub_ext2_inode), (char *) inode))
+  if (grub_fshelp_read (data->disk, data->journal,
+                       grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno,
+                       EXT2_INODE_SIZE (data) * blkoff,
+                       sizeof (struct grub_ext2_inode), (char *) inode,
+                       LOG2_EXT2_BLOCK_SIZE (data)))
     return grub_errno;
   
   return 0;
diff --git a/fs/fshelp.c b/fs/fshelp.c
index faec1f7..52131b0 100644
--- a/fs/fshelp.c
+++ b/fs/fshelp.c
@@ -215,6 +215,45 @@ grub_fshelp_find_file (const char *path, 
grub_fshelp_node_t rootnode,
 }
 
 
+/* Read LEN bytes from the block BLOCK on disk DISK into the buffer BUF,
+   beginning with the block POS.  Apply mappings from LOG.  The blocks
+   have a size of LOG2BLOCKSIZE (in log2).  */
+grub_err_t grub_fshelp_read (grub_disk_t disk, grub_fshelp_journal_t log,
+                            grub_disk_addr_t block, grub_off_t pos,
+                            grub_size_t len, char *buf, int log2blocksize)
+{
+  grub_off_t relblk;
+
+  relblk = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS);
+  block += relblk;
+  pos -= relblk << (log2blocksize + GRUB_DISK_SECTOR_BITS);
+
+  while (len > 0)
+    {
+      grub_err_t ret;
+      grub_size_t size;
+
+      size = (GRUB_DISK_SECTOR_SIZE << log2blocksize) - pos;
+      if (size > len)
+       size = len;
+
+      ret = grub_disk_read (disk,
+                           grub_fshelp_map_block (log, block) << log2blocksize,
+                           pos, size, buf);
+
+      if (ret)
+       return ret;
+
+      block++;
+      pos = 0;
+      buf += size;
+      len -= size;
+    }
+
+  return 0;
+}
+
+
 /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
    beginning with the block POS.  READ_HOOK should be set before
    reading a block from the file.  GET_BLOCK is used to translate file
diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h
index 0120cbf..847f78e 100644
--- a/include/grub/fshelp.h
+++ b/include/grub/fshelp.h
@@ -84,6 +84,15 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
                                    enum grub_fshelp_filetype expect);
 
 
+/* Read LEN bytes from the block BLOCK on disk DISK into the buffer BUF,
+   beginning with the block POS.  Apply mappings from LOG.  The blocks
+   have a size of LOG2BLOCKSIZE (in log2).  */
+grub_err_t
+EXPORT_FUNC(grub_fshelp_read) (grub_disk_t disk, grub_fshelp_journal_t log,
+                              grub_disk_addr_t block, grub_off_t pos,
+                              grub_size_t len, char *buf, int log2blocksize);
+
+
 /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
    beginning with the block POS.  READ_HOOK should be set before
    reading a block from the file.  GET_BLOCK is used to translate file
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to