grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Remove nested functions from disk and file read hooks


From: Colin Watson
Subject: [PATCH] Remove nested functions from disk and file read hooks
Date: Mon, 21 Jan 2013 12:14:30 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

Part seven.  This particular patch in the set loses some of the
compressed-kernel size we'd gained from earlier patches, but it's still
a good bit smaller than when I started on this work so I'm not worried.
Note that, as a general pattern, I have intentionally not zeroed out
read_hook_data after calling code using a read hook; this is because (a)
the code that calls read hooks only checks whether read_hook is NULL,
(b) every function that sets read_hook to something non-NULL naturally
also sets read_hook_data if it cares about its value, and (c) avoiding
the extra code to zero read_hook_data makes a few bytes of difference to
the size of compressed core images.

  UP:   obj/i386-coreboot/grub-core/kernel.img (27868 < 27876) - change: 8
  UP:   obj/i386-ieee1275/grub-core/kernel.img (48364 < 48372) - change: 8
  UP:   obj/i386-pc/grub-core/kernel.img (28852 < 28860) - change: 8
  UP:   obj/amd64-efi/grub-core/affs.mod (8608 < 8624) - change: 16
  UP:   obj/amd64-efi/grub-core/afs.mod (9280 < 9344) - change: 64
  UP:   obj/amd64-efi/grub-core/bfs.mod (10672 < 10752) - change: 80
  DOWN: obj/amd64-efi/grub-core/blocklist.mod (3096 > 3048) - change: -48
  UP:   obj/amd64-efi/grub-core/exfat.mod (8272 < 8336) - change: 64
  UP:   obj/amd64-efi/grub-core/ext2.mod (9096 < 9112) - change: 16
  UP:   obj/amd64-efi/grub-core/fat.mod (8648 < 8680) - change: 32
  UP:   obj/amd64-efi/grub-core/fshelp.mod (4128 < 4144) - change: 16
  UP:   obj/amd64-efi/grub-core/hfs.mod (10800 < 10816) - change: 16
  UP:   obj/amd64-efi/grub-core/hfsplus.mod (10080 < 10096) - change: 16
  UP:   obj/amd64-efi/grub-core/jfs.mod (9416 < 9448) - change: 32
  DOWN: obj/amd64-efi/grub-core/loadenv.mod (8960 > 8928) - change: -32
  UP:   obj/amd64-efi/grub-core/minix2.mod (6032 < 6064) - change: 32
  UP:   obj/amd64-efi/grub-core/minix2_be.mod (6144 < 6176) - change: 32
  UP:   obj/amd64-efi/grub-core/minix3.mod (6016 < 6048) - change: 32
  UP:   obj/amd64-efi/grub-core/minix3_be.mod (6096 < 6128) - change: 32
  UP:   obj/amd64-efi/grub-core/minix_be.mod (6056 < 6072) - change: 16
  UP:   obj/amd64-efi/grub-core/nilfs2.mod (9976 < 9992) - change: 16
  UP:   obj/amd64-efi/grub-core/ntfs.mod (15600 < 15664) - change: 64
  UP:   obj/amd64-efi/grub-core/reiserfs.mod (14288 < 14304) - change: 16
  UP:   obj/amd64-efi/grub-core/romfs.mod (5784 < 5800) - change: 16
  UP:   obj/amd64-efi/grub-core/sfs.mod (7992 < 8008) - change: 16
  UP:   obj/amd64-efi/grub-core/udf.mod (11240 < 11256) - change: 16
  DOWN: obj/amd64-efi/grub-core/ufs1.mod (8144 > 8128) - change: -16
  UP:   obj/amd64-efi/grub-core/ufs1_be.mod (8256 < 8304) - change: 48
  DOWN: obj/amd64-efi/grub-core/ufs2.mod (8160 > 8144) - change: -16
  UP:   obj/amd64-efi/grub-core/xfs.mod (8968 < 8984) - change: 16
  UP:   obj/i386-coreboot/grub-core/affs.mod (5652 < 5656) - change: 4
  UP:   obj/i386-coreboot/grub-core/afs.mod (6912 < 6936) - change: 24
  UP:   obj/i386-coreboot/grub-core/bfs.mod (7656 < 7680) - change: 24
  DOWN: obj/i386-coreboot/grub-core/blocklist.mod (2076 > 1992) - change: -84
  UP:   obj/i386-coreboot/grub-core/exfat.mod (5296 < 5332) - change: 36
  UP:   obj/i386-coreboot/grub-core/ext2.mod (5976 < 5992) - change: 16
  UP:   obj/i386-coreboot/grub-core/fat.mod (5620 < 5640) - change: 20
  UP:   obj/i386-coreboot/grub-core/fshelp.mod (2812 < 2816) - change: 4
  DOWN: obj/i386-coreboot/grub-core/hdparm.mod (7212 > 7208) - change: -4
  UP:   obj/i386-coreboot/grub-core/hfs.mod (7228 < 7232) - change: 4
  UP:   obj/i386-coreboot/grub-core/hfsplus.mod (6596 < 6620) - change: 24
  UP:   obj/i386-coreboot/grub-core/iso9660.mod (8796 < 8804) - change: 8
  UP:   obj/i386-coreboot/grub-core/jfs.mod (6560 < 6580) - change: 20
  DOWN: obj/i386-coreboot/grub-core/loadenv.mod (5568 > 5544) - change: -24
  UP:   obj/i386-coreboot/grub-core/minix.mod (3768 < 3792) - change: 24
  UP:   obj/i386-coreboot/grub-core/minix2.mod (3836 < 3860) - change: 24
  UP:   obj/i386-coreboot/grub-core/minix2_be.mod (3924 < 3956) - change: 32
  UP:   obj/i386-coreboot/grub-core/minix3.mod (3800 < 3832) - change: 32
  UP:   obj/i386-coreboot/grub-core/minix3_be.mod (3872 < 3920) - change: 48
  UP:   obj/i386-coreboot/grub-core/minix_be.mod (3864 < 3896) - change: 32
  UP:   obj/i386-coreboot/grub-core/nilfs2.mod (6600 < 6616) - change: 16
  UP:   obj/i386-coreboot/grub-core/ntfs.mod (10492 < 10496) - change: 4
  UP:   obj/i386-coreboot/grub-core/reiserfs.mod (8952 < 8964) - change: 12
  UP:   obj/i386-coreboot/grub-core/romfs.mod (4068 < 4076) - change: 8
  UP:   obj/i386-coreboot/grub-core/udf.mod (7644 < 7668) - change: 24
  UP:   obj/i386-coreboot/grub-core/ufs1.mod (5468 < 5500) - change: 32
  UP:   obj/i386-coreboot/grub-core/ufs1_be.mod (5596 < 5632) - change: 36
  UP:   obj/i386-coreboot/grub-core/ufs2.mod (5552 < 5584) - change: 32
  UP:   obj/i386-coreboot/grub-core/xfs.mod (6036 < 6060) - change: 24
  UP:   obj/i386-efi/grub-core/affs.mod (5748 < 5752) - change: 4
  UP:   obj/i386-efi/grub-core/afs.mod (6976 < 7020) - change: 44
  UP:   obj/i386-efi/grub-core/bfs.mod (7780 < 7816) - change: 36
  DOWN: obj/i386-efi/grub-core/blocklist.mod (2128 > 2076) - change: -52
  UP:   obj/i386-efi/grub-core/exfat.mod (5452 < 5476) - change: 24
  UP:   obj/i386-efi/grub-core/ext2.mod (6144 < 6156) - change: 12
  UP:   obj/i386-efi/grub-core/fat.mod (5808 < 5824) - change: 16
  UP:   obj/i386-efi/grub-core/fshelp.mod (2856 < 2860) - change: 4
  UP:   obj/i386-efi/grub-core/hfs.mod (7344 < 7356) - change: 12
  UP:   obj/i386-efi/grub-core/hfsplus.mod (6832 < 6852) - change: 20
  UP:   obj/i386-efi/grub-core/iso9660.mod (9140 < 9148) - change: 8
  UP:   obj/i386-efi/grub-core/jfs.mod (6632 < 6644) - change: 12
  DOWN: obj/i386-efi/grub-core/loadenv.mod (5804 > 5784) - change: -20
  UP:   obj/i386-efi/grub-core/minix.mod (3784 < 3804) - change: 20
  UP:   obj/i386-efi/grub-core/minix2.mod (3880 < 3900) - change: 20
  UP:   obj/i386-efi/grub-core/minix2_be.mod (4004 < 4028) - change: 24
  UP:   obj/i386-efi/grub-core/minix3.mod (3868 < 3892) - change: 24
  UP:   obj/i386-efi/grub-core/minix3_be.mod (3948 < 3972) - change: 24
  UP:   obj/i386-efi/grub-core/minix_be.mod (3920 < 3940) - change: 20
  UP:   obj/i386-efi/grub-core/nilfs2.mod (6712 < 6728) - change: 16
  UP:   obj/i386-efi/grub-core/ntfs.mod (10800 < 10812) - change: 12
  UP:   obj/i386-efi/grub-core/reiserfs.mod (9216 < 9224) - change: 8
  UP:   obj/i386-efi/grub-core/udf.mod (7916 < 7928) - change: 12
  UP:   obj/i386-efi/grub-core/ufs1.mod (5548 < 5592) - change: 44
  UP:   obj/i386-efi/grub-core/ufs1_be.mod (5700 < 5720) - change: 20
  UP:   obj/i386-efi/grub-core/ufs2.mod (5632 < 5652) - change: 20
  UP:   obj/i386-efi/grub-core/xfs.mod (6236 < 6260) - change: 24
  UP:   obj/i386-ieee1275/grub-core/affs.mod (5652 < 5656) - change: 4
  UP:   obj/i386-ieee1275/grub-core/afs.mod (6912 < 6936) - change: 24
  UP:   obj/i386-ieee1275/grub-core/bfs.mod (7656 < 7680) - change: 24
  DOWN: obj/i386-ieee1275/grub-core/blocklist.mod (2076 > 1992) - change: -84
  UP:   obj/i386-ieee1275/grub-core/exfat.mod (5296 < 5332) - change: 36
  UP:   obj/i386-ieee1275/grub-core/ext2.mod (5976 < 5992) - change: 16
  UP:   obj/i386-ieee1275/grub-core/fat.mod (5620 < 5640) - change: 20
  UP:   obj/i386-ieee1275/grub-core/fshelp.mod (2812 < 2816) - change: 4
  DOWN: obj/i386-ieee1275/grub-core/hdparm.mod (7140 > 7136) - change: -4
  UP:   obj/i386-ieee1275/grub-core/hfs.mod (7228 < 7232) - change: 4
  UP:   obj/i386-ieee1275/grub-core/hfsplus.mod (6596 < 6620) - change: 24
  UP:   obj/i386-ieee1275/grub-core/iso9660.mod (8796 < 8804) - change: 8
  UP:   obj/i386-ieee1275/grub-core/jfs.mod (6560 < 6580) - change: 20
  DOWN: obj/i386-ieee1275/grub-core/loadenv.mod (5496 > 5472) - change: -24
  UP:   obj/i386-ieee1275/grub-core/minix.mod (3768 < 3792) - change: 24
  UP:   obj/i386-ieee1275/grub-core/minix2.mod (3836 < 3860) - change: 24
  UP:   obj/i386-ieee1275/grub-core/minix2_be.mod (3924 < 3956) - change: 32
  UP:   obj/i386-ieee1275/grub-core/minix3.mod (3800 < 3832) - change: 32
  UP:   obj/i386-ieee1275/grub-core/minix3_be.mod (3872 < 3920) - change: 48
  UP:   obj/i386-ieee1275/grub-core/minix_be.mod (3864 < 3896) - change: 32
  UP:   obj/i386-ieee1275/grub-core/nilfs2.mod (6600 < 6616) - change: 16
  UP:   obj/i386-ieee1275/grub-core/ntfs.mod (10492 < 10496) - change: 4
  UP:   obj/i386-ieee1275/grub-core/reiserfs.mod (8952 < 8964) - change: 12
  UP:   obj/i386-ieee1275/grub-core/romfs.mod (4068 < 4076) - change: 8
  UP:   obj/i386-ieee1275/grub-core/udf.mod (7644 < 7668) - change: 24
  UP:   obj/i386-ieee1275/grub-core/ufs1.mod (5468 < 5500) - change: 32
  UP:   obj/i386-ieee1275/grub-core/ufs1_be.mod (5596 < 5632) - change: 36
  UP:   obj/i386-ieee1275/grub-core/ufs2.mod (5552 < 5584) - change: 32
  UP:   obj/i386-ieee1275/grub-core/xfs.mod (6036 < 6060) - change: 24
  UP:   obj/i386-pc/grub-core/affs.mod (5652 < 5656) - change: 4
  UP:   obj/i386-pc/grub-core/afs.mod (6912 < 6936) - change: 24
  UP:   obj/i386-pc/grub-core/bfs.mod (7656 < 7680) - change: 24
  DOWN: obj/i386-pc/grub-core/blocklist.mod (2076 > 1992) - change: -84
  UP:   obj/i386-pc/grub-core/exfat.mod (5296 < 5332) - change: 36
  UP:   obj/i386-pc/grub-core/ext2.mod (5976 < 5992) - change: 16
  UP:   obj/i386-pc/grub-core/fat.mod (5620 < 5640) - change: 20
  UP:   obj/i386-pc/grub-core/fshelp.mod (2812 < 2816) - change: 4
  DOWN: obj/i386-pc/grub-core/hdparm.mod (7212 > 7208) - change: -4
  UP:   obj/i386-pc/grub-core/hfs.mod (7228 < 7232) - change: 4
  UP:   obj/i386-pc/grub-core/hfsplus.mod (6596 < 6620) - change: 24
  UP:   obj/i386-pc/grub-core/iso9660.mod (8796 < 8804) - change: 8
  UP:   obj/i386-pc/grub-core/jfs.mod (6560 < 6580) - change: 20
  DOWN: obj/i386-pc/grub-core/loadenv.mod (5568 > 5544) - change: -24
  UP:   obj/i386-pc/grub-core/minix.mod (3768 < 3792) - change: 24
  UP:   obj/i386-pc/grub-core/minix2.mod (3836 < 3860) - change: 24
  UP:   obj/i386-pc/grub-core/minix2_be.mod (3924 < 3956) - change: 32
  UP:   obj/i386-pc/grub-core/minix3.mod (3800 < 3832) - change: 32
  UP:   obj/i386-pc/grub-core/minix3_be.mod (3872 < 3920) - change: 48
  UP:   obj/i386-pc/grub-core/minix_be.mod (3864 < 3896) - change: 32
  UP:   obj/i386-pc/grub-core/nilfs2.mod (6600 < 6616) - change: 16
  UP:   obj/i386-pc/grub-core/ntfs.mod (10492 < 10496) - change: 4
  UP:   obj/i386-pc/grub-core/reiserfs.mod (8952 < 8964) - change: 12
  UP:   obj/i386-pc/grub-core/romfs.mod (4068 < 4076) - change: 8
  UP:   obj/i386-pc/grub-core/udf.mod (7644 < 7668) - change: 24
  UP:   obj/i386-pc/grub-core/ufs1.mod (5468 < 5500) - change: 32
  UP:   obj/i386-pc/grub-core/ufs1_be.mod (5596 < 5632) - change: 36
  UP:   obj/i386-pc/grub-core/ufs2.mod (5552 < 5584) - change: 32
  UP:   obj/i386-pc/grub-core/xfs.mod (6036 < 6060) - change: 24
  UP:   i386-pc core image (biosdisk ext2 part_msdos) (26604 < 26647) - change: 
43
  UP:   i386-pc core image (biosdisk ext2 part_msdos lvm mdraid1x) (33959 < 
34004) - change: 45

=== modified file 'ChangeLog'
--- ChangeLog   2013-01-21 11:10:25 +0000
+++ ChangeLog   2013-01-21 11:15:16 +0000
@@ -1,5 +1,17 @@
 2013-01-21  Colin Watson  <address@hidden>
 
+       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.
+
+2013-01-21  Colin Watson  <address@hidden>
+
        * grub-core/partmap/msdos.c (embed_signatures): Add the signature of
        an Acer registration utility with several sightings in the wild.
        Reported by: Rickard Westman.  Fixes Ubuntu bug #987022.

=== modified file 'grub-core/commands/blocklist.c'
--- grub-core/commands/blocklist.c      2012-02-08 18:26:01 +0000
+++ grub-core/commands/blocklist.c      2013-01-21 09:46:39 +0000
@@ -28,58 +28,71 @@
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
-static grub_err_t
-grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
-                   int argc, char **args)
+/* Context for grub_cmd_blocklist.  */
+struct blocklist_ctx
 {
-  grub_file_t file;
-  char buf[GRUB_DISK_SECTOR_SIZE];
-  unsigned long start_sector = 0;
-  unsigned num_sectors = 0;
-  int num_entries = 0;
-  grub_disk_addr_t part_start = 0;
-  auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned 
offset,
-                           unsigned length);
-  auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, 
unsigned num,
-                            unsigned offset, unsigned length);
+  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;
 
-  void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned 
offset,
-                      unsigned length)
+  if (ctx->num_sectors > 0)
     {
-      if (num_sectors > 0)
+      if (ctx->start_sector + ctx->num_sectors == sector
+         && offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
        {
-         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;
+         ctx->num_sectors++;
+         return;
        }
 
-      if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
-       {
-         start_sector = sector;
-         num_sectors++;
-       }
-      else
-       print_blocklist (sector, 0, offset, length);
+      print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
+      ctx->num_sectors = 0;
     }
 
-  void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
-                       unsigned offset, unsigned length)
+  if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
     {
-      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);
+      ctx->start_sector = sector;
+      ctx->num_sectors++;
     }
+  else
+    print_blocklist (sector, 0, offset, length, ctx);
+}
+
+static grub_err_t
+grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
+                   int argc, char **args)
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  struct blocklist_ctx ctx = {
+    .start_sector = 0,
+    .num_sectors = 0,
+    .num_entries = 0,
+    .part_start = 0
+  };
 
   if (argc < 1)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -93,15 +106,16 @@ grub_cmd_blocklist (grub_command_t cmd _
     return grub_error (GRUB_ERR_BAD_DEVICE,
                       "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_data = &ctx;
 
   while (grub_file_read (file, buf, sizeof (buf)) > 0)
     ;
 
-  if (num_sectors > 0)
-    print_blocklist (start_sector, num_sectors, 0, 0);
+  if (ctx.num_sectors > 0)
+    print_blocklist (ctx.start_sector, ctx.num_sectors, 0, 0, &ctx);
 
   grub_file_close (file);
 

=== modified file 'grub-core/commands/loadenv.c'
--- grub-core/commands/loadenv.c        2012-12-31 17:31:38 +0000
+++ grub-core/commands/loadenv.c        2013-01-21 11:29:26 +0000
@@ -284,44 +284,51 @@ write_blocklists (grub_envblk_t envblk,
   return 1;
 }
 
+/* Context for grub_cmd_save_env.  */
+struct grub_cmd_save_env_ctx
+{
+  struct blocklist *head, *tail;
+};
+
+/* Store blocklists in a linked list.  */
+static void
+save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
+                   void *data)
+{
+  struct grub_cmd_save_env_ctx *ctx = data;
+  struct blocklist *block;
+
+  if (offset + length > GRUB_DISK_SECTOR_SIZE)
+    /* Seemingly a bug.  */
+    return;
+
+  block = grub_malloc (sizeof (*block));
+  if (! block)
+    return;
+
+  block->sector = sector;
+  block->offset = offset;
+  block->length = length;
+
+  /* Slightly complicated, because the list should be FIFO.  */
+  block->next = 0;
+  if (ctx->tail)
+    ctx->tail->next = block;
+  ctx->tail = block;
+  if (! ctx->head)
+    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 blocklist *head = 0;
-  struct blocklist *tail = 0;
-
-  /* Store blocklists in a linked list.  */
-  auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
-                                        unsigned offset,
-                                        unsigned length);
-  void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
-                                   unsigned offset, unsigned length)
-    {
-      struct blocklist *block;
-
-      if (offset + length > GRUB_DISK_SECTOR_SIZE)
-        /* Seemingly a bug.  */
-        return;
-
-      block = grub_malloc (sizeof (*block));
-      if (! block)
-        return;
-
-      block->sector = sector;
-      block->offset = offset;
-      block->length = length;
-
-      /* Slightly complicated, because the list should be FIFO.  */
-      block->next = 0;
-      if (tail)
-        tail->next = block;
-      tail = block;
-      if (! head)
-        head = block;
-    }
+  struct grub_cmd_save_env_ctx ctx = {
+    .head = 0,
+    .tail = 0
+  };
 
   if (! argc)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
@@ -336,13 +343,14 @@ grub_cmd_save_env (grub_extcmd_context_t
       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);
   file->read_hook = 0;
   if (! envblk)
     goto fail;
 
-  if (check_blocklists (envblk, head, file))
+  if (check_blocklists (envblk, ctx.head, file))
     goto fail;
 
   while (argc)
@@ -363,12 +371,12 @@ grub_cmd_save_env (grub_extcmd_context_t
       args++;
     }
 
-  write_blocklists (envblk, head, file);
+  write_blocklists (envblk, ctx.head, file);
 
  fail:
   if (envblk)
     grub_envblk_close (envblk);
-  free_blocklists (head);
+  free_blocklists (ctx.head);
   grub_file_close (file);
   return grub_errno;
 }

=== modified file 'grub-core/commands/testload.c'
--- grub-core/commands/testload.c       2012-02-24 11:30:32 +0000
+++ grub-core/commands/testload.c       2013-01-21 09:48:28 +0000
@@ -31,6 +31,17 @@
 
 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
 grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
                   int argc, char *argv[])
@@ -39,15 +50,6 @@ grub_cmd_testload (struct grub_command *
   char *buf;
   grub_size_t size;
   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)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -68,7 +70,7 @@ grub_cmd_testload (struct grub_command *
     goto fail;
 
   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)
     goto fail;
   grub_printf (" Done.\n");

=== modified file 'grub-core/fs/affs.c'
--- grub-core/fs/affs.c 2013-01-21 01:33:46 +0000
+++ grub-core/fs/affs.c 2013-01-21 09:46:14 +0000
@@ -531,7 +531,7 @@ grub_affs_read (grub_file_t file, char *
     (struct grub_affs_data *) file->data;
 
   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,
                                grub_be_to_cpu32 (data->diropen.di.size),
                                data->log_blocksize, 0);

=== modified file 'grub-core/fs/bfs.c'
--- grub-core/fs/bfs.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/bfs.c  2013-01-21 11:28:53 +0000
@@ -217,9 +217,7 @@ read_bfs_file (grub_disk_t disk,
               const struct grub_bfs_superblock *sb,
               const struct grub_bfs_inode *ino,
               grub_off_t off, void *buf, grub_size_t len,
-              void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                                  unsigned offset,
-                                                  unsigned length))
+              grub_disk_read_hook_t read_hook, void *read_hook_data)
 {
   if (len == 0)
     return GRUB_ERR_NONE;
@@ -245,6 +243,7 @@ read_bfs_file (grub_disk_t disk,
              if (read_size > len)
                read_size = len;
              disk->read_hook = read_hook;
+             disk->read_hook_data = read_hook_data;
              err = read_extent (disk, sb, &ino->direct[i], 0, off - pos,
                                 buf, read_size);
              disk->read_hook = 0;
@@ -290,6 +289,7 @@ read_bfs_file (grub_disk_t disk,
              if (read_size > len)
                read_size = len;
              disk->read_hook = read_hook;
+             disk->read_hook_data = read_hook_data;
              err = read_extent (disk, sb, &entries[i], 0, off - pos,
                                 buf, read_size);
              disk->read_hook = 0;
@@ -401,6 +401,7 @@ read_bfs_file (grub_disk_t disk,
        if (read_size > len)
          read_size = len;
        disk->read_hook = read_hook;
+       disk->read_hook_data = read_hook_data;
        err = read_extent (disk, sb, &l2_entries[l2n], 0, boff,
                           buf, read_size);
        disk->read_hook = 0;
@@ -431,7 +432,7 @@ iterate_in_b_tree (grub_disk_t disk,
   int level;
   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)
     return 0;
   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;
       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)
        return 0;
       err = read_bfs_file (disk, sb, ino, node_off
@@ -451,7 +453,7 @@ iterate_in_b_tree (grub_disk_t disk,
                                       BTREE_ALIGN) +
                           grub_bfs_to_cpu_treehead (node.count_keys) *
                           sizeof (grub_uint16_t), &key_value,
-                          sizeof (grub_uint64_t), 0);
+                          sizeof (grub_uint64_t), 0, 0);
       if (err)
        return 0;
 
@@ -461,7 +463,8 @@ iterate_in_b_tree (grub_disk_t disk,
   while (1)
     {
       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)
        return 0;
       {
@@ -473,7 +476,7 @@ iterate_in_b_tree (grub_disk_t disk,
 
        err =
          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)
          return 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),
                             keylen_idx,
                             grub_bfs_to_cpu_treehead (node.count_keys) *
-                            sizeof (grub_uint16_t), 0);
+                            sizeof (grub_uint16_t), 0, 0);
        if (err)
          return 0;
        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) *
                             sizeof (grub_uint16_t), key_values,
                             grub_bfs_to_cpu_treehead (node.count_keys) *
-                            sizeof (grub_uint64_t), 0);
+                            sizeof (grub_uint64_t), 0, 0);
        if (err)
          return 0;
 
@@ -556,7 +559,7 @@ find_in_b_tree (grub_disk_t disk,
   int level;
   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)
     return err;
   node_off = grub_bfs_to_cpu64 (head.root);
@@ -565,7 +568,8 @@ find_in_b_tree (grub_disk_t disk,
   while (1)
     {
       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)
        return err;
       if (node.count_keys == 0)
@@ -578,7 +582,7 @@ find_in_b_tree (grub_disk_t disk,
        unsigned i;
        err =
          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)
          return err;
        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),
                                       BTREE_ALIGN), keylen_idx,
                             grub_bfs_to_cpu_treehead (node.count_keys) *
-                            sizeof (grub_uint16_t), 0);
+                            sizeof (grub_uint16_t), 0, 0);
        if (err)
          return err;
        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) *
                             sizeof (grub_uint16_t), key_values,
                             grub_bfs_to_cpu_treehead (node.count_keys) *
-                            sizeof (grub_uint64_t), 0);
+                            sizeof (grub_uint64_t), 0, 0);
        if (err)
          return err;
 
@@ -771,7 +775,7 @@ find_file (const char *path, grub_disk_t
                  return grub_errno;
                }
              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)
                {
                  grub_free (alloc);
@@ -974,7 +978,8 @@ grub_bfs_read (grub_file_t file, char *b
   struct grub_bfs_data *data = file->data;
 
   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)
     return -1;
   return len;
@@ -1056,7 +1061,7 @@ read_bfs_attr (grub_disk_t disk,
       if (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)
        return -1;
       return read;

=== modified file 'grub-core/fs/ext2.c'
--- grub-core/fs/ext2.c 2013-01-21 01:33:46 +0000
+++ grub-core/fs/ext2.c 2013-01-21 12:02:09 +0000
@@ -525,11 +525,11 @@ grub_ext2_read_block (grub_fshelp_node_t
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_ext2_read_file (grub_fshelp_node_t node,
-                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                       unsigned offset, unsigned length),
+                    grub_disk_read_hook_t read_hook, void *read_hook_data,
                     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,
                                grub_cpu_to_le32 (node->inode.size)
                                | (((grub_off_t) grub_cpu_to_le32 
(node->inode.size_high)) << 32),
@@ -676,7 +676,7 @@ grub_ext2_read_symlink (grub_fshelp_node
                  grub_le_to_cpu32 (diro->inode.size));
   else
     {
-      grub_ext2_read_file (diro, 0, 0,
+      grub_ext2_read_file (diro, 0, 0, 0,
                           grub_le_to_cpu32 (diro->inode.size),
                           symlink);
       if (grub_errno)
@@ -709,7 +709,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_
     {
       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);
       if (grub_errno)
        return 0;
@@ -723,7 +723,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_
          struct grub_fshelp_node *fdiro;
          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);
          if (grub_errno)
            return 0;
@@ -850,7 +850,8 @@ grub_ext2_read (grub_file_t file, char *
 {
   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);
 }
 

=== modified file 'grub-core/fs/fat.c'
--- grub-core/fs/fat.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/fat.c  2013-01-21 11:29:18 +0000
@@ -454,8 +454,7 @@ grub_fat_mount (grub_disk_t disk)
 
 static grub_ssize_t
 grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
+                   grub_disk_read_hook_t read_hook, void *read_hook_data,
                    grub_off_t offset, grub_size_t len, char *buf)
 {
   grub_size_t size;
@@ -561,6 +560,7 @@ grub_fat_read_data (grub_disk_t disk, st
        size = len;
 
       disk->read_hook = read_hook;
+      disk->read_hook_data = read_hook_data;
       grub_disk_read (disk, sector, offset, size, buf);
       disk->read_hook = 0;
       if (grub_errno)
@@ -630,7 +630,7 @@ grub_fat_iterate_dir_next (grub_disk_t d
 
       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)
           != sizeof (dir))
        break;
@@ -652,7 +652,7 @@ grub_fat_iterate_dir_next (grub_disk_t d
            {
              struct grub_fat_dir_entry 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)
                  != sizeof (sec))
                break;
@@ -729,7 +729,7 @@ grub_fat_iterate_dir_next (grub_disk_t d
       ctxt->offset += sizeof (ctxt->dir);
 
       /* 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),
                              (char *) &ctxt->dir)
           != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
@@ -1031,7 +1031,8 @@ grub_fat_open (grub_file_t file, const c
 static grub_ssize_t
 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);
 }
 
@@ -1064,7 +1065,7 @@ grub_fat_label (grub_device_t device, ch
     {
       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)
           != sizeof (dir))
        break;

=== modified file 'grub-core/fs/fshelp.c'
--- grub-core/fs/fshelp.c       2013-01-21 01:33:46 +0000
+++ grub-core/fs/fshelp.c       2013-01-21 11:29:13 +0000
@@ -242,14 +242,13 @@ grub_fshelp_find_file (const char *path,
 
 /* 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
-   blocks to disk blocks.  The file is FILESIZE bytes big and the
+   reading a block from the file.  READ_HOOK_DATA is passed through as
+   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).  */
 grub_ssize_t
 grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
-                      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                                           unsigned offset,
-                                                           unsigned length),
+                      grub_disk_read_hook_t read_hook, void *read_hook_data,
                       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 block),
@@ -301,6 +300,7 @@ grub_fshelp_read_file (grub_disk_t disk,
       if (blknr)
        {
          disk->read_hook = read_hook;
+         disk->read_hook_data = read_hook_data;
 
          grub_disk_read (disk, blknr + blocks_start, skipfirst,
                          blockend, buf);

=== modified file 'grub-core/fs/hfs.c'
--- grub-core/fs/hfs.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/hfs.c  2013-01-21 11:28:41 +0000
@@ -243,8 +243,7 @@ grub_hfs_block (struct grub_hfs_data *da
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_hfs_read_file (struct grub_hfs_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
+                   grub_disk_read_hook_t read_hook, void *read_hook_data,
                    grub_off_t pos, grub_size_t len, char *buf)
 {
   grub_off_t i;
@@ -289,6 +288,7 @@ grub_hfs_read_file (struct grub_hfs_data
       if (blknr)
        {
          data->disk->read_hook = read_hook;
+         data->disk->read_hook_data = read_hook_data;
          grub_disk_read (data->disk, blknr, skipfirst,
                          blockend, buf);
          data->disk->read_hook = 0;
@@ -1269,7 +1269,8 @@ grub_hfs_read (grub_file_t file, char *b
   struct grub_hfs_data *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);
 }
 
 

=== modified file 'grub-core/fs/hfsplus.c'
--- grub-core/fs/hfsplus.c      2013-01-21 01:33:46 +0000
+++ grub-core/fs/hfsplus.c      2013-01-21 09:46:14 +0000
@@ -375,11 +375,11 @@ grub_hfsplus_read_block (grub_fshelp_nod
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_hfsplus_read_file (grub_fshelp_node_t node,
-                       void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                          unsigned offset, unsigned length),
+                       grub_disk_read_hook_t read_hook, void *read_hook_data,
                        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,
                                node->size,
                                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);
 
   /* 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 (header), (char *) &header) <= 0)
     goto fail;
@@ -487,14 +487,14 @@ grub_hfsplus_mount (grub_disk_t disk)
   data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
                          (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 (header), (char *) &header) <= 0)
     goto fail;
 
   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)
     goto fail;
 
@@ -605,7 +605,7 @@ grub_hfsplus_read_symlink (grub_fshelp_n
   if (!symlink)
     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)
     {
       grub_free (symlink);
@@ -649,7 +649,7 @@ grub_hfsplus_btree_iterate_node (struct
        saved_node = first_node->next;
       node_count++;
 
-      if (grub_hfsplus_read_file (&btree->file, 0,
+      if (grub_hfsplus_read_file (&btree->file, 0, 0,
                                  (((grub_disk_addr_t)
                                    grub_be_to_cpu32 (first_node->next))
                                   * btree->nodesize),
@@ -702,7 +702,7 @@ grub_hfsplus_btree_search (struct grub_h
       node_count++;
 
       /* 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) btree->nodesize,
                                  btree->nodesize, (char *) node) <= 0)
@@ -971,8 +971,9 @@ grub_hfsplus_read (grub_file_t file, cha
   struct grub_hfsplus_data *data =
     (struct grub_hfsplus_data *) file->data;
 
-  return grub_hfsplus_read_file (&data->opened_file, file->read_hook,
-                                    file->offset, len, buf);
+  return grub_hfsplus_read_file (&data->opened_file,
+                                file->read_hook, file->read_hook_data,
+                                file->offset, len, buf);
 }
 
 /* Context for grub_hfsplus_dir.  */

=== modified file 'grub-core/fs/iso9660.c'
--- grub-core/fs/iso9660.c      2013-01-21 01:33:46 +0000
+++ grub-core/fs/iso9660.c      2013-01-21 12:07:49 +0000
@@ -961,6 +961,7 @@ grub_iso9660_read (grub_file_t file, cha
 
   /* XXX: The file is stored in as a single extent.  */
   data->disk->read_hook = file->read_hook;
+  data->disk->read_hook_data = file->read_hook_data;
   read_node (data->node, file->offset, len, buf);
   data->disk->read_hook = NULL;
 

=== modified file 'grub-core/fs/jfs.c'
--- grub-core/fs/jfs.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/jfs.c  2013-01-21 11:28:44 +0000
@@ -577,8 +577,7 @@ grub_jfs_getent (struct grub_jfs_diropen
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_jfs_read_file (struct grub_jfs_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
+                   grub_disk_read_hook_t read_hook, void *read_hook_data,
                    grub_off_t pos, grub_size_t len, char *buf)
 {
   grub_off_t i;
@@ -616,6 +615,7 @@ grub_jfs_read_file (struct grub_jfs_data
        }
 
       data->disk->read_hook = read_hook;
+      data->disk->read_hook_data = read_hook_data;
       grub_disk_read (data->disk,
                      blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz)
                                - GRUB_DISK_SECTOR_BITS),
@@ -782,7 +782,7 @@ grub_jfs_lookup_symlink (struct grub_jfs
 
   if (size <= sizeof (data->currinode.symlink.path))
     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;
 
   symlink[size] = '\0';
@@ -894,7 +894,8 @@ grub_jfs_read (grub_file_t file, char *b
   struct grub_jfs_data *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);
 }
 
 

=== modified file 'grub-core/fs/minix.c'
--- grub-core/fs/minix.c        2013-01-21 01:33:46 +0000
+++ grub-core/fs/minix.c        2013-01-21 11:29:15 +0000
@@ -249,8 +249,7 @@ grub_minix_get_file_block (struct grub_m
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_minix_read_file (struct grub_minix_data *data,
-                     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                        unsigned offset, unsigned length),
+                     grub_disk_read_hook_t read_hook, void *read_hook_data,
                      grub_off_t pos, grub_size_t len, char *buf)
 {
   grub_uint32_t i;
@@ -301,6 +300,7 @@ grub_minix_read_file (struct grub_minix_
        }
 
       data->disk->read_hook = read_hook;
+      data->disk->read_hook_data = read_hook_data;
       grub_disk_read (data->disk,
                      GRUB_MINIX_ZONE2SECT(blknr),
                      skipfirst, blockend, buf);
@@ -352,7 +352,7 @@ grub_minix_lookup_symlink (struct grub_m
   if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT)
     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)
     return grub_errno;
 
@@ -409,10 +409,10 @@ grub_minix_find_file (struct grub_minix_
       if (grub_strlen (name) == 0)
        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)
        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)
        return grub_errno;
 
@@ -568,11 +568,11 @@ grub_minix_dir (grub_device_t device, co
       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)
        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)
        return grub_errno;
@@ -649,7 +649,8 @@ grub_minix_read (grub_file_t file, char
   struct grub_minix_data *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);
 }
 
 

=== modified file 'grub-core/fs/nilfs2.c'
--- grub-core/fs/nilfs2.c       2013-01-21 01:33:46 +0000
+++ grub-core/fs/nilfs2.c       2013-01-21 09:46:14 +0000
@@ -630,13 +630,11 @@ grub_nilfs2_read_block (grub_fshelp_node
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_nilfs2_read_file (grub_fshelp_node_t node,
-                      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
-                                                          sector,
-                                                          unsigned offset,
-                                                          unsigned length),
+                      grub_disk_read_hook_t read_hook, void *read_hook_data,
                       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,
                                grub_le_to_cpu64 (node->inode.i_size),
                                LOG2_NILFS2_BLOCK_SIZE (node->data), 0);
@@ -856,7 +854,7 @@ grub_nilfs2_read_symlink (grub_fshelp_no
   if (!symlink)
     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);
   if (grub_errno)
     {
@@ -887,7 +885,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_nod
     {
       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),
                             (char *) &dirent);
       if (grub_errno)
@@ -902,7 +900,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_nod
          struct grub_fshelp_node *fdiro;
          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),
                                 dirent.name_len, filename);
          if (grub_errno)
@@ -1025,7 +1023,8 @@ grub_nilfs2_read (grub_file_t file, char
 {
   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);
 }
 

=== modified file 'grub-core/fs/ntfs.c'
--- grub-core/fs/ntfs.c 2013-01-21 01:33:46 +0000
+++ grub-core/fs/ntfs.c 2013-01-21 11:28:33 +0000
@@ -91,21 +91,15 @@ static grub_err_t read_mft (struct grub_
 static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest,
                             grub_disk_addr_t ofs, grub_size_t len,
                             int cached,
-                            void
-                            NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
-                                                           sector,
-                                                           unsigned offset,
-                                                           unsigned length));
+                            grub_disk_read_hook_t read_hook,
+                            void *read_hook_data);
 
 static grub_err_t 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,
-                            void
-                            NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
-                                                           sector,
-                                                           unsigned offset,
-                                                           unsigned length));
+                            grub_disk_read_hook_t read_hook,
+                            void *read_hook_data);
 
 static void
 init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
@@ -207,7 +201,7 @@ find_attr (struct grub_ntfs_attr *at, gr
          at->edat_buf = grub_malloc (n);
          if (!at->edat_buf)
            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,
                          "fail to read non-resident attribute list");
@@ -249,7 +243,7 @@ find_attr (struct grub_ntfs_attr *at, gr
              if (read_attr
                  (at, pa + 0x10,
                   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;
              pa += u16at (pa, 4);
            }
@@ -325,9 +319,7 @@ retry:
     {
       if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST))
        {
-         void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector,
-                                             unsigned offset,
-                                             unsigned length);
+         grub_disk_read_hook_t save_hook;
 
          save_hook = ctx->comp.disk->read_hook;
          ctx->comp.disk->read_hook = 0;
@@ -379,9 +371,7 @@ grub_ntfs_read_block (grub_fshelp_node_t
 static grub_err_t
 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,
-          void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                              unsigned offset,
-                                              unsigned length))
+          grub_disk_read_hook_t read_hook, void *read_hook_data)
 {
   grub_disk_addr_t vcn;
   struct grub_ntfs_rlst cc, *ctx;
@@ -480,7 +470,8 @@ read_data (struct grub_ntfs_attr *at, gr
   if (!(ctx->flags & GRUB_NTFS_RF_COMP))
     {
       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,
                             ctx->comp.log_spc, 0);
       return grub_errno;
@@ -495,9 +486,7 @@ read_data (struct grub_ntfs_attr *at, gr
 static grub_err_t
 read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
           grub_size_t len, int cached,
-          void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                              unsigned offset,
-                                              unsigned length))
+          grub_disk_read_hook_t read_hook, void *read_hook_data)
 {
   grub_uint8_t *save_cur;
   grub_uint8_t attr;
@@ -532,7 +521,8 @@ read_attr (struct grub_ntfs_attr *at, gr
     }
   pp = find_attr (at, attr);
   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
     ret =
       (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
@@ -546,7 +536,7 @@ read_mft (struct grub_ntfs_data *data, g
 {
   if (read_attr
       (&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 fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE");
 }
@@ -717,7 +707,7 @@ grub_ntfs_read_symlink (grub_fshelp_node
     }
 
   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)
     return NULL;
 
@@ -743,7 +733,7 @@ grub_ntfs_read_symlink (grub_fshelp_node
   if (!buf16)
     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)
     return NULL;
 
@@ -852,7 +842,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_
            }
           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,
                               "fails to read non-resident $BITMAP");
@@ -899,7 +889,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_
            {
              if ((read_attr
                   (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,
                             (const grub_uint8_t *) "INDX")))
                goto done;
@@ -1136,7 +1126,7 @@ grub_ntfs_read (grub_file_t file, char *
     mft->attr.save_pos = 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;
 }
 

=== modified file 'grub-core/fs/ntfscomp.c'
--- grub-core/fs/ntfscomp.c     2013-01-11 06:41:05 +0000
+++ grub-core/fs/ntfscomp.c     2013-01-21 11:29:00 +0000
@@ -302,6 +302,7 @@ ntfscomp (struct grub_ntfs_attr *at, gru
   ret = 0;
 
   //ctx->comp.disk->read_hook = read_hook;
+  //ctx->comp.disk->read_hook_data = read_hook_data;
 
   if ((vcn > ctx->target_vcn) &&
       (read_block

=== modified file 'grub-core/fs/reiserfs.c'
--- grub-core/fs/reiserfs.c     2013-01-21 01:33:46 +0000
+++ grub-core/fs/reiserfs.c     2013-01-21 11:29:06 +0000
@@ -240,9 +240,8 @@ struct grub_reiserfs_data
 static grub_ssize_t
 grub_reiserfs_read_real (struct grub_fshelp_node *node,
                         grub_off_t off, char *buf, grub_size_t len,
-                        void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                                            unsigned offset,
-                                                            unsigned length));
+                        grub_disk_read_hook_t read_hook,
+                        void *read_hook_data);
 
 /* Internal-only functions. Not to be used outside of this file.  */
 
@@ -674,7 +673,7 @@ grub_reiserfs_read_symlink (grub_fshelp_
   if (! symlink_buffer)
     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)
     {
       grub_free (symlink_buffer);
@@ -1036,9 +1035,7 @@ grub_reiserfs_open (struct grub_file *fi
 static grub_ssize_t
 grub_reiserfs_read_real (struct grub_fshelp_node *node,
                         grub_off_t off, char *buf, grub_size_t len,
-                        void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                                            unsigned offset,
-                                                            unsigned length))
+                        grub_disk_read_hook_t read_hook, void *read_hook_data)
 {
   unsigned int indirect_block, indirect_block_count;
   struct grub_reiserfs_key key;
@@ -1105,6 +1102,7 @@ grub_reiserfs_read_real (struct grub_fsh
                             (unsigned) block, (unsigned) offset,
                             (unsigned) (offset + length));
               found.data->disk->read_hook = read_hook;
+              found.data->disk->read_hook_data = read_hook_data;
               grub_disk_read (found.data->disk,
                               block,
                               offset
@@ -1131,6 +1129,7 @@ grub_reiserfs_read_real (struct grub_fsh
           if (grub_errno)
             goto fail;
           found.data->disk->read_hook = read_hook;
+          found.data->disk->read_hook_data = read_hook_data;
           for (indirect_block = 0;
                indirect_block < indirect_block_count
                  && 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)
 {
   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.  */

=== modified file 'grub-core/fs/romfs.c'
--- grub-core/fs/romfs.c        2013-01-21 01:33:46 +0000
+++ grub-core/fs/romfs.c        2013-01-21 12:08:09 +0000
@@ -399,6 +399,7 @@ grub_romfs_read (grub_file_t file, char
 
   /* XXX: The file is stored in as a single extent.  */
   data->data->disk->read_hook = file->read_hook;
+  data->data->disk->read_hook_data = file->read_hook_data;
   grub_disk_read (data->data->disk,
                  (data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS,
                  (data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 
1),                 

=== modified file 'grub-core/fs/sfs.c'
--- grub-core/fs/sfs.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/sfs.c  2013-01-21 09:46:14 +0000
@@ -345,11 +345,11 @@ grub_sfs_read_block (grub_fshelp_node_t
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_sfs_read_file (grub_fshelp_node_t node,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
+                   grub_disk_read_hook_t read_hook, void *read_hook_data,
                    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,
                                node->size, node->data->log_blocksize, 0);
 }
@@ -646,7 +646,8 @@ grub_sfs_read (grub_file_t file, char *b
 {
   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);
 }
 

=== modified file 'grub-core/fs/udf.c'
--- grub-core/fs/udf.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/udf.c  2013-01-21 09:46:14 +0000
@@ -564,9 +564,7 @@ fail:
 
 static grub_ssize_t
 grub_udf_read_file (grub_fshelp_node_t node,
-                   void NESTED_FUNC_ATTR
-                   (*read_hook) (grub_disk_addr_t sector,
-                                 unsigned offset, unsigned length),
+                   grub_disk_read_hook_t read_hook, void *read_hook_data,
                    grub_off_t pos, grub_size_t len, char *buf)
 {
   switch (U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
@@ -591,10 +589,11 @@ grub_udf_read_file (grub_fshelp_node_t n
       return 0;
     }
 
-  return  grub_fshelp_read_file (node->data->disk, node, read_hook,
-                                pos, len, buf, grub_udf_read_block,
-                                U64 (node->block.fe.file_size),
-                                node->data->lbshift, 0);
+  return grub_fshelp_read_file (node->data->disk, node,
+                               read_hook, read_hook_data,
+                               pos, len, buf, grub_udf_read_block,
+                               U64 (node->block.fe.file_size),
+                               node->data->lbshift, 0);
 }
 
 static unsigned sblocklist[] = { 256, 512, 0 };
@@ -861,7 +860,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t
 
   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))
        return 0;
 
@@ -898,7 +897,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t
              if (child->block.fe.icbtag.file_type == 
GRUB_UDF_ICBTAG_TYPE_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,
                                       (char *) raw))
                  != dirent.file_ident_length)
@@ -937,7 +936,7 @@ grub_udf_read_symlink (grub_fshelp_node_
   raw = grub_malloc (sz);
   if (!raw)
     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);
       return NULL;
@@ -1149,7 +1148,8 @@ grub_udf_read (grub_file_t file, char *b
 {
   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

=== modified file 'grub-core/fs/ufs.c'
--- grub-core/fs/ufs.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/ufs.c  2013-01-21 11:28:56 +0000
@@ -331,8 +331,7 @@ grub_ufs_get_file_block (struct grub_ufs
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_ufs_read_file (struct grub_ufs_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
+                   grub_disk_read_hook_t read_hook, void *read_hook_data,
                    grub_off_t pos, grub_size_t len, char *buf)
 {
   struct grub_ufs_sblock *sblock = &data->sblock;
@@ -380,6 +379,7 @@ grub_ufs_read_file (struct grub_ufs_data
       if (blknr)
        {
          data->disk->read_hook = read_hook;
+         data->disk->read_hook_data = read_hook_data;
          grub_disk_read (data->disk,
                          blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz),
                          skipfirst, blockend, buf);
@@ -455,7 +455,7 @@ grub_ufs_lookup_symlink (struct grub_ufs
       && INODE_SIZE (data) <= sizeof (data->inode.symlink))
     grub_strcpy (symlink, (char *) data->inode.symlink);
   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';
 
   /* The symlink is an absolute path, go back to the root inode.  */
@@ -509,7 +509,7 @@ grub_ufs_find_file (struct grub_ufs_data
       if (grub_strlen (name) == 0)
        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)
        return grub_errno;
 
@@ -521,7 +521,7 @@ grub_ufs_find_file (struct grub_ufs_data
       {
        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)
          return grub_errno;
 
@@ -659,7 +659,7 @@ grub_ufs_dir (grub_device_t device, cons
       struct grub_ufs_dirent dirent;
       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)
        break;
 
@@ -679,7 +679,7 @@ grub_ufs_dir (grub_device_t device, cons
 
        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)
          break;
 
@@ -752,7 +752,8 @@ grub_ufs_read (grub_file_t file, char *b
   struct grub_ufs_data *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);
 }
 
 

=== modified file 'grub-core/fs/xfs.c'
--- grub-core/fs/xfs.c  2013-01-21 01:33:46 +0000
+++ grub-core/fs/xfs.c  2013-01-21 09:46:14 +0000
@@ -381,11 +381,11 @@ grub_xfs_read_block (grub_fshelp_node_t
    POS.  Return the amount of read bytes in READ.  */
 static grub_ssize_t
 grub_xfs_read_file (grub_fshelp_node_t node,
-                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t 
sector,
-                                       unsigned offset, unsigned length),
+                    grub_disk_read_hook_t read_hook, void *read_hook_data,
                     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,
                                grub_be_to_cpu64 (node->inode.size),
                                node->data->sblock.log2_bsize
@@ -412,7 +412,7 @@ grub_xfs_read_symlink (grub_fshelp_node_
        if (!symlink)
          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)
          {
            grub_free (symlink);
@@ -594,7 +594,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
            struct grub_xfs_dirblock_tail *tail;
            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,
                                          dirblk_size, dirblock);
            if (numread != dirblk_size)
@@ -831,8 +831,9 @@ grub_xfs_read (grub_file_t file, char *b
   struct grub_xfs_data *data =
     (struct grub_xfs_data *) file->data;
 
-  return grub_xfs_read_file (&data->diropen, file->read_hook,
-                             file->offset, len, buf);
+  return grub_xfs_read_file (&data->diropen,
+                            file->read_hook, file->read_hook_data,
+                            file->offset, len, buf);
 }
 
 

=== modified file 'grub-core/kern/disk.c'
--- grub-core/kern/disk.c       2013-01-10 07:09:26 +0000
+++ grub-core/kern/disk.c       2013-01-21 09:46:14 +0000
@@ -603,7 +603,7 @@ grub_disk_read (grub_disk_t disk, grub_d
          cl = GRUB_DISK_SECTOR_SIZE - o;
          if (cl > l)
            cl = l;
-         (disk->read_hook) (s, o, cl);
+         (disk->read_hook) (s, o, cl, disk->read_hook_data);
          s++;
          l -= cl;
          o = 0;

=== modified file 'include/grub/disk.h'
--- include/grub/disk.h 2013-01-20 15:52:15 +0000
+++ include/grub/disk.h 2013-01-21 09:46:14 +0000
@@ -99,6 +99,10 @@ extern grub_disk_dev_t EXPORT_VAR (grub_
 
 struct grub_partition;
 
+typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector,
+                                      unsigned offset, unsigned length,
+                                      void *data);
+
 /* Disk.  */
 struct grub_disk
 {
@@ -122,8 +126,10 @@ struct grub_disk
 
   /* 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.  */
-  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                    unsigned offset, unsigned length);
+  grub_disk_read_hook_t read_hook;
+
+  /* Caller-specific data passed to the read hook.  */
+  void *read_hook_data;
 
   /* Device-specific data.  */
   void *data;

=== modified file 'include/grub/file.h'
--- include/grub/file.h 2013-01-11 20:32:42 +0000
+++ include/grub/file.h 2013-01-21 09:46:14 +0000
@@ -23,6 +23,7 @@
 #include <grub/err.h>
 #include <grub/device.h>
 #include <grub/fs.h>
+#include <grub/disk.h>
 
 /* File description.  */
 struct grub_file
@@ -46,8 +47,10 @@ struct grub_file
   void *data;
 
   /* 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,
-                    unsigned offset, unsigned length);
+  grub_disk_read_hook_t read_hook;
+
+  /* Caller-specific data passed to the read hook.  */
+  void *read_hook_data;
 };
 typedef struct grub_file *grub_file_t;
 

=== modified file 'include/grub/fshelp.h'
--- include/grub/fshelp.h       2013-01-21 01:33:46 +0000
+++ include/grub/fshelp.h       2013-01-21 09:46:14 +0000
@@ -23,6 +23,7 @@
 #include <grub/types.h>
 #include <grub/symbol.h>
 #include <grub/err.h>
+#include <grub/disk.h>
 
 typedef struct grub_fshelp_node *grub_fshelp_node_t;
 
@@ -68,9 +69,8 @@ EXPORT_FUNC(grub_fshelp_find_file) (cons
    blocks have a size of LOG2BLOCKSIZE (in log2).  */
 grub_ssize_t
 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,
-                                                                        
unsigned offset,
-                                                                        
unsigned length),
+                                   grub_disk_read_hook_t read_hook,
+                                   void *read_hook_data,
                                    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 block),

=== modified file 'util/grub-setup.c'
--- util/grub-setup.c   2013-01-20 15:52:15 +0000
+++ util/grub-setup.c   2013-01-21 09:46:14 +0000
@@ -138,6 +138,70 @@ write_rootdev (grub_device_t root_dev,
 #define BOOT_SECTOR 0
 #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
 /* Context for setup/identify_partmap.  */
 struct identify_partmap_ctx
@@ -147,7 +211,7 @@ struct identify_partmap_ctx
   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
    if dest_dev itself is a whole disk.  */
 static int
@@ -190,73 +254,16 @@ setup (const char *dir,
   grub_uint16_t core_sectors;
 #endif
   grub_device_t root_dev = 0, dest_dev, core_dev;
-  struct grub_boot_blocklist *first_block, *block;
+  struct blocklists bl;
   char *tmp_img;
   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;
 
-  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
-         block->segment = grub_host_to_target16 (current_segment);
+  bl.current_segment =
+    GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
 #endif
-
-         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
-    }
+  bl.last_length = GRUB_DISK_SECTOR_SIZE;
 
   /* Read the boot image by the OS service.  */
   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);
 
   /* Have FIRST_BLOCK to point to the first blocklist.  */
-  first_block = (struct grub_boot_blocklist *) (core_img
-                                               + GRUB_DISK_SECTOR_SIZE
-                                               - sizeof (*block));
+  bl.first_block = (struct grub_boot_blocklist *) (core_img
+                                                  + GRUB_DISK_SECTOR_SIZE
+                                                  - sizeof (*bl.block));
   grub_util_info ("root is `%s', dest is `%s'", root, dest);
 
   grub_util_info ("Opening dest");
@@ -511,38 +518,38 @@ setup (const char *dir,
     assert (nsec <= maxsec);
 
     /* Clean out the blocklists.  */
-    block = first_block;
-    while (block->len)
+    bl.block = bl.first_block;
+    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"));
       }
 
     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++)
       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.  */
-    if (block == first_block)
-      block--;
-    block->start = 0;
-    block->len = 0;
-    block->segment = 0;
+    if (bl.block == bl.first_block)
+      bl.block--;
+    bl.block->start = 0;
+    bl.block->len = 0;
+    bl.block->segment = 0;
 
     write_rootdev (root_dev, boot_img, first_sector);
 
     core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
-    first_block = (struct grub_boot_blocklist *) (core_img
-                                                 + GRUB_DISK_SECTOR_SIZE
-                                                 - sizeof (*block));
+    bl.first_block = (struct grub_boot_blocklist *) (core_img
+                                                    + GRUB_DISK_SECTOR_SIZE
+                                                    - sizeof (*bl.block));
 
     grub_size_t no_rs_length;
     grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE
@@ -698,22 +705,22 @@ unable_to_embed:
 #endif
 
   /* Clean out the blocklists.  */
-  block = first_block;
-  while (block->len)
+  bl.block = bl.first_block;
+  while (bl.block->len)
     {
-      block->start = 0;
-      block->len = 0;
+      bl.block->start = 0;
+      bl.block->len = 0;
 #ifdef GRUB_SETUP_BIOS
-      block->segment = 0;
+      bl.block->segment = 0;
 #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"));
     }
 
-  block = first_block;
+  bl.block = bl.first_block;
 
 #ifdef __linux__
   {
@@ -766,11 +773,11 @@ unable_to_embed:
                if (i == 0 && j == 0)
                  save_first_sector (((grub_uint64_t) blk) * mul
                                     + container_start,
-                                    0, rest);
+                                    0, rest, &first_sector);
                else
                  save_blocklists (((grub_uint64_t) blk) * mul + j
                                   + container_start,
-                                  0, rest);
+                                  0, rest, &bl);
              }
          }
       }
@@ -806,13 +813,14 @@ unable_to_embed:
                                      >> GRUB_DISK_SECTOR_BITS)
                                     + j + container_start,
                                     fie2->fm_extents[i].fe_physical
-                                    & (GRUB_DISK_SECTOR_SIZE - 1), len);
+                                    & (GRUB_DISK_SECTOR_SIZE - 1), len,
+                                    &first_sector);
                else
                  save_blocklists ((fie2->fm_extents[i].fe_physical
                                    >> GRUB_DISK_SECTOR_BITS)
                                   + j + container_start,
                                   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);
 
     file->read_hook = save_first_sector;
+    file->read_hook_data = &first_sector;
     if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
        != GRUB_DISK_SECTOR_SIZE)
       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_data = &bl;
     if (grub_file_read (file, tmp_img, 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"));
@@ -913,11 +923,11 @@ unable_to_embed:
     ptr += GRUB_DISK_SECTOR_SIZE;
     len -= GRUB_DISK_SECTOR_SIZE;
 
-    block = first_block;
-    while (block->len)
+    bl.block = bl.first_block;
+    while (bl.block->len)
       {
-       size_t cur = grub_target_to_host16 (block->len) << 
GRUB_DISK_SECTOR_BITS;
-       blk = grub_target_to_host64 (block->start);
+       size_t cur = grub_target_to_host16 (bl.block->len) << 
GRUB_DISK_SECTOR_BITS;
+       blk = grub_target_to_host64 (bl.block->start);
 
        if (cur > len)
          cur = len;
@@ -932,9 +942,9 @@ unable_to_embed:
 
        ptr += 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"));
       }
     core_dev->disk->partition = container;

Thanks,

-- 
Colin Watson                                       address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]