Remove nested functions from disk and file read hooks.

* include/grub/disk.h (grub_disk_read_hook_t): New type.
	(struct grub_disk): Add read_hook_data member.
	* include/grub/file.h (struct grub_file): Likewise.
	* include/grub/fshelp.h (grub_fshelp_read_file): Add read_hook_data
	argument.

	Update all callers.
This commit is contained in:
Colin Watson 2013-02-27 17:19:15 +01:00 committed by Vladimir 'phcoder' Serbinenko
parent df6da5a52d
commit 4eb8b75659
29 changed files with 409 additions and 345 deletions

View file

@ -1,3 +1,15 @@
2013-02-27 Colin Watson <cjwatson@ubuntu.com>
Remove nested functions from disk and file read hooks.
* include/grub/disk.h (grub_disk_read_hook_t): New type.
(struct grub_disk): Add read_hook_data member.
* include/grub/file.h (struct grub_file): Likewise.
* include/grub/fshelp.h (grub_fshelp_read_file): Add read_hook_data
argument.
Update all callers.
2012-02-27 Andrey Borzenkov <arvidjaar@gmail.com> 2012-02-27 Andrey Borzenkov <arvidjaar@gmail.com>
* grub-core/partmap/msdos.c (grub_partition_msdos_iterate): * grub-core/partmap/msdos.c (grub_partition_msdos_iterate):

View file

@ -5,6 +5,10 @@
#if defined(__PPC__) && !defined(__powerpc__) #if defined(__PPC__) && !defined(__powerpc__)
#define __powerpc__ 1 #define __powerpc__ 1
#endif #endif
/* Define to 1 to enable disk cache statistics. */
#define DISK_CACHE_STATS @DISK_CACHE_STATS@
#if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE)
#include <config-util.h> #include <config-util.h>
#define NESTED_FUNC_ATTR #define NESTED_FUNC_ATTR
@ -39,8 +43,6 @@
#define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@ #define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@
/* Define to 1 if GCC generates calls to __register_frame_info(). */ /* Define to 1 if GCC generates calls to __register_frame_info(). */
#define NEED_REGISTER_FRAME_INFO @NEED_REGISTER_FRAME_INFO@ #define NEED_REGISTER_FRAME_INFO @NEED_REGISTER_FRAME_INFO@
/* Define to 1 to enable disk cache statistics. */
#define DISK_CACHE_STATS @DISK_CACHE_STATS@
#define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" #define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@"
#define GRUB_PLATFORM "@GRUB_PLATFORM@" #define GRUB_PLATFORM "@GRUB_PLATFORM@"

View file

@ -28,58 +28,71 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
/* Context for grub_cmd_blocklist. */
struct blocklist_ctx
{
unsigned long start_sector;
unsigned num_sectors;
int num_entries;
grub_disk_addr_t part_start;
};
/* Helper for grub_cmd_blocklist. */
static void
print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length, struct blocklist_ctx *ctx)
{
if (ctx->num_entries++)
grub_printf (",");
grub_printf ("%llu", (unsigned long long) (sector - ctx->part_start));
if (num > 0)
grub_printf ("+%u", num);
if (offset != 0 || length != 0)
grub_printf ("[%u-%u]", offset, offset + length);
}
/* Helper for grub_cmd_blocklist. */
static void
read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
void *data)
{
struct blocklist_ctx *ctx = data;
if (ctx->num_sectors > 0)
{
if (ctx->start_sector + ctx->num_sectors == sector
&& offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
{
ctx->num_sectors++;
return;
}
print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
ctx->num_sectors = 0;
}
if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
{
ctx->start_sector = sector;
ctx->num_sectors++;
}
else
print_blocklist (sector, 0, offset, length, ctx);
}
static grub_err_t static grub_err_t
grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args) int argc, char **args)
{ {
grub_file_t file; grub_file_t file;
char buf[GRUB_DISK_SECTOR_SIZE]; char buf[GRUB_DISK_SECTOR_SIZE];
unsigned long start_sector = 0; struct blocklist_ctx ctx = {
unsigned num_sectors = 0; .start_sector = 0,
int num_entries = 0; .num_sectors = 0,
grub_disk_addr_t part_start = 0; .num_entries = 0,
auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset, .part_start = 0
unsigned length); };
auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length);
void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
unsigned length)
{
if (num_sectors > 0)
{
if (start_sector + num_sectors == sector
&& offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
{
num_sectors++;
return;
}
print_blocklist (start_sector, num_sectors, 0, 0);
num_sectors = 0;
}
if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
{
start_sector = sector;
num_sectors++;
}
else
print_blocklist (sector, 0, offset, length);
}
void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length)
{
if (num_entries++)
grub_printf (",");
grub_printf ("%llu", (unsigned long long) (sector - part_start));
if (num > 0)
grub_printf ("+%u", num);
if (offset != 0 || length != 0)
grub_printf ("[%u-%u]", offset, offset + length);
}
if (argc < 1) if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@ -93,15 +106,16 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
return grub_error (GRUB_ERR_BAD_DEVICE, return grub_error (GRUB_ERR_BAD_DEVICE,
"this command is available only for disk devices"); "this command is available only for disk devices");
part_start = grub_partition_get_start (file->device->disk->partition); ctx.part_start = grub_partition_get_start (file->device->disk->partition);
file->read_hook = read_blocklist; file->read_hook = read_blocklist;
file->read_hook_data = &ctx;
while (grub_file_read (file, buf, sizeof (buf)) > 0) while (grub_file_read (file, buf, sizeof (buf)) > 0)
; ;
if (num_sectors > 0) if (ctx.num_sectors > 0)
print_blocklist (start_sector, num_sectors, 0, 0); print_blocklist (ctx.start_sector, ctx.num_sectors, 0, 0, &ctx);
grub_file_close (file); grub_file_close (file);

View file

@ -284,22 +284,18 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
return 1; return 1;
} }
static grub_err_t /* Context for grub_cmd_save_env. */
grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) struct grub_cmd_save_env_ctx
{ {
struct grub_arg_list *state = ctxt->state; struct blocklist *head, *tail;
grub_file_t file; };
grub_envblk_t envblk;
struct blocklist *head = 0;
struct blocklist *tail = 0;
/* Store blocklists in a linked list. */ /* Store blocklists in a linked list. */
auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, static void
unsigned offset, save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
unsigned length); void *data)
void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, {
unsigned offset, unsigned length) struct grub_cmd_save_env_ctx *ctx = data;
{
struct blocklist *block; struct blocklist *block;
if (offset + length > GRUB_DISK_SECTOR_SIZE) if (offset + length > GRUB_DISK_SECTOR_SIZE)
@ -316,12 +312,23 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
/* Slightly complicated, because the list should be FIFO. */ /* Slightly complicated, because the list should be FIFO. */
block->next = 0; block->next = 0;
if (tail) if (ctx->tail)
tail->next = block; ctx->tail->next = block;
tail = block; ctx->tail = block;
if (! head) if (! ctx->head)
head = block; ctx->head = block;
} }
static grub_err_t
grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
{
struct grub_arg_list *state = ctxt->state;
grub_file_t file;
grub_envblk_t envblk;
struct grub_cmd_save_env_ctx ctx = {
.head = 0,
.tail = 0
};
if (! argc) if (! argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
@ -336,13 +343,14 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required"); return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
} }
file->read_hook = read_hook; file->read_hook = save_env_read_hook;
file->read_hook_data = &ctx;
envblk = read_envblk_file (file); envblk = read_envblk_file (file);
file->read_hook = 0; file->read_hook = 0;
if (! envblk) if (! envblk)
goto fail; goto fail;
if (check_blocklists (envblk, head, file)) if (check_blocklists (envblk, ctx.head, file))
goto fail; goto fail;
while (argc) while (argc)
@ -363,12 +371,12 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
args++; args++;
} }
write_blocklists (envblk, head, file); write_blocklists (envblk, ctx.head, file);
fail: fail:
if (envblk) if (envblk)
grub_envblk_close (envblk); grub_envblk_close (envblk);
free_blocklists (head); free_blocklists (ctx.head);
grub_file_close (file); grub_file_close (file);
return grub_errno; return grub_errno;
} }

View file

@ -31,6 +31,17 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
/* Helper for grub_cmd_testload. */
static void
read_progress (grub_disk_addr_t sector __attribute__ ((unused)),
unsigned offset __attribute__ ((unused)),
unsigned len __attribute__ ((unused)),
void *data __attribute__ ((unused)))
{
grub_xputs (".");
grub_refresh ();
}
static grub_err_t static grub_err_t
grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
@ -39,15 +50,6 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
char *buf; char *buf;
grub_size_t size; grub_size_t size;
grub_off_t pos; grub_off_t pos;
auto void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector, unsigned offset, unsigned len);
void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector __attribute__ ((unused)),
unsigned offset __attribute__ ((unused)),
unsigned len __attribute__ ((unused)))
{
grub_xputs (".");
grub_refresh ();
}
if (argc < 1) if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@ -68,7 +70,7 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
goto fail; goto fail;
grub_printf ("Reading %s sequentially", argv[0]); grub_printf ("Reading %s sequentially", argv[0]);
file->read_hook = read_func; file->read_hook = read_progress;
if (grub_file_read (file, buf, size) != (grub_ssize_t) size) if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
goto fail; goto fail;
grub_printf (" Done.\n"); grub_printf (" Done.\n");

View file

@ -531,7 +531,7 @@ grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
(struct grub_affs_data *) file->data; (struct grub_affs_data *) file->data;
return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen, return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen,
file->read_hook, file->read_hook, file->read_hook_data,
file->offset, len, buf, grub_affs_read_block, file->offset, len, buf, grub_affs_read_block,
grub_be_to_cpu32 (data->diropen.di.size), grub_be_to_cpu32 (data->diropen.di.size),
data->log_blocksize, 0); data->log_blocksize, 0);

View file

@ -217,9 +217,7 @@ read_bfs_file (grub_disk_t disk,
const struct grub_bfs_superblock *sb, const struct grub_bfs_superblock *sb,
const struct grub_bfs_inode *ino, const struct grub_bfs_inode *ino,
grub_off_t off, void *buf, grub_size_t len, grub_off_t off, void *buf, grub_size_t len,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data)
unsigned offset,
unsigned length))
{ {
if (len == 0) if (len == 0)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -245,6 +243,7 @@ read_bfs_file (grub_disk_t disk,
if (read_size > len) if (read_size > len)
read_size = len; read_size = len;
disk->read_hook = read_hook; disk->read_hook = read_hook;
disk->read_hook_data = read_hook_data;
err = read_extent (disk, sb, &ino->direct[i], 0, off - pos, err = read_extent (disk, sb, &ino->direct[i], 0, off - pos,
buf, read_size); buf, read_size);
disk->read_hook = 0; disk->read_hook = 0;
@ -290,6 +289,7 @@ read_bfs_file (grub_disk_t disk,
if (read_size > len) if (read_size > len)
read_size = len; read_size = len;
disk->read_hook = read_hook; disk->read_hook = read_hook;
disk->read_hook_data = read_hook_data;
err = read_extent (disk, sb, &entries[i], 0, off - pos, err = read_extent (disk, sb, &entries[i], 0, off - pos,
buf, read_size); buf, read_size);
disk->read_hook = 0; disk->read_hook = 0;
@ -401,6 +401,7 @@ read_bfs_file (grub_disk_t disk,
if (read_size > len) if (read_size > len)
read_size = len; read_size = len;
disk->read_hook = read_hook; disk->read_hook = read_hook;
disk->read_hook_data = read_hook_data;
err = read_extent (disk, sb, &l2_entries[l2n], 0, boff, err = read_extent (disk, sb, &l2_entries[l2n], 0, boff,
buf, read_size); buf, read_size);
disk->read_hook = 0; disk->read_hook = 0;
@ -431,7 +432,7 @@ iterate_in_b_tree (grub_disk_t disk,
int level; int level;
grub_uint64_t node_off; grub_uint64_t node_off;
err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0, 0);
if (err) if (err)
return 0; return 0;
node_off = grub_bfs_to_cpu64 (head.root); node_off = grub_bfs_to_cpu64 (head.root);
@ -441,7 +442,8 @@ iterate_in_b_tree (grub_disk_t disk,
{ {
struct grub_bfs_btree_node node; struct grub_bfs_btree_node node;
grub_uint64_t key_value; grub_uint64_t key_value;
err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node),
0, 0);
if (err) if (err)
return 0; return 0;
err = read_bfs_file (disk, sb, ino, node_off err = read_bfs_file (disk, sb, ino, node_off
@ -451,7 +453,7 @@ iterate_in_b_tree (grub_disk_t disk,
BTREE_ALIGN) + BTREE_ALIGN) +
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), &key_value, sizeof (grub_uint16_t), &key_value,
sizeof (grub_uint64_t), 0); sizeof (grub_uint64_t), 0, 0);
if (err) if (err)
return 0; return 0;
@ -461,7 +463,8 @@ iterate_in_b_tree (grub_disk_t disk,
while (1) while (1)
{ {
struct grub_bfs_btree_node node; struct grub_bfs_btree_node node;
err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node),
0, 0);
if (err) if (err)
return 0; return 0;
{ {
@ -473,7 +476,7 @@ iterate_in_b_tree (grub_disk_t disk,
err = err =
read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data,
grub_bfs_to_cpu_treehead (node.total_key_len), 0); grub_bfs_to_cpu_treehead (node.total_key_len), 0, 0);
if (err) if (err)
return 0; return 0;
key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0;
@ -483,7 +486,7 @@ iterate_in_b_tree (grub_disk_t disk,
(node.total_key_len), BTREE_ALIGN), (node.total_key_len), BTREE_ALIGN),
keylen_idx, keylen_idx,
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), 0); sizeof (grub_uint16_t), 0, 0);
if (err) if (err)
return 0; return 0;
err = read_bfs_file (disk, sb, ino, node_off err = read_bfs_file (disk, sb, ino, node_off
@ -494,7 +497,7 @@ iterate_in_b_tree (grub_disk_t disk,
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), key_values, sizeof (grub_uint16_t), key_values,
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint64_t), 0); sizeof (grub_uint64_t), 0, 0);
if (err) if (err)
return 0; return 0;
@ -556,7 +559,7 @@ find_in_b_tree (grub_disk_t disk,
int level; int level;
grub_uint64_t node_off; grub_uint64_t node_off;
err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0, 0);
if (err) if (err)
return err; return err;
node_off = grub_bfs_to_cpu64 (head.root); node_off = grub_bfs_to_cpu64 (head.root);
@ -565,7 +568,8 @@ find_in_b_tree (grub_disk_t disk,
while (1) while (1)
{ {
struct grub_bfs_btree_node node; struct grub_bfs_btree_node node;
err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node),
0, 0);
if (err) if (err)
return err; return err;
if (node.count_keys == 0) if (node.count_keys == 0)
@ -578,7 +582,7 @@ find_in_b_tree (grub_disk_t disk,
unsigned i; unsigned i;
err = err =
read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data,
grub_bfs_to_cpu_treehead (node.total_key_len), 0); grub_bfs_to_cpu_treehead (node.total_key_len), 0, 0);
if (err) if (err)
return err; return err;
key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0;
@ -589,7 +593,7 @@ find_in_b_tree (grub_disk_t disk,
total_key_len), total_key_len),
BTREE_ALIGN), keylen_idx, BTREE_ALIGN), keylen_idx,
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), 0); sizeof (grub_uint16_t), 0, 0);
if (err) if (err)
return err; return err;
err = read_bfs_file (disk, sb, ino, node_off err = read_bfs_file (disk, sb, ino, node_off
@ -600,7 +604,7 @@ find_in_b_tree (grub_disk_t disk,
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), key_values, sizeof (grub_uint16_t), key_values,
grub_bfs_to_cpu_treehead (node.count_keys) * grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint64_t), 0); sizeof (grub_uint64_t), 0, 0);
if (err) if (err)
return err; return err;
@ -771,7 +775,7 @@ find_file (const char *path, grub_disk_t disk,
return grub_errno; return grub_errno;
} }
grub_free (old_alloc); grub_free (old_alloc);
err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0); err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0, 0);
if (err) if (err)
{ {
grub_free (alloc); grub_free (alloc);
@ -974,7 +978,8 @@ grub_bfs_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_bfs_data *data = file->data; struct grub_bfs_data *data = file->data;
err = read_bfs_file (file->device->disk, &data->sb, err = read_bfs_file (file->device->disk, &data->sb,
data->ino, file->offset, buf, len, file->read_hook); data->ino, file->offset, buf, len,
file->read_hook, file->read_hook_data);
if (err) if (err)
return -1; return -1;
return len; return len;
@ -1056,7 +1061,7 @@ read_bfs_attr (grub_disk_t disk,
if (read > len) if (read > len)
read = len; read = len;
err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0, 0);
if (err) if (err)
return -1; return -1;
return read; return read;

View file

@ -525,11 +525,11 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t 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, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t 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, read_hook_data,
pos, len, buf, grub_ext2_read_block, pos, len, buf, grub_ext2_read_block,
grub_cpu_to_le32 (node->inode.size) grub_cpu_to_le32 (node->inode.size)
| (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32), | (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32),
@ -676,7 +676,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
grub_le_to_cpu32 (diro->inode.size)); grub_le_to_cpu32 (diro->inode.size));
else else
{ {
grub_ext2_read_file (diro, 0, 0, grub_ext2_read_file (diro, 0, 0, 0,
grub_le_to_cpu32 (diro->inode.size), grub_le_to_cpu32 (diro->inode.size),
symlink); symlink);
if (grub_errno) if (grub_errno)
@ -709,7 +709,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
{ {
struct ext2_dirent dirent; struct ext2_dirent dirent;
grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent), grub_ext2_read_file (diro, 0, 0, fpos, sizeof (struct ext2_dirent),
(char *) &dirent); (char *) &dirent);
if (grub_errno) if (grub_errno)
return 0; return 0;
@ -723,7 +723,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
struct grub_fshelp_node *fdiro; struct grub_fshelp_node *fdiro;
enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent), grub_ext2_read_file (diro, 0, 0, fpos + sizeof (struct ext2_dirent),
dirent.namelen, filename); dirent.namelen, filename);
if (grub_errno) if (grub_errno)
return 0; return 0;
@ -850,7 +850,8 @@ grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
{ {
struct grub_ext2_data *data = (struct grub_ext2_data *) file->data; struct grub_ext2_data *data = (struct grub_ext2_data *) file->data;
return grub_ext2_read_file (&data->diropen, file->read_hook, return grub_ext2_read_file (&data->diropen,
file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf);
} }

View file

@ -454,8 +454,7 @@ grub_fat_mount (grub_disk_t disk)
static grub_ssize_t static grub_ssize_t
grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t offset, grub_size_t len, char *buf) grub_off_t offset, grub_size_t len, char *buf)
{ {
grub_size_t size; grub_size_t size;
@ -561,6 +560,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
size = len; size = len;
disk->read_hook = read_hook; disk->read_hook = read_hook;
disk->read_hook_data = read_hook_data;
grub_disk_read (disk, sector, offset, size, buf); grub_disk_read (disk, sector, offset, size, buf);
disk->read_hook = 0; disk->read_hook = 0;
if (grub_errno) if (grub_errno)
@ -630,7 +630,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
ctxt->offset += sizeof (dir); ctxt->offset += sizeof (dir);
if (grub_fat_read_data (disk, data, 0, ctxt->offset, sizeof (dir), if (grub_fat_read_data (disk, data, 0, 0, ctxt->offset, sizeof (dir),
(char *) &dir) (char *) &dir)
!= sizeof (dir)) != sizeof (dir))
break; break;
@ -652,7 +652,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
{ {
struct grub_fat_dir_entry sec; struct grub_fat_dir_entry sec;
ctxt->offset += sizeof (sec); ctxt->offset += sizeof (sec);
if (grub_fat_read_data (disk, data, 0, if (grub_fat_read_data (disk, data, 0, 0,
ctxt->offset, sizeof (sec), (char *) &sec) ctxt->offset, sizeof (sec), (char *) &sec)
!= sizeof (sec)) != sizeof (sec))
break; break;
@ -729,7 +729,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
ctxt->offset += sizeof (ctxt->dir); ctxt->offset += sizeof (ctxt->dir);
/* Read a directory entry. */ /* Read a directory entry. */
if (grub_fat_read_data (disk, data, 0, if (grub_fat_read_data (disk, data, 0, 0,
ctxt->offset, sizeof (ctxt->dir), ctxt->offset, sizeof (ctxt->dir),
(char *) &ctxt->dir) (char *) &ctxt->dir)
!= sizeof (ctxt->dir) || ctxt->dir.name[0] == 0) != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
@ -1031,7 +1031,8 @@ grub_fat_open (grub_file_t file, const char *name)
static grub_ssize_t static grub_ssize_t
grub_fat_read (grub_file_t file, char *buf, grub_size_t len) grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
{ {
return grub_fat_read_data (file->device->disk, file->data, file->read_hook, return grub_fat_read_data (file->device->disk, file->data,
file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf);
} }
@ -1064,7 +1065,7 @@ grub_fat_label (grub_device_t device, char **label)
{ {
offset += sizeof (dir); offset += sizeof (dir);
if (grub_fat_read_data (disk, data, 0, if (grub_fat_read_data (disk, data, 0, 0,
offset, sizeof (dir), (char *) &dir) offset, sizeof (dir), (char *) &dir)
!= sizeof (dir)) != sizeof (dir))
break; break;

View file

@ -248,14 +248,13 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, /* 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 beginning with the block POS. READ_HOOK should be set before
reading a block from the file. GET_BLOCK is used to translate file reading a block from the file. READ_HOOK_DATA is passed through as
blocks to disk blocks. The file is FILESIZE bytes big and the the DATA argument to READ_HOOK. GET_BLOCK is used to translate
file blocks to disk blocks. The file is FILESIZE bytes big and the
blocks have a size of LOG2BLOCKSIZE (in log2). */ blocks have a size of LOG2BLOCKSIZE (in log2). */
grub_ssize_t grub_ssize_t
grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset,
unsigned length),
grub_off_t pos, grub_size_t len, char *buf, grub_off_t pos, grub_size_t len, char *buf,
grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
grub_disk_addr_t block), grub_disk_addr_t block),
@ -307,6 +306,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
if (blknr) if (blknr)
{ {
disk->read_hook = read_hook; disk->read_hook = read_hook;
disk->read_hook_data = read_hook_data;
grub_disk_read (disk, blknr + blocks_start, skipfirst, grub_disk_read (disk, blknr + blocks_start, skipfirst,
blockend, buf); blockend, buf);

View file

@ -243,8 +243,7 @@ grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat,
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_hfs_read_file (struct grub_hfs_data *data, grub_hfs_read_file (struct grub_hfs_data *data,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
grub_off_t i; grub_off_t i;
@ -289,6 +288,7 @@ grub_hfs_read_file (struct grub_hfs_data *data,
if (blknr) if (blknr)
{ {
data->disk->read_hook = read_hook; data->disk->read_hook = read_hook;
data->disk->read_hook_data = read_hook_data;
grub_disk_read (data->disk, blknr, skipfirst, grub_disk_read (data->disk, blknr, skipfirst,
blockend, buf); blockend, buf);
data->disk->read_hook = 0; data->disk->read_hook = 0;
@ -1269,7 +1269,8 @@ grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_hfs_data *data = struct grub_hfs_data *data =
(struct grub_hfs_data *) file->data; (struct grub_hfs_data *) file->data;
return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf); return grub_hfs_read_file (data, file->read_hook, file->read_hook_data,
file->offset, len, buf);
} }

View file

@ -375,11 +375,11 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_hfsplus_read_file (grub_fshelp_node_t node, grub_hfsplus_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t 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, read_hook_data,
pos, len, buf, grub_hfsplus_read_block, pos, len, buf, grub_hfsplus_read_block,
node->size, node->size,
node->data->log2blksize - GRUB_DISK_SECTOR_BITS, node->data->log2blksize - GRUB_DISK_SECTOR_BITS,
@ -477,7 +477,7 @@ grub_hfsplus_mount (grub_disk_t disk)
grub_be_to_cpu64 (data->volheader.extents_file.size); grub_be_to_cpu64 (data->volheader.extents_file.size);
/* Read the essential information about the trees. */ /* Read the essential information about the trees. */
if (grub_hfsplus_read_file (&data->catalog_tree.file, 0, if (grub_hfsplus_read_file (&data->catalog_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode), sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0) sizeof (header), (char *) &header) <= 0)
goto fail; goto fail;
@ -487,14 +487,14 @@ grub_hfsplus_mount (grub_disk_t disk)
data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) && data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
(header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE)); (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode), sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0) sizeof (header), (char *) &header) <= 0)
goto fail; goto fail;
data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, 0,
sizeof (node), (char *) &node) <= 0) sizeof (node), (char *) &node) <= 0)
goto fail; goto fail;
@ -605,7 +605,7 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
if (!symlink) if (!symlink)
return 0; return 0;
numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink); numread = grub_hfsplus_read_file (node, 0, 0, 0, node->size, symlink);
if (numread != (grub_ssize_t) node->size) if (numread != (grub_ssize_t) node->size)
{ {
grub_free (symlink); grub_free (symlink);
@ -649,7 +649,7 @@ grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
saved_node = first_node->next; saved_node = first_node->next;
node_count++; node_count++;
if (grub_hfsplus_read_file (&btree->file, 0, if (grub_hfsplus_read_file (&btree->file, 0, 0,
(((grub_disk_addr_t) (((grub_disk_addr_t)
grub_be_to_cpu32 (first_node->next)) grub_be_to_cpu32 (first_node->next))
* btree->nodesize), * btree->nodesize),
@ -702,7 +702,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
node_count++; node_count++;
/* Read a node. */ /* Read a node. */
if (grub_hfsplus_read_file (&btree->file, 0, if (grub_hfsplus_read_file (&btree->file, 0, 0,
(grub_disk_addr_t) currnode (grub_disk_addr_t) currnode
* (grub_disk_addr_t) btree->nodesize, * (grub_disk_addr_t) btree->nodesize,
btree->nodesize, (char *) node) <= 0) btree->nodesize, (char *) node) <= 0)
@ -971,7 +971,8 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_hfsplus_data *data = struct grub_hfsplus_data *data =
(struct grub_hfsplus_data *) file->data; (struct grub_hfsplus_data *) file->data;
return grub_hfsplus_read_file (&data->opened_file, file->read_hook, return grub_hfsplus_read_file (&data->opened_file,
file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf);
} }

View file

@ -961,6 +961,7 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
/* XXX: The file is stored in as a single extent. */ /* XXX: The file is stored in as a single extent. */
data->disk->read_hook = file->read_hook; data->disk->read_hook = file->read_hook;
data->disk->read_hook_data = file->read_hook_data;
read_node (data->node, file->offset, len, buf); read_node (data->node, file->offset, len, buf);
data->disk->read_hook = NULL; data->disk->read_hook = NULL;

View file

@ -577,8 +577,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_jfs_read_file (struct grub_jfs_data *data, grub_jfs_read_file (struct grub_jfs_data *data,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
grub_off_t i; grub_off_t i;
@ -616,6 +615,7 @@ grub_jfs_read_file (struct grub_jfs_data *data,
} }
data->disk->read_hook = read_hook; data->disk->read_hook = read_hook;
data->disk->read_hook_data = read_hook_data;
grub_disk_read (data->disk, grub_disk_read (data->disk,
blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz) blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS), - GRUB_DISK_SECTOR_BITS),
@ -782,7 +782,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino)
if (size <= sizeof (data->currinode.symlink.path)) if (size <= sizeof (data->currinode.symlink.path))
grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size); grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size);
else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0) else if (grub_jfs_read_file (data, 0, 0, 0, size, symlink) < 0)
return grub_errno; return grub_errno;
symlink[size] = '\0'; symlink[size] = '\0';
@ -894,7 +894,8 @@ grub_jfs_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_jfs_data *data = struct grub_jfs_data *data =
(struct grub_jfs_data *) file->data; (struct grub_jfs_data *) file->data;
return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf); return grub_jfs_read_file (data, file->read_hook, file->read_hook_data,
file->offset, len, buf);
} }

View file

@ -249,8 +249,7 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_minix_read_file (struct grub_minix_data *data, grub_minix_read_file (struct grub_minix_data *data,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
grub_uint32_t i; grub_uint32_t i;
@ -301,6 +300,7 @@ grub_minix_read_file (struct grub_minix_data *data,
} }
data->disk->read_hook = read_hook; data->disk->read_hook = read_hook;
data->disk->read_hook_data = read_hook_data;
grub_disk_read (data->disk, grub_disk_read (data->disk,
GRUB_MINIX_ZONE2SECT(blknr), GRUB_MINIX_ZONE2SECT(blknr),
skipfirst, blockend, buf); skipfirst, blockend, buf);
@ -352,7 +352,7 @@ grub_minix_lookup_symlink (struct grub_minix_data *data, grub_minix_ino_t ino)
if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT) if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT)
return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks")); return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks"));
if (grub_minix_read_file (data, 0, 0, if (grub_minix_read_file (data, 0, 0, 0,
GRUB_MINIX_INODE_SIZE (data), symlink) < 0) GRUB_MINIX_INODE_SIZE (data), symlink) < 0)
return grub_errno; return grub_errno;
@ -409,10 +409,10 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path)
if (grub_strlen (name) == 0) if (grub_strlen (name) == 0)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if (grub_minix_read_file (data, 0, pos, sizeof (ino), if (grub_minix_read_file (data, 0, 0, pos, sizeof (ino),
(char *) &ino) < 0) (char *) &ino) < 0)
return grub_errno; return grub_errno;
if (grub_minix_read_file (data, 0, pos + sizeof (ino), if (grub_minix_read_file (data, 0, 0, pos + sizeof (ino),
data->filename_size, (char *) filename)< 0) data->filename_size, (char *) filename)< 0)
return grub_errno; return grub_errno;
@ -568,11 +568,11 @@ grub_minix_dir (grub_device_t device, const char *path,
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
if (grub_minix_read_file (data, 0, pos, sizeof (ino), if (grub_minix_read_file (data, 0, 0, pos, sizeof (ino),
(char *) &ino) < 0) (char *) &ino) < 0)
return grub_errno; return grub_errno;
if (grub_minix_read_file (data, 0, pos + sizeof (ino), if (grub_minix_read_file (data, 0, 0, pos + sizeof (ino),
data->filename_size, data->filename_size,
(char *) filename) < 0) (char *) filename) < 0)
return grub_errno; return grub_errno;
@ -649,7 +649,8 @@ grub_minix_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_minix_data *data = struct grub_minix_data *data =
(struct grub_minix_data *) file->data; (struct grub_minix_data *) file->data;
return grub_minix_read_file (data, file->read_hook, file->offset, len, buf); return grub_minix_read_file (data, file->read_hook, file->read_hook_data,
file->offset, len, buf);
} }

View file

@ -630,13 +630,11 @@ grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_nilfs2_read_file (grub_fshelp_node_t node, grub_nilfs2_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t grub_disk_read_hook_t read_hook, void *read_hook_data,
sector,
unsigned offset,
unsigned length),
grub_off_t 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, read_hook_data,
pos, len, buf, grub_nilfs2_read_block, pos, len, buf, grub_nilfs2_read_block,
grub_le_to_cpu64 (node->inode.i_size), grub_le_to_cpu64 (node->inode.i_size),
LOG2_NILFS2_BLOCK_SIZE (node->data), 0); LOG2_NILFS2_BLOCK_SIZE (node->data), 0);
@ -856,7 +854,7 @@ grub_nilfs2_read_symlink (grub_fshelp_node_t node)
if (!symlink) if (!symlink)
return 0; return 0;
grub_nilfs2_read_file (diro, 0, 0, grub_nilfs2_read_file (diro, 0, 0, 0,
grub_le_to_cpu64 (diro->inode.i_size), symlink); grub_le_to_cpu64 (diro->inode.i_size), symlink);
if (grub_errno) if (grub_errno)
{ {
@ -887,7 +885,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
{ {
struct grub_nilfs2_dir_entry dirent; struct grub_nilfs2_dir_entry dirent;
grub_nilfs2_read_file (diro, 0, fpos, grub_nilfs2_read_file (diro, 0, 0, fpos,
sizeof (struct grub_nilfs2_dir_entry), sizeof (struct grub_nilfs2_dir_entry),
(char *) &dirent); (char *) &dirent);
if (grub_errno) if (grub_errno)
@ -902,7 +900,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
struct grub_fshelp_node *fdiro; struct grub_fshelp_node *fdiro;
enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
grub_nilfs2_read_file (diro, 0, grub_nilfs2_read_file (diro, 0, 0,
fpos + sizeof (struct grub_nilfs2_dir_entry), fpos + sizeof (struct grub_nilfs2_dir_entry),
dirent.name_len, filename); dirent.name_len, filename);
if (grub_errno) if (grub_errno)
@ -1025,7 +1023,8 @@ grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len)
{ {
struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data; struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data;
return grub_nilfs2_read_file (&data->diropen, file->read_hook, return grub_nilfs2_read_file (&data->diropen,
file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf);
} }

View file

@ -91,21 +91,15 @@ static grub_err_t read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf,
static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest,
grub_disk_addr_t ofs, grub_size_t len, grub_disk_addr_t ofs, grub_size_t len,
int cached, int cached,
void grub_disk_read_hook_t read_hook,
NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t void *read_hook_data);
sector,
unsigned offset,
unsigned length));
static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa,
grub_uint8_t *dest, grub_uint8_t *dest,
grub_disk_addr_t ofs, grub_size_t len, grub_disk_addr_t ofs, grub_size_t len,
int cached, int cached,
void grub_disk_read_hook_t read_hook,
NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t void *read_hook_data);
sector,
unsigned offset,
unsigned length));
static void static void
init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
@ -207,7 +201,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
at->edat_buf = grub_malloc (n); at->edat_buf = grub_malloc (n);
if (!at->edat_buf) if (!at->edat_buf)
return NULL; return NULL;
if (read_data (at, pa, at->edat_buf, 0, n, 0, 0)) if (read_data (at, pa, at->edat_buf, 0, n, 0, 0, 0))
{ {
grub_error (GRUB_ERR_BAD_FS, grub_error (GRUB_ERR_BAD_FS,
"fail to read non-resident attribute list"); "fail to read non-resident attribute list");
@ -249,7 +243,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
if (read_attr if (read_attr
(at, pa + 0x10, (at, pa + 0x10,
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0))
return NULL; return NULL;
pa += u16at (pa, 4); pa += u16at (pa, 4);
} }
@ -325,9 +319,7 @@ retry:
{ {
if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST))
{ {
void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t save_hook;
unsigned offset,
unsigned length);
save_hook = ctx->comp.disk->read_hook; save_hook = ctx->comp.disk->read_hook;
ctx->comp.disk->read_hook = 0; ctx->comp.disk->read_hook = 0;
@ -379,9 +371,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
static grub_err_t static grub_err_t
read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
grub_disk_addr_t ofs, grub_size_t len, int cached, grub_disk_addr_t ofs, grub_size_t len, int cached,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data)
unsigned offset,
unsigned length))
{ {
grub_disk_addr_t vcn; grub_disk_addr_t vcn;
struct grub_ntfs_rlst cc, *ctx; struct grub_ntfs_rlst cc, *ctx;
@ -480,7 +470,8 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
if (!(ctx->flags & GRUB_NTFS_RF_COMP)) if (!(ctx->flags & GRUB_NTFS_RF_COMP))
{ {
grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx,
read_hook, ofs, len, (char *) dest, read_hook, read_hook_data, ofs, len,
(char *) dest,
grub_ntfs_read_block, ofs + len, grub_ntfs_read_block, ofs + len,
ctx->comp.log_spc, 0); ctx->comp.log_spc, 0);
return grub_errno; return grub_errno;
@ -495,9 +486,7 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
static grub_err_t static grub_err_t
read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
grub_size_t len, int cached, grub_size_t len, int cached,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data)
unsigned offset,
unsigned length))
{ {
grub_uint8_t *save_cur; grub_uint8_t *save_cur;
grub_uint8_t attr; grub_uint8_t attr;
@ -532,7 +521,8 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
} }
pp = find_attr (at, attr); pp = find_attr (at, attr);
if (pp) if (pp)
ret = read_data (at, pp, dest, ofs, len, cached, read_hook); ret = read_data (at, pp, dest, ofs, len, cached,
read_hook, read_hook_data);
else else
ret = ret =
(grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS, (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
@ -546,7 +536,7 @@ read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, grub_uint32_t mftno)
{ {
if (read_attr if (read_attr
(&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR),
data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0))
return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE"); return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE");
} }
@ -717,7 +707,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node)
} }
err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0, err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0,
sizeof (struct symlink_descriptor), 1, 0); sizeof (struct symlink_descriptor), 1, 0, 0);
if (err) if (err)
return NULL; return NULL;
@ -743,7 +733,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node)
if (!buf16) if (!buf16)
return NULL; return NULL;
err = read_attr (&mft->attr, (grub_uint8_t *) buf16, off, len, 1, 0); err = read_attr (&mft->attr, (grub_uint8_t *) buf16, off, len, 1, 0, 0);
if (err) if (err)
return NULL; return NULL;
@ -852,7 +842,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
} }
else else
{ {
if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0)) if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0, 0))
{ {
grub_error (GRUB_ERR_BAD_FS, grub_error (GRUB_ERR_BAD_FS,
"fails to read non-resident $BITMAP"); "fails to read non-resident $BITMAP");
@ -899,7 +889,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
{ {
if ((read_attr if ((read_attr
(at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR), (at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
(mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0)) (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0, 0))
|| (fixup (indx, mft->data->idx_size, || (fixup (indx, mft->data->idx_size,
(const grub_uint8_t *) "INDX"))) (const grub_uint8_t *) "INDX")))
goto done; goto done;
@ -1136,7 +1126,7 @@ grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len)
mft->attr.save_pos = 1; mft->attr.save_pos = 1;
read_attr (&mft->attr, (grub_uint8_t *) buf, file->offset, len, 1, read_attr (&mft->attr, (grub_uint8_t *) buf, file->offset, len, 1,
file->read_hook); file->read_hook, file->read_hook_data);
return (grub_errno) ? -1 : (grub_ssize_t) len; return (grub_errno) ? -1 : (grub_ssize_t) len;
} }

View file

@ -302,6 +302,7 @@ ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
ret = 0; ret = 0;
//ctx->comp.disk->read_hook = read_hook; //ctx->comp.disk->read_hook = read_hook;
//ctx->comp.disk->read_hook_data = read_hook_data;
if ((vcn > ctx->target_vcn) && if ((vcn > ctx->target_vcn) &&
(read_block (read_block

View file

@ -240,9 +240,8 @@ struct grub_reiserfs_data
static grub_ssize_t static grub_ssize_t
grub_reiserfs_read_real (struct grub_fshelp_node *node, grub_reiserfs_read_real (struct grub_fshelp_node *node,
grub_off_t off, char *buf, grub_size_t len, grub_off_t off, char *buf, grub_size_t len,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook,
unsigned offset, void *read_hook_data);
unsigned length));
/* Internal-only functions. Not to be used outside of this file. */ /* Internal-only functions. Not to be used outside of this file. */
@ -674,7 +673,7 @@ grub_reiserfs_read_symlink (grub_fshelp_node_t node)
if (! symlink_buffer) if (! symlink_buffer)
return 0; return 0;
ret = grub_reiserfs_read_real (node, 0, symlink_buffer, len, 0); ret = grub_reiserfs_read_real (node, 0, symlink_buffer, len, 0, 0);
if (ret < 0) if (ret < 0)
{ {
grub_free (symlink_buffer); grub_free (symlink_buffer);
@ -1036,9 +1035,7 @@ grub_reiserfs_open (struct grub_file *file, const char *name)
static grub_ssize_t static grub_ssize_t
grub_reiserfs_read_real (struct grub_fshelp_node *node, grub_reiserfs_read_real (struct grub_fshelp_node *node,
grub_off_t off, char *buf, grub_size_t len, grub_off_t off, char *buf, grub_size_t len,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data)
unsigned offset,
unsigned length))
{ {
unsigned int indirect_block, indirect_block_count; unsigned int indirect_block, indirect_block_count;
struct grub_reiserfs_key key; struct grub_reiserfs_key key;
@ -1105,6 +1102,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
(unsigned) block, (unsigned) offset, (unsigned) block, (unsigned) offset,
(unsigned) (offset + length)); (unsigned) (offset + length));
found.data->disk->read_hook = read_hook; found.data->disk->read_hook = read_hook;
found.data->disk->read_hook_data = read_hook_data;
grub_disk_read (found.data->disk, grub_disk_read (found.data->disk,
block, block,
offset offset
@ -1131,6 +1129,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
if (grub_errno) if (grub_errno)
goto fail; goto fail;
found.data->disk->read_hook = read_hook; found.data->disk->read_hook = read_hook;
found.data->disk->read_hook_data = read_hook_data;
for (indirect_block = 0; for (indirect_block = 0;
indirect_block < indirect_block_count indirect_block < indirect_block_count
&& current_position < final_position; && current_position < final_position;
@ -1236,7 +1235,7 @@ static grub_ssize_t
grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
{ {
return grub_reiserfs_read_real (file->data, file->offset, buf, len, return grub_reiserfs_read_real (file->data, file->offset, buf, len,
file->read_hook); file->read_hook, file->read_hook_data);
} }
/* Close the file FILE. */ /* Close the file FILE. */

View file

@ -399,6 +399,7 @@ grub_romfs_read (grub_file_t file, char *buf, grub_size_t len)
/* XXX: The file is stored in as a single extent. */ /* XXX: The file is stored in as a single extent. */
data->data->disk->read_hook = file->read_hook; data->data->disk->read_hook = file->read_hook;
data->data->disk->read_hook_data = file->read_hook_data;
grub_disk_read (data->data->disk, grub_disk_read (data->data->disk,
(data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS, (data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS,
(data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1), (data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1),

View file

@ -345,11 +345,11 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_sfs_read_file (grub_fshelp_node_t node, grub_sfs_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t 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, read_hook_data,
pos, len, buf, grub_sfs_read_block, pos, len, buf, grub_sfs_read_block,
node->size, node->data->log_blocksize, 0); node->size, node->data->log_blocksize, 0);
} }
@ -646,7 +646,8 @@ grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
{ {
struct grub_sfs_data *data = (struct grub_sfs_data *) file->data; struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;
return grub_sfs_read_file (&data->diropen, file->read_hook, return grub_sfs_read_file (&data->diropen,
file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf);
} }

View file

@ -564,9 +564,7 @@ fail:
static grub_ssize_t static grub_ssize_t
grub_udf_read_file (grub_fshelp_node_t node, grub_udf_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR grub_disk_read_hook_t read_hook, void *read_hook_data,
(*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
grub_off_t pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
switch (U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) switch (U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
@ -591,7 +589,8 @@ grub_udf_read_file (grub_fshelp_node_t node,
return 0; return 0;
} }
return grub_fshelp_read_file (node->data->disk, node, read_hook, return grub_fshelp_read_file (node->data->disk, node,
read_hook, read_hook_data,
pos, len, buf, grub_udf_read_block, pos, len, buf, grub_udf_read_block,
U64 (node->block.fe.file_size), U64 (node->block.fe.file_size),
node->data->lbshift, 0); node->data->lbshift, 0);
@ -861,7 +860,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
while (offset < U64 (dir->block.fe.file_size)) while (offset < U64 (dir->block.fe.file_size))
{ {
if (grub_udf_read_file (dir, 0, offset, sizeof (dirent), if (grub_udf_read_file (dir, 0, 0, offset, sizeof (dirent),
(char *) &dirent) != sizeof (dirent)) (char *) &dirent) != sizeof (dirent))
return 0; return 0;
@ -898,7 +897,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
if (child->block.fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK) if (child->block.fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK)
type = GRUB_FSHELP_SYMLINK; type = GRUB_FSHELP_SYMLINK;
if ((grub_udf_read_file (dir, 0, offset, if ((grub_udf_read_file (dir, 0, 0, offset,
dirent.file_ident_length, dirent.file_ident_length,
(char *) raw)) (char *) raw))
!= dirent.file_ident_length) != dirent.file_ident_length)
@ -937,7 +936,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
raw = grub_malloc (sz); raw = grub_malloc (sz);
if (!raw) if (!raw)
return NULL; return NULL;
if (grub_udf_read_file (node, NULL, 0, sz, (char *) raw) < 0) if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
{ {
grub_free (raw); grub_free (raw);
return NULL; return NULL;
@ -1149,7 +1148,8 @@ grub_udf_read (grub_file_t file, char *buf, grub_size_t len)
{ {
struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data; struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
return grub_udf_read_file (node, file->read_hook, file->offset, len, buf); return grub_udf_read_file (node, file->read_hook, file->read_hook_data,
file->offset, len, buf);
} }
static grub_err_t static grub_err_t

View file

@ -331,8 +331,7 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_ufs_read_file (struct grub_ufs_data *data, grub_ufs_read_file (struct grub_ufs_data *data,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t pos, grub_size_t len, char *buf) grub_off_t pos, grub_size_t len, char *buf)
{ {
struct grub_ufs_sblock *sblock = &data->sblock; struct grub_ufs_sblock *sblock = &data->sblock;
@ -380,6 +379,7 @@ grub_ufs_read_file (struct grub_ufs_data *data,
if (blknr) if (blknr)
{ {
data->disk->read_hook = read_hook; data->disk->read_hook = read_hook;
data->disk->read_hook_data = read_hook_data;
grub_disk_read (data->disk, grub_disk_read (data->disk,
blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz), blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz),
skipfirst, blockend, buf); skipfirst, blockend, buf);
@ -455,7 +455,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
&& INODE_SIZE (data) <= sizeof (data->inode.symlink)) && INODE_SIZE (data) <= sizeof (data->inode.symlink))
grub_strcpy (symlink, (char *) data->inode.symlink); grub_strcpy (symlink, (char *) data->inode.symlink);
else else
grub_ufs_read_file (data, 0, 0, INODE_SIZE (data), symlink); grub_ufs_read_file (data, 0, 0, 0, INODE_SIZE (data), symlink);
symlink[INODE_SIZE (data)] = '\0'; symlink[INODE_SIZE (data)] = '\0';
/* The symlink is an absolute path, go back to the root inode. */ /* The symlink is an absolute path, go back to the root inode. */
@ -509,7 +509,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
if (grub_strlen (name) == 0) if (grub_strlen (name) == 0)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent),
(char *) &dirent) < 0) (char *) &dirent) < 0)
return grub_errno; return grub_errno;
@ -521,7 +521,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
{ {
char filename[namelen + 1]; char filename[namelen + 1];
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent),
namelen, filename) < 0) namelen, filename) < 0)
return grub_errno; return grub_errno;
@ -659,7 +659,7 @@ grub_ufs_dir (grub_device_t device, const char *path,
struct grub_ufs_dirent dirent; struct grub_ufs_dirent dirent;
int namelen; int namelen;
if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent),
(char *) &dirent) < 0) (char *) &dirent) < 0)
break; break;
@ -679,7 +679,7 @@ grub_ufs_dir (grub_device_t device, const char *path,
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent),
namelen, filename) < 0) namelen, filename) < 0)
break; break;
@ -752,7 +752,8 @@ grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_ufs_data *data = struct grub_ufs_data *data =
(struct grub_ufs_data *) file->data; (struct grub_ufs_data *) file->data;
return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf); return grub_ufs_read_file (data, file->read_hook, file->read_hook_data,
file->offset, len, buf);
} }

View file

@ -379,11 +379,11 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
POS. Return the amount of read bytes in READ. */ POS. Return the amount of read bytes in READ. */
static grub_ssize_t static grub_ssize_t
grub_xfs_read_file (grub_fshelp_node_t node, grub_xfs_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook, void *read_hook_data,
unsigned offset, unsigned length),
grub_off_t 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, read_hook_data,
pos, len, buf, grub_xfs_read_block, pos, len, buf, grub_xfs_read_block,
grub_be_to_cpu64 (node->inode.size), grub_be_to_cpu64 (node->inode.size),
node->data->sblock.log2_bsize node->data->sblock.log2_bsize
@ -410,7 +410,7 @@ grub_xfs_read_symlink (grub_fshelp_node_t node)
if (!symlink) if (!symlink)
return 0; return 0;
numread = grub_xfs_read_file (node, 0, 0, size, symlink); numread = grub_xfs_read_file (node, 0, 0, 0, size, symlink);
if (numread != size) if (numread != size)
{ {
grub_free (symlink); grub_free (symlink);
@ -592,7 +592,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
struct grub_xfs_dirblock_tail *tail; struct grub_xfs_dirblock_tail *tail;
tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start]; tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
numread = grub_xfs_read_file (dir, 0, numread = grub_xfs_read_file (dir, 0, 0,
blk << dirblk_log2, blk << dirblk_log2,
dirblk_size, dirblock); dirblk_size, dirblock);
if (numread != dirblk_size) if (numread != dirblk_size)
@ -829,7 +829,8 @@ grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_xfs_data *data = struct grub_xfs_data *data =
(struct grub_xfs_data *) file->data; (struct grub_xfs_data *) file->data;
return grub_xfs_read_file (&data->diropen, file->read_hook, return grub_xfs_read_file (&data->diropen,
file->read_hook, file->read_hook_data,
file->offset, len, buf); file->offset, len, buf);
} }

View file

@ -603,7 +603,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
cl = GRUB_DISK_SECTOR_SIZE - o; cl = GRUB_DISK_SECTOR_SIZE - o;
if (cl > l) if (cl > l)
cl = l; cl = l;
(disk->read_hook) (s, o, cl); (disk->read_hook) (s, o, cl, disk->read_hook_data);
s++; s++;
l -= cl; l -= cl;
o = 0; o = 0;

View file

@ -19,6 +19,8 @@
#ifndef GRUB_DISK_HEADER #ifndef GRUB_DISK_HEADER
#define GRUB_DISK_HEADER 1 #define GRUB_DISK_HEADER 1
#include <config.h>
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/types.h> #include <grub/types.h>
@ -99,6 +101,10 @@ extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list);
struct grub_partition; struct grub_partition;
typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector,
unsigned offset, unsigned length,
void *data);
/* Disk. */ /* Disk. */
struct grub_disk struct grub_disk
{ {
@ -122,8 +128,10 @@ struct grub_disk
/* Called when a sector was read. OFFSET is between 0 and /* Called when a sector was read. OFFSET is between 0 and
the sector size minus 1, and LENGTH is between 0 and the sector size. */ the sector size minus 1, and LENGTH is between 0 and the sector size. */
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook;
unsigned offset, unsigned length);
/* Caller-specific data passed to the read hook. */
void *read_hook_data;
/* Device-specific data. */ /* Device-specific data. */
void *data; void *data;

View file

@ -23,6 +23,7 @@
#include <grub/err.h> #include <grub/err.h>
#include <grub/device.h> #include <grub/device.h>
#include <grub/fs.h> #include <grub/fs.h>
#include <grub/disk.h>
/* File description. */ /* File description. */
struct grub_file struct grub_file
@ -46,8 +47,10 @@ struct grub_file
void *data; void *data;
/* This is called when a sector is read. Used only for a disk device. */ /* This is called when a sector is read. Used only for a disk device. */
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook;
unsigned offset, unsigned length);
/* Caller-specific data passed to the read hook. */
void *read_hook_data;
}; };
typedef struct grub_file *grub_file_t; typedef struct grub_file *grub_file_t;

View file

@ -23,6 +23,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/disk.h>
typedef struct grub_fshelp_node *grub_fshelp_node_t; typedef struct grub_fshelp_node *grub_fshelp_node_t;
@ -68,9 +69,8 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
blocks have a size of LOG2BLOCKSIZE (in log2). */ blocks have a size of LOG2BLOCKSIZE (in log2). */
grub_ssize_t grub_ssize_t
EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node, EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, grub_disk_read_hook_t read_hook,
unsigned offset, void *read_hook_data,
unsigned length),
grub_off_t pos, grub_size_t len, char *buf, grub_off_t pos, grub_size_t len, char *buf,
grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
grub_disk_addr_t block), grub_disk_addr_t block),

View file

@ -138,6 +138,70 @@ write_rootdev (grub_device_t root_dev,
#define BOOT_SECTOR 0 #define BOOT_SECTOR 0
#endif #endif
/* Helper for setup. */
static void
save_first_sector (grub_disk_addr_t sector, unsigned offset, unsigned length,
void *data)
{
grub_disk_addr_t *first_sector = data;
grub_util_info ("the first sector is <%" PRIuGRUB_UINT64_T ",%u,%u>",
sector, offset, length);
if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("%s", _("the first sector of the core file is not sector-aligned"));
*first_sector = sector;
}
struct blocklists
{
struct grub_boot_blocklist *first_block, *block;
#ifdef GRUB_SETUP_BIOS
grub_uint16_t current_segment;
#endif
grub_uint16_t last_length;
};
/* Helper for setup. */
static void
save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length,
void *data)
{
struct blocklists *bl = data;
struct grub_boot_blocklist *prev = bl->block + 1;
grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>",
sector, offset, length);
if (offset != 0 || bl->last_length != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("%s", _("non-sector-aligned data is found in the core file"));
if (bl->block != bl->first_block
&& (grub_target_to_host64 (prev->start)
+ grub_target_to_host16 (prev->len)) == sector)
{
grub_uint16_t t = grub_target_to_host16 (prev->len) + 1;
prev->len = grub_host_to_target16 (t);
}
else
{
bl->block->start = grub_host_to_target64 (sector);
bl->block->len = grub_host_to_target16 (1);
#ifdef GRUB_SETUP_BIOS
bl->block->segment = grub_host_to_target16 (bl->current_segment);
#endif
bl->block--;
if (bl->block->len)
grub_util_error ("%s", _("the sectors of the core file are too fragmented"));
}
bl->last_length = length;
#ifdef GRUB_SETUP_BIOS
bl->current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
#endif
}
#ifdef GRUB_SETUP_BIOS #ifdef GRUB_SETUP_BIOS
/* Context for setup/identify_partmap. */ /* Context for setup/identify_partmap. */
struct identify_partmap_ctx struct identify_partmap_ctx
@ -147,7 +211,7 @@ struct identify_partmap_ctx
int multiple_partmaps; int multiple_partmaps;
}; };
/* Helper for setup/identify_partmap. /* Helper for setup.
Unlike root_dev, with dest_dev we're interested in the partition map even Unlike root_dev, with dest_dev we're interested in the partition map even
if dest_dev itself is a whole disk. */ if dest_dev itself is a whole disk. */
static int static int
@ -190,73 +254,16 @@ setup (const char *dir,
grub_uint16_t core_sectors; grub_uint16_t core_sectors;
#endif #endif
grub_device_t root_dev = 0, dest_dev, core_dev; grub_device_t root_dev = 0, dest_dev, core_dev;
struct grub_boot_blocklist *first_block, *block; struct blocklists bl;
char *tmp_img; char *tmp_img;
grub_disk_addr_t first_sector; grub_disk_addr_t first_sector;
#ifdef GRUB_SETUP_BIOS
grub_uint16_t current_segment
= GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
#endif
grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE;
FILE *fp; FILE *fp;
auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector,
unsigned offset,
unsigned length);
auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector,
unsigned offset,
unsigned length);
void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector,
unsigned offset,
unsigned length)
{
grub_util_info ("the first sector is <%" PRIuGRUB_UINT64_T ",%u,%u>",
sector, offset, length);
if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("%s", _("the first sector of the core file is not sector-aligned"));
first_sector = sector;
}
void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector,
unsigned offset,
unsigned length)
{
struct grub_boot_blocklist *prev = block + 1;
grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>",
sector, offset, length);
if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("%s", _("non-sector-aligned data is found in the core file"));
if (block != first_block
&& (grub_target_to_host64 (prev->start)
+ grub_target_to_host16 (prev->len)) == sector)
{
grub_uint16_t t = grub_target_to_host16 (prev->len) + 1;
prev->len = grub_host_to_target16 (t);
}
else
{
block->start = grub_host_to_target64 (sector);
block->len = grub_host_to_target16 (1);
#ifdef GRUB_SETUP_BIOS #ifdef GRUB_SETUP_BIOS
block->segment = grub_host_to_target16 (current_segment); bl.current_segment =
GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
#endif #endif
bl.last_length = GRUB_DISK_SECTOR_SIZE;
block--;
if (block->len)
grub_util_error ("%s", _("the sectors of the core file are too fragmented"));
}
last_length = length;
#ifdef GRUB_SETUP_BIOS
current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
#endif
}
/* Read the boot image by the OS service. */ /* Read the boot image by the OS service. */
boot_path = grub_util_get_path (dir, boot_file); boot_path = grub_util_get_path (dir, boot_file);
@ -283,9 +290,9 @@ setup (const char *dir,
core_img = grub_util_read_image (core_path); core_img = grub_util_read_image (core_path);
/* Have FIRST_BLOCK to point to the first blocklist. */ /* Have FIRST_BLOCK to point to the first blocklist. */
first_block = (struct grub_boot_blocklist *) (core_img bl.first_block = (struct grub_boot_blocklist *) (core_img
+ GRUB_DISK_SECTOR_SIZE + GRUB_DISK_SECTOR_SIZE
- sizeof (*block)); - sizeof (*bl.block));
grub_util_info ("root is `%s', dest is `%s'", root, dest); grub_util_info ("root is `%s', dest is `%s'", root, dest);
grub_util_info ("Opening dest"); grub_util_info ("Opening dest");
@ -511,38 +518,38 @@ setup (const char *dir,
assert (nsec <= maxsec); assert (nsec <= maxsec);
/* Clean out the blocklists. */ /* Clean out the blocklists. */
block = first_block; bl.block = bl.first_block;
while (block->len) while (bl.block->len)
{ {
grub_memset (block, 0, sizeof (block)); grub_memset (bl.block, 0, sizeof (bl.block));
block--; bl.block--;
if ((char *) block <= core_img) if ((char *) bl.block <= core_img)
grub_util_error ("%s", _("no terminator in the core image")); grub_util_error ("%s", _("no terminator in the core image"));
} }
save_first_sector (sectors[0] + grub_partition_get_start (ctx.container), save_first_sector (sectors[0] + grub_partition_get_start (ctx.container),
0, GRUB_DISK_SECTOR_SIZE); 0, GRUB_DISK_SECTOR_SIZE, &first_sector);
block = first_block; bl.block = bl.first_block;
for (i = 1; i < nsec; i++) for (i = 1; i < nsec; i++)
save_blocklists (sectors[i] + grub_partition_get_start (ctx.container), save_blocklists (sectors[i] + grub_partition_get_start (ctx.container),
0, GRUB_DISK_SECTOR_SIZE); 0, GRUB_DISK_SECTOR_SIZE, &bl);
/* Make sure that the last blocklist is a terminator. */ /* Make sure that the last blocklist is a terminator. */
if (block == first_block) if (bl.block == bl.first_block)
block--; bl.block--;
block->start = 0; bl.block->start = 0;
block->len = 0; bl.block->len = 0;
block->segment = 0; bl.block->segment = 0;
write_rootdev (root_dev, boot_img, first_sector); write_rootdev (root_dev, boot_img, first_sector);
core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
first_block = (struct grub_boot_blocklist *) (core_img bl.first_block = (struct grub_boot_blocklist *) (core_img
+ GRUB_DISK_SECTOR_SIZE + GRUB_DISK_SECTOR_SIZE
- sizeof (*block)); - sizeof (*bl.block));
grub_size_t no_rs_length; grub_size_t no_rs_length;
grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE
@ -698,22 +705,22 @@ unable_to_embed:
#endif #endif
/* Clean out the blocklists. */ /* Clean out the blocklists. */
block = first_block; bl.block = bl.first_block;
while (block->len) while (bl.block->len)
{ {
block->start = 0; bl.block->start = 0;
block->len = 0; bl.block->len = 0;
#ifdef GRUB_SETUP_BIOS #ifdef GRUB_SETUP_BIOS
block->segment = 0; bl.block->segment = 0;
#endif #endif
block--; bl.block--;
if ((char *) block <= core_img) if ((char *) bl.block <= core_img)
grub_util_error ("%s", _("no terminator in the core image")); grub_util_error ("%s", _("no terminator in the core image"));
} }
block = first_block; bl.block = bl.first_block;
#ifdef __linux__ #ifdef __linux__
{ {
@ -766,11 +773,11 @@ unable_to_embed:
if (i == 0 && j == 0) if (i == 0 && j == 0)
save_first_sector (((grub_uint64_t) blk) * mul save_first_sector (((grub_uint64_t) blk) * mul
+ container_start, + container_start,
0, rest); 0, rest, &first_sector);
else else
save_blocklists (((grub_uint64_t) blk) * mul + j save_blocklists (((grub_uint64_t) blk) * mul + j
+ container_start, + container_start,
0, rest); 0, rest, &bl);
} }
} }
} }
@ -806,13 +813,14 @@ unable_to_embed:
>> GRUB_DISK_SECTOR_BITS) >> GRUB_DISK_SECTOR_BITS)
+ j + container_start, + j + container_start,
fie2->fm_extents[i].fe_physical fie2->fm_extents[i].fe_physical
& (GRUB_DISK_SECTOR_SIZE - 1), len); & (GRUB_DISK_SECTOR_SIZE - 1), len,
&first_sector);
else else
save_blocklists ((fie2->fm_extents[i].fe_physical save_blocklists ((fie2->fm_extents[i].fe_physical
>> GRUB_DISK_SECTOR_BITS) >> GRUB_DISK_SECTOR_BITS)
+ j + container_start, + j + container_start,
fie2->fm_extents[i].fe_physical fie2->fm_extents[i].fe_physical
& (GRUB_DISK_SECTOR_SIZE - 1), len); & (GRUB_DISK_SECTOR_SIZE - 1), len, &bl);
} }
@ -830,12 +838,14 @@ unable_to_embed:
grub_util_error ("%s", grub_errmsg); grub_util_error ("%s", grub_errmsg);
file->read_hook = save_first_sector; file->read_hook = save_first_sector;
file->read_hook_data = &first_sector;
if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
!= GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("%s", _("failed to read the first sector of the core image")); grub_util_error ("%s", _("failed to read the first sector of the core image"));
block = first_block; bl.block = bl.first_block;
file->read_hook = save_blocklists; file->read_hook = save_blocklists;
file->read_hook_data = &bl;
if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE) if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE)
!= (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
grub_util_error ("%s", _("failed to read the rest sectors of the core image")); grub_util_error ("%s", _("failed to read the rest sectors of the core image"));
@ -913,11 +923,11 @@ unable_to_embed:
ptr += GRUB_DISK_SECTOR_SIZE; ptr += GRUB_DISK_SECTOR_SIZE;
len -= GRUB_DISK_SECTOR_SIZE; len -= GRUB_DISK_SECTOR_SIZE;
block = first_block; bl.block = bl.first_block;
while (block->len) while (bl.block->len)
{ {
size_t cur = grub_target_to_host16 (block->len) << GRUB_DISK_SECTOR_BITS; size_t cur = grub_target_to_host16 (bl.block->len) << GRUB_DISK_SECTOR_BITS;
blk = grub_target_to_host64 (block->start); blk = grub_target_to_host64 (bl.block->start);
if (cur > len) if (cur > len)
cur = len; cur = len;
@ -932,9 +942,9 @@ unable_to_embed:
ptr += cur; ptr += cur;
len -= cur; len -= cur;
block--; bl.block--;
if ((char *) block <= core_img) if ((char *) bl.block <= core_img)
grub_util_error ("%s", _("no terminator in the core image")); grub_util_error ("%s", _("no terminator in the core image"));
} }
core_dev->disk->partition = container; core_dev->disk->partition = container;