disk: Allow read hook callback to take read buffer to potentially modify it

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>
This commit is contained in:
Glenn Washburn authored and Daniel Kiper committed 2022-07-04 14:43:25 +02:00
1 parent 190d79e135
commit f5a92e6040
9 files changed
+40 -31

No files matched your search

+6 -4
View File
@@ -53,9 +53,9 @@ print_blocklist (grub_disk_addr_t sector, unsigned num,
} }
/* Helper for grub_cmd_blocklist. */ /* Helper for grub_cmd_blocklist. */
static void static grub_err_t
read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
void *data) char *buf __attribute__ ((unused)), void *data)
{ {
struct blocklist_ctx *ctx = data; struct blocklist_ctx *ctx = data;
@@ -70,7 +70,7 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
} }
if (!length) if (!length)
return; return GRUB_ERR_NONE;
print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx); print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
ctx->num_sectors = 0; ctx->num_sectors = 0;
} }
@@ -87,7 +87,7 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
} }
if (!length) if (!length)
return; return GRUB_ERR_NONE;
if (length & (GRUB_DISK_SECTOR_SIZE - 1)) 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->start_sector = sector;
ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS; ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS;
} }
return GRUB_ERR_NONE;
} }
static grub_err_t static grub_err_t
+5 -3
View File
@@ -352,16 +352,16 @@ struct grub_cmd_save_env_ctx
}; };
/* Store blocklists in a linked list. */ /* 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, 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 grub_cmd_save_env_ctx *ctx = data;
struct blocklist *block; struct blocklist *block;
block = grub_malloc (sizeof (*block)); block = grub_malloc (sizeof (*block));
if (! block) if (! block)
return; return GRUB_ERR_NONE;
block->sector = sector; block->sector = sector;
block->offset = offset; block->offset = offset;
@@ -374,6 +374,8 @@ save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
ctx->tail = block; ctx->tail = block;
if (! ctx->head) if (! ctx->head)
ctx->head = block; ctx->head = block;
return GRUB_ERR_NONE;
} }
static grub_err_t static grub_err_t
+3 -1
View File
@@ -32,10 +32,11 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
/* Helper for grub_cmd_testload. */ /* Helper for grub_cmd_testload. */
static void static grub_err_t
read_progress (grub_disk_addr_t sector __attribute__ ((unused)), read_progress (grub_disk_addr_t sector __attribute__ ((unused)),
unsigned offset __attribute__ ((unused)), unsigned offset __attribute__ ((unused)),
unsigned len, unsigned len,
char *buf __attribute__ ((unused)),
void *data __attribute__ ((unused))) void *data __attribute__ ((unused)))
{ {
for (; len >= GRUB_DISK_SECTOR_SIZE; len -= GRUB_DISK_SECTOR_SIZE) 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) if (len)
grub_xputs ("."); grub_xputs (".");
grub_refresh (); grub_refresh ();
return GRUB_ERR_NONE;
} }
static grub_err_t static grub_err_t
+2 -2
View File
@@ -123,7 +123,7 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node,
{ {
grub_memcpy (buf, node->cbuf + pos, len); grub_memcpy (buf, node->cbuf + pos, len);
if (grub_file_progress_hook && node->file) 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; 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), grub_memcpy (buf, node->cbuf + (pos % HFSPLUS_COMPRESS_BLOCK_SIZE),
curlen); curlen);
if (grub_file_progress_hook && node->file) 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; buf += curlen;
pos += curlen; pos += curlen;
len -= curlen; len -= curlen;
+7 -7
View 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); grub_memset (buf, 0, nn * GRUB_NTFS_COM_LEN);
buf += nn * GRUB_NTFS_COM_LEN; buf += nn * GRUB_NTFS_COM_LEN;
if (grub_file_progress_hook && ctx->file) 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); ctx->file);
} }
} }
@@ -240,7 +240,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num)
if (buf) if (buf)
buf += GRUB_NTFS_COM_LEN; buf += GRUB_NTFS_COM_LEN;
if (grub_file_progress_hook && ctx->file) 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); ctx->file);
nn--; 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) if (grub_file_progress_hook && ctx->file)
grub_file_progress_hook (0, 0, grub_file_progress_hook (0, 0,
tt << (ctx->comp.log_spc tt << (ctx->comp.log_spc
+ GRUB_NTFS_BLK_SHR), + GRUB_NTFS_BLK_SHR), NULL,
ctx->file); ctx->file);
buf += tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); 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) if (grub_file_progress_hook && ctx->file)
grub_file_progress_hook (0, 0, grub_file_progress_hook (0, 0,
nn << (ctx->comp.log_spc nn << (ctx->comp.log_spc
+ GRUB_NTFS_BLK_SHR), + GRUB_NTFS_BLK_SHR), NULL,
ctx->file); ctx->file);
} }
ctx->target_vcn += nn; 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); grub_memcpy (dest, ctx->attr->sbuf + ofs - ctx->attr->save_pos, n);
if (grub_file_progress_hook && ctx->file) 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) if (n == len)
return 0; return 0;
@@ -390,7 +390,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
n = len; n = len;
grub_memcpy (dest, &ctx->attr->sbuf[o], n); grub_memcpy (dest, &ctx->attr->sbuf[o], n);
if (grub_file_progress_hook && ctx->file) 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) if (n == len)
goto quit; goto quit;
dest += n; dest += n;
@@ -422,7 +422,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
grub_memcpy (dest, ctx->attr->sbuf, len); grub_memcpy (dest, ctx->attr->sbuf, len);
if (grub_file_progress_hook && file) if (grub_file_progress_hook && file)
grub_file_progress_hook (0, 0, len, file); grub_file_progress_hook (0, 0, len, NULL, file);
} }
quit: quit:
+6 -6
View File
@@ -402,10 +402,10 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector,
if (err) if (err)
return err; return err;
if (disk->read_hook) if (disk->read_hook)
(disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS), err = (disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS),
offset & (GRUB_DISK_SECTOR_SIZE - 1), offset & (GRUB_DISK_SECTOR_SIZE - 1),
size, disk->read_hook_data); size, buf, disk->read_hook_data);
return GRUB_ERR_NONE; return err;
} }
/* Read data from the disk. */ /* 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) if (disk->read_hook)
(disk->read_hook) (sector, 0, agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS), (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; sector += agglomerate << GRUB_DISK_CACHE_BITS;
size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_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) if (disk->read_hook)
(disk->read_hook) (sector, 0, (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS), (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; sector += GRUB_DISK_CACHE_SIZE;
buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
+7 -4
View File
@@ -29,10 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define UPDATE_INTERVAL 800 #define UPDATE_INTERVAL 800
static void static grub_err_t
grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)), grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
unsigned offset __attribute__ ((unused)), unsigned offset __attribute__ ((unused)),
unsigned length, void *data) unsigned length,
char *buf __attribute__ ((unused)), void *data)
{ {
static int call_depth = 0; static int call_depth = 0;
grub_uint64_t now; grub_uint64_t now;
@@ -42,11 +43,11 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
file->progress_offset += length; file->progress_offset += length;
if (call_depth) if (call_depth)
return; return GRUB_ERR_NONE;
e = grub_env_get ("enable_progress_indicator"); e = grub_env_get ("enable_progress_indicator");
if (e && e[0] == '0') { if (e && e[0] == '0') {
return; return GRUB_ERR_NONE;
} }
call_depth = 1; call_depth = 1;
@@ -132,6 +133,8 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
last_progress_update_time = now; last_progress_update_time = now;
} }
call_depth = 0; call_depth = 0;
return GRUB_ERR_NONE;
} }
GRUB_MOD_INIT(progress) GRUB_MOD_INIT(progress)
+1 -1
View File
@@ -1662,7 +1662,7 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
total += amount; total += amount;
file->device->net->offset += amount; file->device->net->offset += amount;
if (grub_file_progress_hook) if (grub_file_progress_hook)
grub_file_progress_hook (0, 0, amount, file); grub_file_progress_hook (0, 0, amount, NULL, file);
if (buf) if (buf)
{ {
grub_memcpy (ptr, nb->data, amount); grub_memcpy (ptr, nb->data, amount);
+3 -3
View File
@@ -110,9 +110,9 @@ extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list);
struct grub_partition; struct grub_partition;
typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector, typedef grub_err_t (*grub_disk_read_hook_t) (grub_disk_addr_t sector,
unsigned offset, unsigned length, unsigned offset, unsigned length,
void *data); char *buf, void *data);
/* Disk. */ /* Disk. */
struct grub_disk struct grub_disk