]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
disk: Allow read hook callback to take read buffer to potentially modify it
authorGlenn Washburn <development@efficientek.com>
Wed, 8 Jun 2022 15:34:02 +0000 (10:34 -0500)
committerDaniel Kiper <daniel.kiper@oracle.com>
Mon, 4 Jul 2022 12:43:25 +0000 (14:43 +0200)
It will be desirable in the future to allow having the read hook modify the
data passed back from a read function call on a disk or file. This adds that
infrastructure and has no impact on code flow for existing uses of the read
hook. Also changed is that now when the read hook callback is called it can
also indicate what error code should be sent back to the read caller.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/commands/blocklist.c
grub-core/commands/loadenv.c
grub-core/commands/testload.c
grub-core/fs/hfspluscomp.c
grub-core/fs/ntfscomp.c
grub-core/kern/disk.c
grub-core/lib/progress.c
grub-core/net/net.c
include/grub/disk.h

index 944449b77d4bdb6fc26b7906853e47e142ffb2d8..48fd85a338f43deea98439d6cdb9f66146466887 100644 (file)
@@ -53,9 +53,9 @@ print_blocklist (grub_disk_addr_t sector, unsigned num,
 }
 
 /* Helper for grub_cmd_blocklist.  */
-static void
+static grub_err_t
 read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
-               void *data)
+               char *buf __attribute__ ((unused)), void *data)
 {
   struct blocklist_ctx *ctx = data;
 
@@ -70,7 +70,7 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
        }
 
       if (!length)
-       return;
+       return GRUB_ERR_NONE;
       print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
       ctx->num_sectors = 0;
     }
@@ -87,7 +87,7 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
     }
 
   if (!length)
-    return;
+    return GRUB_ERR_NONE;
 
   if (length & (GRUB_DISK_SECTOR_SIZE - 1))
     {
@@ -103,6 +103,8 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
       ctx->start_sector = sector;
       ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS;
     }
+
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
index 3fd664aac331dba48f8f938c113eac4304e67d21..16644584978b26924b30f1a14cf040d559acd5f5 100644 (file)
@@ -352,16 +352,16 @@ struct grub_cmd_save_env_ctx
 };
 
 /* Store blocklists in a linked list.  */
-static void
+static grub_err_t
 save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
-                   void *data)
+                   char *buf __attribute__ ((unused)), void *data)
 {
   struct grub_cmd_save_env_ctx *ctx = data;
   struct blocklist *block;
 
   block = grub_malloc (sizeof (*block));
   if (! block)
-    return;
+    return GRUB_ERR_NONE;
 
   block->sector = sector;
   block->offset = offset;
@@ -374,6 +374,8 @@ save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
   ctx->tail = block;
   if (! ctx->head)
     ctx->head = block;
+
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
index ff01a0516dd71fb9a0ea87436bc3de4caa654db0..76a8af94c5aff91db76b6a6200eabec54f007197 100644 (file)
 GRUB_MOD_LICENSE ("GPLv3+");
 
 /* Helper for grub_cmd_testload.  */
-static void
+static grub_err_t
 read_progress (grub_disk_addr_t sector __attribute__ ((unused)),
               unsigned offset __attribute__ ((unused)),
               unsigned len,
+              char *buf __attribute__ ((unused)),
               void *data __attribute__ ((unused)))
 {
   for (; len >= GRUB_DISK_SECTOR_SIZE; len -= GRUB_DISK_SECTOR_SIZE)
@@ -43,6 +44,7 @@ read_progress (grub_disk_addr_t sector __attribute__ ((unused)),
   if (len)
     grub_xputs (".");
   grub_refresh ();
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
index 095ea48c9a62faaebc354324d5ac048aabc2e5cb..48ae438d85018cd94cd2bc076545b790a9f338e3 100644 (file)
@@ -123,7 +123,7 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node,
     {
       grub_memcpy (buf, node->cbuf + pos, len);
       if (grub_file_progress_hook && node->file)
-       grub_file_progress_hook (0, 0, len, node->file);
+       grub_file_progress_hook (0, 0, len, NULL, node->file);
       return len;
     }
 
@@ -170,7 +170,7 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node,
       grub_memcpy (buf, node->cbuf + (pos % HFSPLUS_COMPRESS_BLOCK_SIZE),
                   curlen);
       if (grub_file_progress_hook && node->file)
-       grub_file_progress_hook (0, 0, curlen, node->file);
+       grub_file_progress_hook (0, 0, curlen, NULL, node->file);
       buf += curlen;
       pos += curlen;
       len -= curlen;
index 3cd97d337ce9c68c052b3850436fb617bc272d48..a009f2c2ddf9c6efa2b2de63d694d93c9360046f 100644 (file)
@@ -227,7 +227,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num)
                  grub_memset (buf, 0, nn * GRUB_NTFS_COM_LEN);
                  buf += nn * GRUB_NTFS_COM_LEN;
                  if (grub_file_progress_hook && ctx->file)
-                   grub_file_progress_hook (0, 0, nn * GRUB_NTFS_COM_LEN,
+                   grub_file_progress_hook (0, 0, nn * GRUB_NTFS_COM_LEN, NULL,
                                             ctx->file);
                }
            }
@@ -240,7 +240,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num)
                  if (buf)
                    buf += GRUB_NTFS_COM_LEN;
                  if (grub_file_progress_hook && ctx->file)
-                   grub_file_progress_hook (0, 0, GRUB_NTFS_COM_LEN,
+                   grub_file_progress_hook (0, 0, GRUB_NTFS_COM_LEN, NULL,
                                             ctx->file);
                  nn--;
                }
@@ -271,7 +271,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num)
                  if (grub_file_progress_hook && ctx->file)
                    grub_file_progress_hook (0, 0,
                                             tt << (ctx->comp.log_spc
-                                                   + GRUB_NTFS_BLK_SHR),
+                                                   + GRUB_NTFS_BLK_SHR), NULL,
                                             ctx->file);
                  buf += tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR);
                }
@@ -294,7 +294,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num)
                  if (grub_file_progress_hook && ctx->file)
                    grub_file_progress_hook (0, 0,
                                             nn << (ctx->comp.log_spc
-                                                   + GRUB_NTFS_BLK_SHR),
+                                                   + GRUB_NTFS_BLK_SHR), NULL,
                                             ctx->file);
                }
              ctx->target_vcn += nn;
@@ -323,7 +323,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
 
          grub_memcpy (dest, ctx->attr->sbuf + ofs - ctx->attr->save_pos, n);
          if (grub_file_progress_hook && ctx->file)
-           grub_file_progress_hook (0, 0, n, ctx->file);
+           grub_file_progress_hook (0, 0, n, NULL, ctx->file);
          if (n == len)
            return 0;
 
@@ -390,7 +390,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
        n = len;
       grub_memcpy (dest, &ctx->attr->sbuf[o], n);
       if (grub_file_progress_hook && ctx->file)
-       grub_file_progress_hook (0, 0, n, ctx->file);
+       grub_file_progress_hook (0, 0, n, NULL, ctx->file);
       if (n == len)
        goto quit;
       dest += n;
@@ -422,7 +422,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
 
       grub_memcpy (dest, ctx->attr->sbuf, len);
       if (grub_file_progress_hook && file)
-       grub_file_progress_hook (0, 0, len, file);
+       grub_file_progress_hook (0, 0, len, NULL, file);
     }
 
 quit:
index 3a42c007be4dab6c662417a48b5ab9b9c5f6cd61..01190085eeb7973feb4c7dc52aa259fbafa3c58a 100644 (file)
@@ -402,10 +402,10 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector,
   if (err)
     return err;
   if (disk->read_hook)
-    (disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS),
-                      offset & (GRUB_DISK_SECTOR_SIZE - 1),
-                      size, disk->read_hook_data);
-  return GRUB_ERR_NONE;
+    err = (disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS),
+                            offset & (GRUB_DISK_SECTOR_SIZE - 1),
+                            size, buf, disk->read_hook_data);
+  return err;
 }
 
 /* Read data from the disk.  */
@@ -501,7 +501,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
 
          if (disk->read_hook)
            (disk->read_hook) (sector, 0, agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS),
-                              disk->read_hook_data);
+                              buf, disk->read_hook_data);
 
          sector += agglomerate << GRUB_DISK_CACHE_BITS;
          size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
@@ -513,7 +513,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
        {
          if (disk->read_hook)
            (disk->read_hook) (sector, 0, (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS),
-                              disk->read_hook_data);
+                              buf, disk->read_hook_data);
          sector += GRUB_DISK_CACHE_SIZE;
          buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
          size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
index 4b7cbbca6ddce81071584207d74868ee91a1d224..4f4389dd586fe5b77694684ec971755ddb04cf04 100644 (file)
@@ -29,10 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
 
 #define UPDATE_INTERVAL 800
 
-static void
+static grub_err_t
 grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
                               unsigned offset __attribute__ ((unused)),
-                              unsigned length, void *data)
+                              unsigned length,
+                             char *buf __attribute__ ((unused)), void *data)
 {
   static int call_depth = 0;
   grub_uint64_t now;
@@ -42,11 +43,11 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
   file->progress_offset += length;
 
   if (call_depth)
-    return;
+    return GRUB_ERR_NONE;
 
   e = grub_env_get ("enable_progress_indicator");
   if (e && e[0] == '0') {
-    return;
+    return GRUB_ERR_NONE;
   }
 
   call_depth = 1;
@@ -132,6 +133,8 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
       last_progress_update_time = now;
     }
   call_depth = 0;
+
+  return GRUB_ERR_NONE;
 }
 
 GRUB_MOD_INIT(progress)
index 9f09f8e487caf1d42d46cb84459b11687ed9e420..064e7114e012541c7828677b2458394c949c3019 100644 (file)
@@ -1662,7 +1662,7 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
          total += amount;
          file->device->net->offset += amount;
          if (grub_file_progress_hook)
-           grub_file_progress_hook (0, 0, amount, file);
+           grub_file_progress_hook (0, 0, amount, NULL, file);
          if (buf)
            {
              grub_memcpy (ptr, nb->data, amount);
index a17d257c39b269783ffd7e4a067c2a0ca14c5dad..25c141ea27812e8992a8eb768ff7ab40b1707b0b 100644 (file)
@@ -110,9 +110,9 @@ extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list);
 
 struct grub_partition;
 
-typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length,
-                                      void *data);
+typedef grub_err_t (*grub_disk_read_hook_t) (grub_disk_addr_t sector,
+                                            unsigned offset, unsigned length,
+                                            char *buf, void *data);
 
 /* Disk.  */
 struct grub_disk