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));
}
{
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]);
+ 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;
% 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;
}
+/* 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
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